Repository: morphiaorg/morphia
Issue: Empty maps are deserialized as null

When configuring the mapper to also store empties

```
mapper.getOptions().setStoreEmpties(true);
```

then empty Maps and Lists are stored as well to DB.
They also get deserialized as empty Maps resp. List again.
This works for an empty

```
Map<String, String>
```

BUT it does not work for empty Maps like the following

```
Map<String, List<String>>
Map<String, MyObject>
```

where

```
class MyObject {
   private String valueA;
   private int valueB;
}
```

It seems when having a complex type in the value part of the map, the map is no longer deserialized as empty map but simply as null object, which subsequently breaks the code as they are no longer equal after loading.

Tested with Morphia 1.0.1


Changed files:
morphia/src/test/java/org/mongodb/morphia/mapping/MapperOptionsTest.java, morphia/src/main/java/org/mongodb/morphia/mapping/EmbeddedMapper.java

diff --git a/morphia/src/main/java/org/mongodb/morphia/mapping/EmbeddedMapper.java b/morphia/src/main/java/org/mongodb/morphia/mapping/EmbeddedMapper.java
index dcf43e71cc5..8369c31f434 100644
--- a/morphia/src/main/java/org/mongodb/morphia/mapping/EmbeddedMapper.java
+++ b/morphia/src/main/java/org/mongodb/morphia/mapping/EmbeddedMapper.java
@@ -188,7 +188,7 @@ class EmbeddedMapper implements CustomMapper {
             }
         });
 
-        if (!map.isEmpty()) {
+        if (!map.isEmpty() || mapper.getOptions().isStoreEmpties()) {
             mf.setFieldValue(entity, map);
         }
     }
diff --git a/morphia/src/test/java/org/mongodb/morphia/mapping/MapperOptionsTest.java b/morphia/src/test/java/org/mongodb/morphia/mapping/MapperOptionsTest.java
index 696b3002261..f4c2e0e9d4b 100644
--- a/morphia/src/test/java/org/mongodb/morphia/mapping/MapperOptionsTest.java
+++ b/morphia/src/test/java/org/mongodb/morphia/mapping/MapperOptionsTest.java
@@ -14,6 +14,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Collection;
 
 
 /**
@@ -72,6 +73,42 @@ public class MapperOptionsTest extends TestBase {
         shouldNotFindField(hm);
     }
 
+    @Test
+    public void emptyCollectionValuedMapStoredWithOptions() throws Exception {
+        final HasCollectionValuedMap hm = new HasCollectionValuedMap();
+        hm.properties = new HashMap<String, Collection<String>>();
+
+        //Test default behavior
+        getMorphia().getMapper().getOptions().setStoreEmpties(false);
+        shouldNotFindField(hm);
+
+        //Test default storing empty map with storeEmpties option
+        getMorphia().getMapper().getOptions().setStoreEmpties(true);
+        shouldFindField(hm, new HashMap<String, Collection<String>>());
+
+        //Test opposite from above
+        getMorphia().getMapper().getOptions().setStoreEmpties(false);
+        shouldNotFindField(hm);
+    }
+
+    @Test
+    public void emptyComplexObjectValuedMapStoredWithOptions() throws Exception {
+        final HasComplexObjectValuedMap hm = new HasComplexObjectValuedMap();
+        hm.properties = new HashMap<String, ComplexObject>();
+
+        //Test default behavior
+        getMorphia().getMapper().getOptions().setStoreEmpties(false);
+        shouldNotFindField(hm);
+
+        //Test default storing empty map with storeEmpties option
+        getMorphia().getMapper().getOptions().setStoreEmpties(true);
+        shouldFindField(hm, new HashMap<String, ComplexObject>());
+
+        //Test opposite from above
+        getMorphia().getMapper().getOptions().setStoreEmpties(false);
+        shouldNotFindField(hm);
+    }
+
     @Test
     public void lowercaseDefaultCollection() {
         DummyEntity entity = new DummyEntity();
@@ -137,6 +174,22 @@ public class MapperOptionsTest extends TestBase {
         Assert.assertEquals(expected, getDs().createQuery(HasMap.class).get().properties);
     }
 
+    private void shouldFindField(final HasCollectionValuedMap hm, final Map<String, Collection<String>> expected) {
+        final DBObject dbObj;
+        getDs().save(hm);
+        dbObj = getDs().getCollection(HasCollectionValuedMap.class).findOne();
+        Assert.assertTrue("Should find the field", dbObj.containsField("properties"));
+        Assert.assertEquals(expected, getDs().createQuery(HasCollectionValuedMap.class).get().properties);
+    }
+
+    private void shouldFindField(final HasComplexObjectValuedMap hm, final Map<String, ComplexObject> expected) {
+        final DBObject dbObj;
+        getDs().save(hm);
+        dbObj = getDs().getCollection(HasComplexObjectValuedMap.class).findOne();
+        Assert.assertTrue("Should find the field", dbObj.containsField("properties"));
+        Assert.assertEquals(expected, getDs().createQuery(HasComplexObjectValuedMap.class).get().properties);
+    }
+
     private void shouldNotFindField(final HasMap hl) {
         getDs().save(hl);
         DBObject dbObj = getDs().getCollection(HasMap.class).findOne();
@@ -151,6 +204,20 @@ public class MapperOptionsTest extends TestBase {
         Assert.assertNull(getDs().createQuery(HasList.class).get().names);
     }
 
+    private void shouldNotFindField(final HasCollectionValuedMap hm) {
+        getDs().save(hm);
+        DBObject dbObj = getDs().getCollection(HasCollectionValuedMap.class).findOne();
+        Assert.assertFalse("field should not exist, value = " + dbObj.get("properties"), dbObj.containsField("properties"));
+        Assert.assertNull(getDs().createQuery(HasCollectionValuedMap.class).get().properties);
+    }
+
+    private void shouldNotFindField(final HasComplexObjectValuedMap hm) {
+        getDs().save(hm);
+        DBObject dbObj = getDs().getCollection(HasComplexObjectValuedMap.class).findOne();
+        Assert.assertFalse("field should not exist, value = " + dbObj.get("properties"), dbObj.containsField("properties"));
+        Assert.assertNull(getDs().createQuery(HasComplexObjectValuedMap.class).get().properties);
+    }
+
     private static class HasList implements Serializable {
         @Id
         private ObjectId id = new ObjectId();
@@ -169,8 +236,30 @@ public class MapperOptionsTest extends TestBase {
         }
     }
 
+    private static class HasCollectionValuedMap implements Serializable {
+        @Id
+        private ObjectId id = new ObjectId();
+        private Map<String, Collection<String>> properties;
+
+        HasCollectionValuedMap() {
+        }
+    }
+
+    private static class HasComplexObjectValuedMap implements Serializable {
+        @Id
+        private ObjectId id = new ObjectId();
+        private Map<String, ComplexObject> properties;
+
+        HasComplexObjectValuedMap() {
+        }
+    }
+
     @Entity
     private static class DummyEntity {
     }
 
+    private static class ComplexObject {
+        private String stringVal;
+        private int intVal;
+    }
 }