diff --git a/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java b/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
index 8820341..e136b10 100644
--- a/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
+++ b/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
@@ -44,6 +44,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 
 import javax.sql.DataSource;
+import javax.xml.transform.TransformerException;
 
 import org.geotools.data.DataStore;
 import org.geotools.data.DefaultQuery;
@@ -88,7 +89,9 @@ import org.opengis.filter.expression.PropertyName;
 import org.opengis.filter.identity.GmlObjectId;
 import org.opengis.filter.sort.SortBy;
 import org.opengis.filter.sort.SortOrder;
+import org.opengis.referencing.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.TransformException;
 
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
@@ -1078,64 +1081,86 @@ public final class JDBCDataStore extends ContentDataStore
         
         Statement st = null;
         ResultSet rs = null;
+        ReferencedEnvelope bounds = new ReferencedEnvelope(featureType.getCoordinateReferenceSystem());
         try {
-            if ( dialect instanceof PreparedStatementSQLDialect ) {
-                st = selectBoundsSQLPS(featureType, query, cx);
-                rs = ((PreparedStatement)st).executeQuery();
-            }
-            else {
-                String sql = selectBoundsSQL(featureType, query);
-                LOGGER.log(Level.FINE, "Retriving bounding box: {0}", sql);
-        
-                st = cx.createStatement();
-                rs = st.executeQuery(sql);
-            }
-                        
-            try {
-                ReferencedEnvelope bounds = null;
-                Envelope e = null;
-                if( rs.next() ) {
-                    e = dialect.decodeGeometryEnvelope(rs, 1, st.getConnection());
-                }
-                
-                if ( e == null ) {
-                    e = new Envelope();
-                    e.setToNull();
+            List<ReferencedEnvelope> result = dialect.getOptimizedBounds(databaseSchema, featureType, cx);
+            if(result != null && !result.isEmpty()) {
+                // merge the envelopes into one
+                for (ReferencedEnvelope envelope : result) {
+                    bounds = mergeEnvelope(bounds, envelope);
                 }
-               
-                if (e instanceof ReferencedEnvelope) {
-                    bounds = (ReferencedEnvelope) e;
+            } else {
+                // build an aggregate query
+                if ( dialect instanceof PreparedStatementSQLDialect ) {
+                    st = selectBoundsSQLPS(featureType, query, cx);
+                    rs = ((PreparedStatement)st).executeQuery();
                 } else {
-                    //set the crs to be the crs of the feature type
-                    // grab the 2d part of the crs 
-                    CoordinateReferenceSystem flatCRS = CRS.getHorizontalCRS(featureType.getCoordinateReferenceSystem());
-                    
-                    if ( e != null ) {
-                        bounds = new ReferencedEnvelope(e, flatCRS);
-                    }
-                    else {
-                        bounds = new ReferencedEnvelope( flatCRS );
-                        bounds.setToNull();
-                    }
+                    String sql = selectBoundsSQL(featureType, query);
+                    LOGGER.log(Level.FINE, "Retriving bounding box: {0}", sql);
+            
+                    st = cx.createStatement();
+                    rs = st.executeQuery(sql);
                 }
 
-                //keep going to handle case where envelope is not calculated
-                // as aggregate function
-		if (e.isNull()==false) { // featuretype not empty
-		  while (rs.next()) {
-		      bounds.expandToInclude(dialect.decodeGeometryEnvelope(rs, 1, st.getConnection()));
-		  }
-		}
-
-                return bounds;
-            }
-            finally {
-                closeSafe(rs);
-                closeSafe(st);
+                // scan through all the rows (just in case a non aggregated function was used)
+                // and through all the columns (in case we have multiple geometry columns)
+                CoordinateReferenceSystem flatCRS = CRS.getHorizontalCRS(featureType
+                        .getCoordinateReferenceSystem());
+                final int columns = rs.getMetaData().getColumnCount();
+                while (rs.next()) {
+                    for (int i = 1; i <= columns; i++) {
+                        final Envelope envelope = dialect.decodeGeometryEnvelope(rs, i, st.getConnection());
+                        if(envelope instanceof ReferencedEnvelope) {
+                            bounds = mergeEnvelope(bounds, (ReferencedEnvelope) envelope);
+                        } else {
+                            bounds = mergeEnvelope(bounds, new ReferencedEnvelope(envelope, flatCRS));
+                        }
+                    }
+                }
             }
-        } catch (SQLException e) {
+        } catch (Exception e) {
             String msg = "Error occured calculating bounds";
             throw (IOException) new IOException(msg).initCause(e);
+        } finally {
+            closeSafe(rs);
+            closeSafe(st);
+        }
+        
+        return bounds;
+    }
+    
+    /**
+     * Merges two envelopes handling possibly different CRS
+     * @param base
+     * @param merge
+     * @return
+     * @throws TransformException
+     * @throws FactoryException
+     */
+    ReferencedEnvelope mergeEnvelope(ReferencedEnvelope base, ReferencedEnvelope merge) 
+                        throws TransformException, FactoryException {
+        if(base == null || base.isNull()) {
+            return merge;
+        } else if(merge == null || merge.isNull()) {
+            return base;
+        } else {
+            // reproject and merge
+            final CoordinateReferenceSystem crsBase = base.getCoordinateReferenceSystem();
+            final CoordinateReferenceSystem crsMerge = merge.getCoordinateReferenceSystem();
+            if(crsBase == null) {
+                merge.expandToInclude(base);
+                return merge;
+            } else if(crsMerge == null) {
+                base.expandToInclude(base);
+                return base;
+            } else {
+                // both not null, are they equal?
+                if(!CRS.equalsIgnoreMetadata(crsBase, crsMerge)) {
+                    merge = merge.transform(crsBase, true);
+                }
+                base.expandToInclude(merge);
+                return base;
+            }
         }
     }
 
diff --git a/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java b/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
index bc4f70e..97c8355 100644
--- a/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
+++ b/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
@@ -26,6 +26,7 @@ import java.sql.SQLException;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.logging.Level;
@@ -38,6 +39,7 @@ import org.geotools.feature.visitor.MaxVisitor;
 import org.geotools.feature.visitor.MinVisitor;
 import org.geotools.feature.visitor.SumVisitor;
 import org.geotools.filter.FilterCapabilities;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.referencing.CRS;
 import org.geotools.util.logging.Logging;
 import org.opengis.feature.FeatureVisitor;
@@ -535,6 +537,26 @@ public abstract class SQLDialect {
             return null;
         }
     }
+    
+    /**
+     * Returns the bounds of all geometry columns in the layer using any approach that proves 
+     * to be faster than the plain bounds aggregation 
+     * (e.g., better than the "plain select extent(geom) from table" on PostGIS),
+     * or null if none exists or the fast method has not been enabled (e.g., if the fast method is
+     * just an estimate of the bounds you probably want the user to enable it manually)
+     * 
+     * @param schema
+     *            The database schema, if any, or null
+     * @param featureType
+     *            The feature type containing the geometry columns whose bounds need to computed.
+     *            Mind, it may be retyped and thus contain less geometry columns than the table
+     * @param cx
+     * @return a list of referenced envelopes (some of which may be null or empty)
+     */
+    public List<ReferencedEnvelope> getOptimizedBounds(String schema, SimpleFeatureType featureType,
+            Connection cx) throws SQLException, IOException {
+        return null;
+    }
 
     /**
      * Encodes the spatial extent function of a geometry column in a SELECT statement.
diff --git a/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleDialect.java b/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleDialect.java
index 2106eb3..90eacac 100644
--- a/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleDialect.java
+++ b/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleDialect.java
@@ -23,8 +23,10 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 
@@ -38,6 +40,7 @@ import org.geotools.data.oracle.sdo.GeometryConverter;
 import org.geotools.data.oracle.sdo.SDOSqlDumper;
 import org.geotools.data.oracle.sdo.TT;
 import org.geotools.factory.Hints;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.jdbc.JDBCDataStore;
 import org.geotools.jdbc.PreparedFilterToSQL;
 import org.geotools.jdbc.PreparedStatementSQLDialect;
@@ -121,6 +124,11 @@ public class OracleDialect extends PreparedStatementSQLDialect {
     boolean looseBBOXEnabled = false;
     
     /**
+     * Whether to use estimated extents to build
+     */
+    boolean estimatedExtentsEnabled = false;
+    
+    /**
      * Stores srid and their nature, true if geodetic, false otherwise. Avoids repeated
      * accesses to the MDSYS.GEODETIC_SRIDS table
      */
@@ -143,6 +151,14 @@ public class OracleDialect extends PreparedStatementSQLDialect {
         this.looseBBOXEnabled = looseBBOXEnabled;
     }
     
+    public boolean isEstimatedExtentsEnabled() {
+        return estimatedExtentsEnabled;
+    }
+
+    public void setEstimatedExtentsEnabled(boolean estimatedExtenstEnabled) {
+        this.estimatedExtentsEnabled = estimatedExtenstEnabled;
+    }
+
     /**
      * Checks the user has permissions to read from the USER_SDO_INDEX_METADATA and
      * USER_SDO_GEOM_METADATA. The code can use this information to decide to access the
@@ -580,6 +596,53 @@ public class OracleDialect extends PreparedStatementSQLDialect {
         encodeColumnName(geometryColumn, sql);
         sql.append( ")");
     }
+    
+    @Override
+    public List<ReferencedEnvelope> getOptimizedBounds(String schema, SimpleFeatureType featureType,
+            Connection cx) throws SQLException, IOException {
+        if (!estimatedExtentsEnabled)
+            return null;
+
+        String tableName = featureType.getTypeName();
+
+        Statement st = null;
+        ResultSet rs = null;
+
+        List<ReferencedEnvelope> result = new ArrayList<ReferencedEnvelope>();
+        try {
+            st = cx.createStatement();
+
+            for (AttributeDescriptor att : featureType.getAttributeDescriptors()) {
+                if (att instanceof GeometryDescriptor) {
+                    // use estimated extent (optimizer statistics)
+                    StringBuffer sql = new StringBuffer();
+                    sql.append("select SDO_TUNE.EXTENT_OF('");
+                    sql.append(tableName);
+                    sql.append("', '");
+                    sql.append(att.getName().getLocalPart());
+                    sql.append("') FROM DUAL");
+                    rs = st.executeQuery(sql.toString());
+
+                    if (rs.next()) {
+                        // decode the geometry
+                        Envelope env = decodeGeometryEnvelope(rs, 1, cx);
+
+                        // reproject and merge
+                        if (!env.isNull()) {
+                            CoordinateReferenceSystem crs = ((GeometryDescriptor) att)
+                                    .getCoordinateReferenceSystem();
+                            result.add(new ReferencedEnvelope(env, crs));
+                        }
+                    }
+                    rs.close();
+                }
+            }
+        } finally {
+            dataStore.closeSafe(rs);
+            dataStore.closeSafe(st);
+        }
+        return result;
+    }
 
     @Override
     public void postCreateTable(String schemaName,
diff --git a/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleNGDataStoreFactory.java b/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleNGDataStoreFactory.java
index 69da2fc..75b8b44 100644
--- a/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleNGDataStoreFactory.java
+++ b/modules/plugin/jdbc/jdbc-oracle/src/main/java/org/geotools/data/oracle/OracleNGDataStoreFactory.java
@@ -19,6 +19,7 @@ package org.geotools.data.oracle;
 import java.io.IOException;
 import java.util.Map;
 
+import org.geotools.data.DataAccessFactory.Param;
 import org.geotools.jdbc.JDBCDataStore;
 import org.geotools.jdbc.JDBCDataStoreFactory;
 import org.geotools.jdbc.SQLDialect;
@@ -40,6 +41,9 @@ public class OracleNGDataStoreFactory extends JDBCDataStoreFactory {
     /** parameter for database port */
     public static final Param PORT = new Param("port", Integer.class, "Port", true, 1521);
     
+    /** parameter that enables estimated extends instead of exact ones */ 
+    public static final Param ESTIMATED_EXTENTS = new Param("Estimated extends", Boolean.class, "Use the spatial index information to quickly get an estimate of the data bounds", false, Boolean.TRUE);
+    
     /** parameter for namespace of the datastore */
     public static final Param LOOSEBBOX = new Param("Loose bbox", Boolean.class, "Perform only primary filter on bbox", false, Boolean.TRUE);
     
@@ -100,6 +104,10 @@ public class OracleNGDataStoreFactory extends JDBCDataStoreFactory {
         Boolean loose = (Boolean) LOOSEBBOX.lookUp(params);
         dialect.setLooseBBOXEnabled(loose == null || Boolean.TRUE.equals(loose));
         
+        // check the estimated extents
+        Boolean estimated = (Boolean) ESTIMATED_EXTENTS.lookUp(params);
+        dialect.setEstimatedExtentsEnabled(estimated == null || Boolean.TRUE.equals(estimated));
+        
         // setup proper fetch size
         dataStore.setFetchSize(200);
         
@@ -126,6 +134,7 @@ public class OracleNGDataStoreFactory extends JDBCDataStoreFactory {
         
         super.setupParameters(parameters);
         parameters.put(LOOSEBBOX.key, LOOSEBBOX);
+        parameters.put(ESTIMATED_EXTENTS.key, ESTIMATED_EXTENTS);
         parameters.put(MAX_OPEN_PREPARED_STATEMENTS.key, MAX_OPEN_PREPARED_STATEMENTS);
         parameters.put(PORT.key, PORT);
         parameters.put(DBTYPE.key, DBTYPE);
diff --git a/modules/plugin/jdbc/jdbc-oracle/src/test/java/org/geotools/data/oracle/OracleFeatureSourceTest.java b/modules/plugin/jdbc/jdbc-oracle/src/test/java/org/geotools/data/oracle/OracleFeatureSourceTest.java
index 7131649..2006924 100644
--- a/modules/plugin/jdbc/jdbc-oracle/src/test/java/org/geotools/data/oracle/OracleFeatureSourceTest.java
+++ b/modules/plugin/jdbc/jdbc-oracle/src/test/java/org/geotools/data/oracle/OracleFeatureSourceTest.java
@@ -16,8 +16,11 @@
  */
 package org.geotools.data.oracle;
 
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.jdbc.JDBCDataStore;
 import org.geotools.jdbc.JDBCFeatureSourceTest;
 import org.geotools.jdbc.JDBCTestSetup;
+import org.geotools.referencing.CRS;
 
 public class OracleFeatureSourceTest extends JDBCFeatureSourceTest {
 
@@ -25,5 +28,18 @@ public class OracleFeatureSourceTest extends JDBCFeatureSourceTest {
     protected JDBCTestSetup createTestSetup() {
         return new OracleTestSetup();
     }
+    
+    public void testEstimatedBounds() throws Exception {
+        // enable fast bbox
+        ((OracleDialect) ((JDBCDataStore) dataStore).getSQLDialect()).setEstimatedExtentsEnabled(true);
+        
+        ReferencedEnvelope bounds = dataStore.getFeatureSource("FT1").getBounds();
+        assertEquals(0l, Math.round(bounds.getMinX()));
+        assertEquals(0l, Math.round(bounds.getMinY()));
+        assertEquals(2l, Math.round(bounds.getMaxX()));
+        assertEquals(2l, Math.round(bounds.getMaxY()));
+    
+        assertTrue(areCRSEqual(CRS.decode("EPSG:4326"), bounds.getCoordinateReferenceSystem()));
+    }
 
 }
diff --git a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
index def6eb0..afb8911 100644
--- a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
+++ b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
@@ -22,11 +22,14 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 
 import org.geotools.data.jdbc.FilterToSQL;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.jdbc.BasicSQLDialect;
 import org.geotools.jdbc.JDBCDataStore;
 import org.geotools.referencing.CRS;
@@ -106,6 +109,15 @@ public class PostGISDialect extends BasicSQLDialect {
     public void setLooseBBOXEnabled(boolean looseBBOXEnabled) {
         this.looseBBOXEnabled = looseBBOXEnabled;
     }
+    
+        
+    public boolean isEstimatedExtentsEnabled() {
+        return estimatedExtentsEnabled;
+    }
+
+    public void setEstimatedExtentsEnabled(boolean estimatedExtentsEnabled) {
+        this.estimatedExtentsEnabled = estimatedExtentsEnabled;
+    }
 
     @Override
     public boolean includeTable(String schemaName, String tableName,
@@ -164,13 +176,62 @@ public class PostGISDialect extends BasicSQLDialect {
     @Override
     public void encodeGeometryEnvelope(String tableName, String geometryColumn,
             StringBuffer sql) {
-        if (estimatedExtentsEnabled) {
-            sql.append("ST_Estimated_Extent(");
-            sql.append("'" + tableName + "','" + geometryColumn + "'))));");
-        } else {
-            sql.append("ST_AsText(ST_Force_2D(Envelope(");
-            sql.append("ST_Extent(\"" + geometryColumn + "\"::geometry))))");
-        }
+        sql.append("ST_AsText(ST_Force_2D(Envelope(");
+        sql.append("ST_Extent(\"" + geometryColumn + "\"::geometry))))");
+    }
+    
+    @Override
+    public List<ReferencedEnvelope> getOptimizedBounds(String schema, SimpleFeatureType featureType,
+            Connection cx) throws SQLException, IOException {
+        if (!estimatedExtentsEnabled)
+            return null;
+
+        String tableName = featureType.getTypeName();
+
+        Statement st = null;
+        ResultSet rs = null;
+
+        List<ReferencedEnvelope> result = new ArrayList<ReferencedEnvelope>();
+        try {
+            st = cx.createStatement();
+
+            for (AttributeDescriptor att : featureType.getAttributeDescriptors()) {
+                if (att instanceof GeometryDescriptor) {
+                    // use estimated extent (optimizer statistics)
+                    StringBuffer sql = new StringBuffer();
+                    sql.append("select AsText(force_2d(Envelope(ST_Estimated_Extent('");
+                    if(schema != null) {
+                        sql.append(schema);
+                        sql.append("', '");
+                    }
+                    sql.append(tableName);
+                    sql.append("', '");
+                    sql.append(att.getName().getLocalPart());
+                    sql.append("'))))");
+                    rs = st.executeQuery(sql.toString());
+
+                    if (rs.next()) {
+                        // decode the geometry
+                        Envelope env = decodeGeometryEnvelope(rs, 1, cx);
+
+                        // reproject and merge
+                        if (!env.isNull()) {
+                            CoordinateReferenceSystem crs = ((GeometryDescriptor) att)
+                                    .getCoordinateReferenceSystem();
+                            result.add(new ReferencedEnvelope(env, crs));
+                        }
+                    }
+                    rs.close();
+                }
+            }
+        } catch(SQLException e) {
+            LOGGER.log(Level.WARNING, "Failed to use ST_Estimated_Extent, falling back on envelope aggregation", e);
+            return null;
+        } finally {
+            dataStore.closeSafe(rs);
+            dataStore.closeSafe(st);
+        } 
+        return result;
     }
 
     @Override
diff --git a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGDataStoreFactory.java b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGDataStoreFactory.java
index a49f3f5..d7ed1b3 100644
--- a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGDataStoreFactory.java
+++ b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostgisNGDataStoreFactory.java
@@ -28,9 +28,12 @@ public class PostgisNGDataStoreFactory extends JDBCDataStoreFactory {
     /** parameter for database type */
     public static final Param DBTYPE = new Param("dbtype", String.class, "Type", true, "postgis");
     
-    /** parameter for namespace of the datastore */
+    /** enables using && in bbox queries */
     public static final Param LOOSEBBOX = new Param("Loose bbox", Boolean.class, "Perform only primary filter on bbox", false, Boolean.TRUE);
     
+    /** parameter that enables estimated extends instead of exact ones */ 
+    public static final Param ESTIMATED_EXTENTS = new Param("Estimated extends", Boolean.class, "Use the spatial index information to quickly get an estimate of the data bounds", false, Boolean.TRUE);
+    
     /** parameter for database port */
     public static final Param PORT = new Param("port", Integer.class, "Port", true, 5432);
     
@@ -95,12 +98,17 @@ public class PostgisNGDataStoreFactory extends JDBCDataStoreFactory {
         Boolean loose = (Boolean) LOOSEBBOX.lookUp(params);
         dialect.setLooseBBOXEnabled(loose == null || Boolean.TRUE.equals(loose));
         
+        // check the estimated extents
+        Boolean estimated = (Boolean) ESTIMATED_EXTENTS.lookUp(params);
+        dialect.setEstimatedExtentsEnabled(estimated == null || Boolean.TRUE.equals(estimated));
+        
         // setup the ps dialect if need be
         Boolean usePs = (Boolean) PREPARED_STATEMENTS.lookUp(params);
         if(Boolean.TRUE.equals(usePs)) {
             dataStore.setSQLDialect(new PostGISPSDialect(dataStore, dialect));
         }
         
+        
         return dataStore;
     }
     
@@ -112,6 +120,7 @@ public class PostgisNGDataStoreFactory extends JDBCDataStoreFactory {
         parameters.put(DBTYPE.key, DBTYPE);
         parameters.put(SCHEMA.key, SCHEMA);
         parameters.put(LOOSEBBOX.key, LOOSEBBOX);
+        parameters.put(ESTIMATED_EXTENTS.key, ESTIMATED_EXTENTS);
         parameters.put(PORT.key, PORT);
         parameters.put(PREPARED_STATEMENTS.key, PREPARED_STATEMENTS);
         parameters.put(MAX_OPEN_PREPARED_STATEMENTS.key, MAX_OPEN_PREPARED_STATEMENTS);
diff --git a/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISFeatureSourceTest.java b/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISFeatureSourceTest.java
index 5eba793..89f57f6 100644
--- a/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISFeatureSourceTest.java
+++ b/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISFeatureSourceTest.java
@@ -15,8 +15,11 @@
  *    Lesser General Public License for more details.
  */
 package org.geotools.data.postgis;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.jdbc.JDBCDataStore;
 import org.geotools.jdbc.JDBCFeatureSourceTest;
 import org.geotools.jdbc.JDBCTestSetup;
+import org.geotools.referencing.CRS;
 
 
 public class PostGISFeatureSourceTest extends JDBCFeatureSourceTest {
@@ -25,5 +28,25 @@ public class PostGISFeatureSourceTest extends JDBCFeatureSourceTest {
     protected JDBCTestSetup createTestSetup() {
         return new PostGISTestSetup();
     }
+    
+    
+    @Override
+    protected void setUpInternal() throws Exception {
+        super.setUpInternal();
+    }
+    
+    public void testEstimatedBounds() throws Exception {
+        // enable fast bbox
+        ((PostGISDialect) ((JDBCDataStore) dataStore).getSQLDialect()).setEstimatedExtentsEnabled(true);
+        
+        ReferencedEnvelope bounds = dataStore.getFeatureSource("ft1").getBounds();
+        assertEquals(0l, Math.round(bounds.getMinX()));
+        assertEquals(0l, Math.round(bounds.getMinY()));
+        assertEquals(2l, Math.round(bounds.getMaxX()));
+        assertEquals(2l, Math.round(bounds.getMaxY()));
+    
+        assertTrue(areCRSEqual(CRS.decode("EPSG:4326"), bounds.getCoordinateReferenceSystem()));
+    }
+    
 
 }
diff --git a/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java b/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
index 2c66d5a..e36be9a 100644
--- a/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
+++ b/modules/plugin/jdbc/jdbc-postgis/src/test/java/org/geotools/data/postgis/PostGISTestSetup.java
@@ -31,6 +31,9 @@ public class PostGISTestSetup extends JDBCTestSetup {
         // the unit tests assume a non loose behaviour
         ((PostGISDialect) dataStore.getSQLDialect()).setLooseBBOXEnabled(false);
         
+        // the tests assume non estimated extents 
+        ((PostGISDialect) dataStore.getSQLDialect()).setEstimatedExtentsEnabled(false);
+        
         // let's work with the most common schema please
         dataStore.setDatabaseSchema("public");
     }
@@ -69,6 +72,9 @@ public class PostGISTestSetup extends JDBCTestSetup {
         // advance the sequence to 2
         run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
         run("SELECT nextval(pg_get_serial_sequence('ft1','id'))");
+        // analyze so that the stats will be up to date
+        run("ANALYZE \"ft1\"");
+
     }
 
     @Override
