Implement #540
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 775ec3e..b4c5223 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -9,6 +9,8 @@
 #539: Problem with post-procesing of "empty bean" serializer; was not calling
   'BeanSerializerModifier.modifySerializer()` for empty beans
  (reported by Fabien R, fabienrenaud@github)
+#540: Support deserializing `[]` as null or empty collection when the java type is a not an object
+ (requested by Fabien R, fabienrenaud@github)
 #543: Problem resolving self-referential recursive types
  (reported by ahgittin@github)
 #550: Minor optimization: prune introspection of "well-known" JDK types
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
index f73bcfe..32a9052 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
@@ -1192,15 +1192,24 @@
                 wrapInstantiationProblem(e, ctxt);
             }
         } else if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
-            jp.nextToken();
+            JsonToken t = jp.nextToken();
+            if (t == JsonToken.END_ARRAY && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
+                return null;
+            }
             final Object value = deserialize(jp, ctxt);
             if (jp.nextToken() != JsonToken.END_ARRAY) {
                 throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, 
                         "Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array");
             }
             return value;
+        } else if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
+            JsonToken t = jp.nextToken();
+            if (t == JsonToken.END_ARRAY) {
+                return null;
+            }
+            throw ctxt.mappingException(handledType(), JsonToken.START_ARRAY);
         }
-        throw ctxt.mappingException(getBeanClass());
+        throw ctxt.mappingException(handledType());
     }
 
     public Object deserializeFromEmbedded(JsonParser jp, DeserializationContext ctxt) throws IOException
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java
index 1a34b6d..12a9918 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java
@@ -19,7 +19,7 @@
     extends ContainerDeserializerBase<EnumMap<?,?>>
     implements ContextualDeserializer
 {
-    private static final long serialVersionUID = 4564890642370311174L;
+    private static final long serialVersionUID = 1;
 
     protected final JavaType _mapType;
     
@@ -114,13 +114,14 @@
     /* Actual deserialization
     /**********************************************************
      */
-
+    
     @Override
-    public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
+    public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt)
+        throws IOException
     {
         // Ok: must point to START_OBJECT
         if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw ctxt.mappingException(EnumMap.class);
+            return _deserializeFromEmpty(jp, ctxt);
         }
         EnumMap result = constructMap();
         final JsonDeserializer<Object> valueDes = _valueDeserializer;
@@ -172,14 +173,15 @@
     }
 
     @Override
-   public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
+    public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
         throws IOException, JsonProcessingException
     {
         // In future could check current token... for now this should be enough:
         return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
     }
     
-    private EnumMap<?,?> constructMap() {
+    protected EnumMap<?,?> constructMap() {
         return new EnumMap(_enumClass);
     }
 }
+
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
index a446777..cdad99b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java
@@ -303,7 +303,8 @@
             if (t == JsonToken.VALUE_STRING) {
                 return (Map<Object,Object>) _valueInstantiator.createFromString(ctxt, jp.getText());
             }
-            throw ctxt.mappingException(getMapClass());
+            // slightly redundant (since String was passed above), but
+            return _deserializeFromEmpty(jp, ctxt);
         }
         final Map<Object,Object> result = (Map<Object,Object>) _valueInstantiator.createUsingDefault(ctxt);
         if (_standardStringKey) {
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
index e4eeddc..3f9fa66 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java
@@ -800,6 +800,35 @@
     }
 
     /**
+     * Helper method that may be used to support fallback for Empty String / Empty Array
+     * non-standard representations; usually for things serialized as JSON Objects.
+     * 
+     * @since 2.5
+     */
+    protected T _deserializeFromEmpty(JsonParser jp, DeserializationContext ctxt)
+        throws IOException
+    {
+        JsonToken t = jp.getCurrentToken();
+        if (t == JsonToken.START_ARRAY) {
+            if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
+                t = jp.nextToken();
+                if (t == JsonToken.END_ARRAY) {
+                    return null;
+                }
+                throw ctxt.mappingException(handledType(), JsonToken.START_ARRAY);
+            }
+        } else if (t == JsonToken.VALUE_STRING) {
+            if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
+                String str = jp.getText().trim();
+                if (str.isEmpty()) {
+                    return null;
+                }
+            }
+        }
+        throw ctxt.mappingException(handledType());
+    }
+    
+    /**
      * Helper method called to determine if we are seeing String value of
      * "null", and, further, that it should be coerced to null just like
      * null token.
diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/TestMapDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/deser/TestMapDeserialization.java
index 13a9fd1..c69a8eb 100644
--- a/src/test/java/com/fasterxml/jackson/databind/deser/TestMapDeserialization.java
+++ b/src/test/java/com/fasterxml/jackson/databind/deser/TestMapDeserialization.java
@@ -9,7 +9,6 @@
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.fasterxml.jackson.core.*;
 import com.fasterxml.jackson.core.type.TypeReference;
-
 import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
@@ -18,13 +17,7 @@
 public class TestMapDeserialization
     extends BaseMapTest
 {
-    /*
-    /**********************************************************
-    /* Test classes, enums
-    /**********************************************************
-     */
-
-    enum Key {
+    static enum Key {
         KEY1, KEY2, WHATEVER;
     }
 
@@ -84,8 +77,6 @@
         ONE, TWO;
     }
 
-    
-    
     /*
     /**********************************************************
     /* Test methods, untyped (Object valued) maps
@@ -302,6 +293,31 @@
         assertNull(result.get(""));
     }
 
+    // [Databind#540]
+    public void testMapFromEmptyArray() throws Exception
+    {
+        final String JSON = "  [\n]";
+        assertFalse(MAPPER.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT));
+        // first, verify default settings which do not accept empty Array
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            mapper.readValue(JSON, Map.class);
+            fail("Should not accept Empty Array for Map by default");
+        } catch (JsonProcessingException e) {
+            verifyException(e, "START_ARRAY token");
+        }
+        // should be ok to enable dynamically:
+        ObjectReader r = MAPPER.reader(Map.class)
+                .with(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
+
+        Map<?,?> result = r.readValue(JSON);
+        assertNull(result);
+
+        EnumMap<?,?> result2 = r.withType(new TypeReference<EnumMap<Key,String>>() { })
+                .readValue(JSON);
+        assertNull(result2);
+    }
+
     /*
     /**********************************************************
     /* Test methods, maps with enums