Index: main/java/org/geotools/data/memory/MemoryDataStore.java
===================================================================
--- main/java/org/geotools/data/memory/MemoryDataStore.java	(revision 32714)
+++ main/java/org/geotools/data/memory/MemoryDataStore.java	(working copy)
@@ -17,23 +17,16 @@
 package org.geotools.data.memory;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 
 import org.geotools.data.AbstractDataStore;
-import org.geotools.data.DataAccess;
 import org.geotools.data.DataSourceException;
-import org.geotools.data.DataStore;
-import org.geotools.data.DataUtilities;
 import org.geotools.data.FeatureReader;
-import org.geotools.data.FeatureSource;
 import org.geotools.data.FeatureWriter;
 import org.geotools.data.Query;
 import org.geotools.data.SchemaNotFoundException;
@@ -47,8 +40,8 @@
 import org.opengis.feature.FeatureVisitor;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.feature.type.Name;
 import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
@@ -76,15 +69,27 @@
  */
 public class MemoryDataStore extends AbstractDataStore {
     /** Memory holds Map of Feature by fid by typeName. */
-    protected Map memory = new HashMap();
+    protected Map<String,Map<String,SimpleFeature>> memory = new ConcurrentHashMap<String,Map<String,SimpleFeature>>();
 
     /** Schema holds FeatureType by typeName */
-    protected Map schema = new HashMap();
+    protected Map<String,SimpleFeatureType> schema = new ConcurrentHashMap<String,SimpleFeatureType>();
 
     public MemoryDataStore() {
         super(true);
     }
 
+    /**
+     * Construct an MemoryDataStore around an empty collection of the provided SimpleFeatureType
+     * @param schema An empty feature collection of this type will be made available
+     */
+    public MemoryDataStore(SimpleFeatureType featureType) {
+    	try {
+			createSchema(featureType);
+		} catch (IOException e) {
+			// this should never happen
+			throw new RuntimeException(e);
+		}
+    }
     public MemoryDataStore(FeatureCollection<SimpleFeatureType, SimpleFeature> collection) {
         addFeatures(collection);
     }
@@ -114,7 +119,7 @@
             // use an order preserving map, so that features are returned in the same
             // order as they were inserted. This is important for repeatable rendering
             // of overlapping features.
-            Map featureMap = new LinkedHashMap();
+            Map<String,SimpleFeature> featureMap = new ConcurrentHashMap<String,SimpleFeature>();
             String typeName;
             SimpleFeature feature;
 
@@ -155,7 +160,7 @@
     public void addFeatures(FeatureIterator<SimpleFeature> reader) throws IOException {
         try {
             SimpleFeatureType featureType;
-            Map featureMap = new HashMap();
+            Map<String,SimpleFeature> featureMap = new ConcurrentHashMap<String,SimpleFeature>();
             String typeName;
             SimpleFeature feature;
 
@@ -198,27 +203,25 @@
             throw new IllegalArgumentException("Provided FeatureCollection<SimpleFeatureType, SimpleFeature> is empty");
         }
 
-        synchronized (memory) {
-            for (Iterator i = collection.iterator(); i.hasNext();) {
-                addFeatureInternal((SimpleFeature) i.next());
-            }
+        for (Iterator i = collection.iterator(); i.hasNext();) {
+            addFeatureInternal((SimpleFeature) i.next());
         }
     }
-    public void addFeatures(FeatureCollection collection) {
+    
+    public void addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> collection) {
         if ((collection == null) ) {
             throw new IllegalArgumentException("Provided FeatureCollection<SimpleFeatureType, SimpleFeature> is empty");
         }
-        synchronized (memory) {
-            try {
-                collection.accepts( new FeatureVisitor(){
-                    public void visit(Feature feature) {
-                        addFeatureInternal( (SimpleFeature) feature );
-                    }                
-                }, null );
-            }
-            catch( IOException ignore){
-                LOGGER.log( Level.FINE, "Unable to add all features", ignore );
-            }
+
+        try {
+            collection.accepts( new FeatureVisitor(){
+                public void visit(Feature feature) {
+                    addFeatureInternal( (SimpleFeature) feature );
+                }                
+            }, null );
+        }
+        catch( IOException ignore){
+            LOGGER.log( Level.FINE, "Unable to add all features", ignore );
         }
     }
     /**
@@ -233,11 +236,9 @@
             throw new IllegalArgumentException("Provided features are empty");
         }
 
-        synchronized (memory) {
-            for (int i = 0; i < features.length; i++) {
-                addFeatureInternal(features[i]);
-            }
-        }
+		for (int i = 0; i < features.length; i++) {
+        	addFeatureInternal(features[i]);
+		}
     }
 
     /**
@@ -255,9 +256,7 @@
      * @param feature Individual feature to add
      */
     public void addFeature(SimpleFeature feature) {
-        synchronized (memory) {
-            addFeatureInternal(feature);
-        }
+		addFeatureInternal(feature);
     }
 
     private void addFeatureInternal(SimpleFeature feature) {
@@ -270,19 +269,18 @@
 
         String typeName = featureType.getTypeName();
 
-        Map featuresMap;
-
         if (!memory.containsKey(typeName)) {
             try {
                 createSchema(featureType);
             } catch (IOException e) {
                 // this should not of happened ?!?
                 // only happens if typeNames is taken and
-                // we just checked                    
+                // we just checked           
+                throw new RuntimeException(e);         
             }
         }
 
-        featuresMap = (Map) memory.get(typeName);
+		Map<String, SimpleFeature> featuresMap = (Map) memory.get(typeName);
         featuresMap.put(feature.getID(), feature);
     }
 
@@ -295,12 +293,10 @@
      *
      * @throws IOException If typeName cannot be found
      */
-    protected Map features(String typeName) throws IOException {
-        synchronized (memory) {
-            if (memory.containsKey(typeName)) {
-                return (Map) memory.get(typeName);
-            }
-        }
+    protected Map<String, SimpleFeature> features(String typeName) throws IOException {
+        if (memory.containsKey(typeName)) {
+			return (Map<String, SimpleFeature>) memory.get(typeName);
+		}
 
         throw new IOException("Type name " + typeName + " not found");
     }
@@ -313,16 +309,14 @@
      * @see org.geotools.data.AbstractDataStore#getFeatureTypes()
      */
     public String[] getTypeNames() {
-        synchronized (memory) {
-            String[] types = new String[schema.size()];
-            int index = 0;
+		String[] types = new String[schema.size()];
+        int index = 0;
 
-            for (Iterator i = schema.keySet().iterator(); i.hasNext(); index++) {
-                types[index] = (String) i.next();
-            }
+        for (Iterator i = schema.keySet().iterator(); i.hasNext(); index++) {
+        	types[index] = (String) i.next();
+		}
 
-            return types;
-        }
+        return types;
     }
 
     /**
@@ -338,12 +332,11 @@
      * @see org.geotools.data.AbstractDataStore#getSchema(java.lang.String)
      */
     public SimpleFeatureType getSchema(String typeName) throws IOException {
-        synchronized (memory) {
-            if (schema.containsKey(typeName)) {
-                return (SimpleFeatureType) schema.get(typeName);
-            }
-                throw new SchemaNotFoundException(typeName);
-        }
+		if (schema.containsKey(typeName)) {
+        	return (SimpleFeatureType) schema.get(typeName);
+		}
+        
+        throw new SchemaNotFoundException(typeName);
     }
 
     /**
@@ -367,10 +360,10 @@
             // we have a conflict
             throw new IOException(typeName + " already exists");
         }
-            // insertion order preserving map
-            Map featuresMap = new LinkedHashMap();
-            schema.put(typeName, featureType);
-            memory.put(typeName, featuresMap);
+        
+        Map<String,SimpleFeature> featureMap = new ConcurrentHashMap<String,SimpleFeature>();
+        schema.put(typeName, featureType);
+        memory.put(typeName, featureMap);
     }
 
     /**
@@ -579,25 +572,25 @@
     protected ReferencedEnvelope getBounds(Query query)
         throws IOException {
         String typeName = query.getTypeName();
-        Map contents = features(typeName);
-        Iterator iterator = contents.values().iterator();
+        Map<String, SimpleFeature> contents = features(typeName);
+        Iterator<SimpleFeature> iterator = contents.values().iterator();
 
+        CoordinateReferenceSystem coordinateSystem = query.getCoordinateSystem();
         ReferencedEnvelope envelope = null;
-
-        if (iterator.hasNext()) {
-            int count = 1;
-            Filter filter = query.getFilter();
-            SimpleFeature first = (SimpleFeature) iterator.next();
-            Envelope env = ((Geometry) first.getDefaultGeometry()).getEnvelopeInternal();
-			envelope = new ReferencedEnvelope(env, first.getType().getCoordinateReferenceSystem());
-
-            while (iterator.hasNext() && (count < query.getMaxFeatures())) {
-                SimpleFeature feature = (SimpleFeature) iterator.next();
-
-                if (filter.evaluate(feature)) {
-                    count++;
-                    envelope.expandToInclude(((Geometry) feature.getDefaultGeometry()).getEnvelopeInternal());
+        
+        Filter filter = query.getFilter();
+        
+        int count = 0;
+        while(iterator.hasNext() && (count < query.getMaxFeatures())) {
+            count ++;
+            SimpleFeature feature = (SimpleFeature) iterator.next();
+            if(filter.evaluate(feature)) {
+                count++;
+                Envelope env = ((Geometry) feature.getDefaultGeometry()).getEnvelopeInternal();
+                if (null == envelope) {
+                    envelope = new ReferencedEnvelope(coordinateSystem);
                 }
+                envelope.expandToInclude(env);
             }
         }
 
@@ -610,15 +603,15 @@
     protected int getCount(Query query)
         throws IOException {
         String typeName = query.getTypeName();
-        Map contents = features(typeName);
-        Iterator iterator = contents.values().iterator();
+        Map<String, SimpleFeature> contents = features(typeName);
+        Iterator<SimpleFeature> iterator = contents.values().iterator();
 
         int count = 0;
 
         Filter filter = query.getFilter();
 
         while (iterator.hasNext() && (count < query.getMaxFeatures())) {
-            if (filter.evaluate((SimpleFeature) iterator.next())) {
+            if (filter.evaluate(iterator.next())) {
                 count++;
             }
         }
@@ -626,4 +619,4 @@
         return count;
     }
 
-}
+}
\ No newline at end of file
Index: test/java/org/geotools/data/memory/MemoryDataStoreTest.java
===================================================================
--- test/java/org/geotools/data/memory/MemoryDataStoreTest.java	(revision 32714)
+++ test/java/org/geotools/data/memory/MemoryDataStoreTest.java	(working copy)
@@ -1267,4 +1267,15 @@
         } while ( then > System.currentTimeMillis() - 515 );     
         assertFalse(isLocked("road", "road.rd1"));
     }
+
+    /**
+     * @see http://jira.codehaus.org/browse/GEOT-2404
+     * @throws Exception
+     */
+    public void testGetBounds() throws Exception {
+        // the Bounds of the queried features should be equal to the bounding 
+        // box of the road2 feature, because of the road2 FID filter
+        Query query = new DefaultQuery("road", rd2Filter);
+        assertEquals(roadFeatures[1].getBounds(), data.getBounds(query));
+    }
 }
