diff --git a/configure.in b/configure.in
index 6088b7a..fc1b825 100755
--- a/configure.in
+++ b/configure.in
@@ -1285,6 +1285,7 @@ else
   fi
 
   dnl Try to locate include directory
+  test -f $ORA_HOME/include/oci.h && ORA_INCDIR="$ORA_HOME/include"
   test -f $ORA_HOME/sdk/include/oci.h && ORA_INCDIR="$ORA_HOME/sdk/include"
   test -f $ORA_HOME/rdbms/public/oci.h && ORA_INCDIR="$ORA_HOME/rdbms/public"
   test -f $ORA_HOME/rdbms/demo/oci.h && ORA_INCDIR="$ORA_HOME/rdbms/public"
diff --git a/mapdraw.c b/mapdraw.c
index a4c3d78..1d70d24 100644
--- a/mapdraw.c
+++ b/mapdraw.c
@@ -964,7 +964,7 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image)
   if((map->projection.numargs > 0) && (layer->projection.numargs > 0))
     msProjectRect(&map->projection, &layer->projection, &searchrect); /* project the searchrect to source coords */
 #endif
-    
+
   status = msLayerWhichShapes(layer, searchrect, MS_FALSE);
   if(status == MS_DONE) { /* no overlap */
     msLayerClose(layer);
diff --git a/mapgml.c b/mapgml.c
index ad5539a..24f5927 100644
--- a/mapgml.c
+++ b/mapgml.c
@@ -1532,8 +1532,6 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int startindex, int maxfeature
         msFreeShape(&shape); /* init too */
 
         features++;
-        if (maxfeatures > 0 && features == maxfeatures)
-          break; 
       }      
 
       /* done with this layer, do a little clean-up */      
@@ -1547,9 +1545,6 @@ int msGMLWriteWFSQuery(mapObj *map, FILE *stream, int startindex, int maxfeature
       /* msLayerClose(lp); */
     }
 
-    if (maxfeatures > 0 && features == maxfeatures)
-      break;
-
   } /* next layer */
 
   return(MS_SUCCESS);
diff --git a/maplayer.c b/maplayer.c
index d630f7f..14a4658 100644
--- a/maplayer.c
+++ b/maplayer.c
@@ -1194,7 +1194,9 @@ msLayerApplyCondSQLFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
 
 int msLayerSupportsPaging(layerObj *layer)
 {
-    if (layer && layer->connectiontype == MS_ORACLESPATIAL)
+    if (layer &&
+        ((layer->connectiontype == MS_ORACLESPATIAL) ||
+         (layer->connectiontype == MS_POSTGIS)) )
       return MS_TRUE;
 
     return MS_FALSE;
@@ -1211,6 +1213,30 @@ msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
 #endif
 }
 
+int msLayerGetPaging(layerObj *layer)
+{
+  if ( ! layer->vtable) {
+    int rv =  msInitializeVirtualTable(layer);
+    if (rv != MS_SUCCESS) {
+      msSetError(MS_MISCERR, "Unable to initialize virtual table", "msLayerGetPaging()");
+      return;
+    }
+  }
+    return layer->vtable->LayerGetPaging(layer);
+}
+
+void msLayerEnablePaging(layerObj *layer, int value) 
+{
+    if ( ! layer->vtable) {
+        int rv =  msInitializeVirtualTable(layer);
+        if (rv != MS_SUCCESS) {
+            msSetError(MS_MISCERR, "Unable to initialize virtual table", "msLayerEnablePaging()");
+            return;
+        }
+    }
+    return layer->vtable->LayerEnablePaging(layer, value);
+}
+
 int LayerDefaultGetExtent(layerObj *layer, rectObj *extent)
 {
   return MS_FAILURE;
@@ -1255,6 +1281,16 @@ int LayerDefaultSupportsCommonFilters(layerObj *layer)
   return MS_FALSE;
 }
 
+int msLayerDefaultGetPaging(layerObj *layer)
+{
+  return MS_TRUE;
+}
+
+void msLayerDefaultEnablePaging(layerObj *layer, int value)
+{
+  return;
+}
+
 /************************************************************************/
 /*                          LayerDefaultEscapeSQLParam                  */
 /*                                                                      */
@@ -1398,6 +1434,9 @@ static int populateVirtualTable(layerVTableObj *vtable)
 
   vtable->LayerEscapePropertyName = LayerDefaultEscapePropertyName;
 
+  vtable->LayerEnablePaging = msLayerDefaultEnablePaging;
+  vtable->LayerGetPaging = msLayerDefaultGetPaging;
+
   return MS_SUCCESS;
 }
 
@@ -1631,6 +1670,10 @@ msINLINELayerInitializeVirtualTable(layerObj *layer)
 
     /*layer->vtable->LayerEscapeSQLParam, use default*/
     /*layer->vtable->LayerEscapePropertyName, use default*/
+
+    /* layer->vtable->LayerEnablePaging, use default */
+    /* layer->vtable->LayerGetPaging, use default */    
+    
     return MS_SUCCESS;
 }
 
diff --git a/mapogcfilter.c b/mapogcfilter.c
index 2f8e5fa..f01d435 100644
--- a/mapogcfilter.c
+++ b/mapogcfilter.c
@@ -3676,6 +3676,7 @@ void FLTPreParseFilterForAlias(FilterEncodingNode *psFilterNode,
     layerObj *lp=NULL;
     char szTmp[256];
     const char *pszFullName = NULL;
+    int layerWasOpened =  MS_FALSE;
 
 #if defined(USE_WMS_SVR) || defined (USE_WFS_SVR) || defined (USE_WCS_SVR) || defined(USE_SOS_SVR)
 
@@ -3685,6 +3686,7 @@ void FLTPreParseFilterForAlias(FilterEncodingNode *psFilterNode,
         FLTStripNameSpacesFromPropertyName(psFilterNode);
 
         lp = GET_LAYER(map, i);
+        layerWasOpened = msLayerIsOpen(lp); 
         if (msLayerOpen(lp) == MS_SUCCESS && msLayerGetItems(lp) == MS_SUCCESS)
         {
             for(i=0; i<lp->numitems; i++) 
@@ -3699,7 +3701,8 @@ void FLTPreParseFilterForAlias(FilterEncodingNode *psFilterNode,
                                            lp->items[i]);
                 }
             }
-            msLayerClose(lp);
+            if (!layerWasOpened) /* do not close the layer if it has been opened somewhere else (paging?) */
+                msLayerClose(lp);
         }
     } 
 #else
diff --git a/maporaclespatial.c b/maporaclespatial.c
index 9d5d27d..97dbb85 100644
--- a/maporaclespatial.c
+++ b/maporaclespatial.c
@@ -167,7 +167,9 @@ typedef
          * disposed by CloseLayer (if set)
          */
         msOracleSpatialStatement *orastmt2;
-        
+        /* Driver handling of pagination, enabled by default */
+        int paging;
+      
     } msOracleSpatialLayerInfo;
     
 static OCIType  *ordinates_tdo = NULL;
@@ -1775,7 +1777,7 @@ int msOracleSpatialLayerOpen( layerObj *layer )
     dthand = (msOracleSpatialDataHandler *)malloc(sizeof(msOracleSpatialDataHandler));
     sthand = (msOracleSpatialStatement *)malloc(sizeof(msOracleSpatialStatement));
     sthand2 = (msOracleSpatialStatement *)malloc(sizeof(msOracleSpatialStatement));
-
+    
     if ((dthand == NULL) || (layerinfo == NULL))
     {
         msSetError(MS_MEMERR, NULL, "msOracleSpatialLayerOpen()");
@@ -1786,7 +1788,8 @@ int msOracleSpatialLayerOpen( layerObj *layer )
     memset( sthand, 0, sizeof(msOracleSpatialStatement) );
     memset( sthand2, 0, sizeof(msOracleSpatialStatement) );
     memset( layerinfo, 0, sizeof(msOracleSpatialLayerInfo) );
-
+    layerinfo->paging = MS_TRUE;
+      
     msSplitLogin( layer->connection, layer->map, &username, &password, &dblink );
 
     hand = (msOracleSpatialHandler *) msConnPoolRequest( layer );
@@ -2072,7 +2075,7 @@ int msOracleSpatialLayerWhichShapes( layerObj *layer, rectObj rect, int isQuery)
 
     osFilteritem(layer, function, query_str, sizeof(query_str), 1);
 
-    if (layer->maxfeatures > 0 && layer->startindex < 0)
+    if (layerinfo->paging && layer->maxfeatures > 0 && layer->startindex < 0)
     {
        if (function == FUNCTION_NONE && layer->filter.string == NULL)
            snprintf( query_str + strlen(query_str), sizeof(query_str)-strlen(query_str), "%s"," WHERE ");
@@ -2091,7 +2094,7 @@ int msOracleSpatialLayerWhichShapes( layerObj *layer, rectObj rect, int isQuery)
 
 
     /*assuming startindex starts at 1*/
-    if (layer->startindex > 0)
+    if (layerinfo->paging && layer->startindex > 0)
      {
        tmp1_str = msStrdup("SELECT * from (SELECT atmp.*, ROWNUM rnum from (");
        tmp_str = msStringConcatenate(tmp_str,  tmp1_str);
@@ -3497,6 +3500,40 @@ int msOracleSpatialLayerGetAutoStyle( mapObj *map, layerObj *layer, classObj *c,
     return MS_FAILURE; 
 }
 
+int msOrableSpatialGetPaging(layerObj *layer)
+{
+    msOracleSpatialLayerInfo *layerinfo = NULL;
+    
+    if (layer->debug)
+        msDebug("msOracleSpatialLayerGetPaging was called.\n");
+
+    if(!msOracleSpatialLayerIsOpen(layer))
+      return MS_TRUE;
+    
+    assert( layer->layerinfo != NULL);
+    layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
+
+    return layerinfo->paging;
+}
+
+void msOrableSpatialEnablePaging(layerObj *layer, int value)
+{
+    msOracleSpatialLayerInfo *layerinfo = NULL;
+    
+    if (layer->debug)
+        msDebug("msOracleSpatialLayerEnablePaging was called.\n");
+
+    if(!msOracleSpatialLayerIsOpen(layer))
+        msOracleSpatialLayerOpen(layer);
+
+    assert( layer->layerinfo != NULL);
+    layerinfo = (msOracleSpatialLayerInfo *)layer->layerinfo;
+
+    layerinfo->paging = value;
+    
+    return;
+}
+
 #else
 /* OracleSpatial "not-supported" procedures */
 
@@ -3565,6 +3602,18 @@ int msOracleSpatialLayerGetAutoStyle( mapObj *map, layerObj *layer, classObj *c,
   return MS_FAILURE;
 }
 
+void msOrableSpatialEnablePaging(layerObj *layer, int value)
+{
+  msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerEnablePaging()" );  
+  return;
+}
+
+int msOrableSpatialGetPaging(layerObj *layer)
+{
+  msSetError( MS_ORACLESPATIALERR, "OracleSpatial is not supported", "msLayerGetPaging()" );  
+  return;
+}
+
 #endif
 
 #ifdef USE_ORACLE_PLUGIN 
@@ -3593,7 +3642,9 @@ PluginInitializeVirtualTable(layerVTableObj* vtable, layerObj *layer)
     vtable->LayerSetTimeFilter = msLayerMakePlainTimeFilter;
     /* layer->vtable->LayerGetNumFeatures, use default */
     /* layer->vtable->LayerGetAutoProjection = msOracleSpatialLayerGetAutoProjection; Disabled until tested */
-
+    vtable->LayerEnablePaging = msOrableSpatialEnablePaging;
+    vtable->LayerGetPaging = msOrableSpatialGetPaging;    
+    
     return MS_SUCCESS;
 }
 #endif
@@ -3621,7 +3672,9 @@ int msOracleSpatialLayerInitializeVirtualTable(layerObj *layer)
     /* layer->vtable->LayerCreateItems, use default */
     /* layer->vtable->LayerGetNumFeatures, use default */
     /* layer->vtable->LayerGetAutoProjection = msOracleSpatialLayerGetAutoProjection; Disabled until tested */
-
+    layer->vtable->LayerEnablePaging = msOrableSpatialEnablePaging;
+    layer->vtable->LayerGetPaging = msOrableSpatialGetPaging;    
+    
     return MS_SUCCESS;
 }
 
diff --git a/mappostgis.c b/mappostgis.c
index 3078a41..27a38f9 100644
--- a/mappostgis.c
+++ b/mappostgis.c
@@ -107,6 +107,7 @@ msPostGISLayerInfo *msPostGISCreateLayerInfo(void) {
     layerinfo->endian = 0;
     layerinfo->rownum = 0;
     layerinfo->version = 0;
+    layerinfo->paging = MS_TRUE;        
     return layerinfo;
 }
 
@@ -1862,10 +1863,12 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid) {
     char *strUid = 0;
     char *strWhere = 0;
     char *strLimit = 0;
+    char *strOffset = 0;
     size_t strRectLength = 0;
     size_t strFilterLength = 0;
     size_t strUidLength = 0;
     size_t strLimitLength = 0;
+    size_t strOffsetLength = 0;
     size_t bufferSize = 0;
     int insert_and = 0;
     msPostGISLayerInfo *layerinfo;
@@ -1884,13 +1887,21 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid) {
     }
 
     /* Populate strLimit, if necessary. */
-    if( layer->maxfeatures >= 0 ) {
+    if ( layerinfo->paging && layer->maxfeatures >= 0 ) {
         static char *strLimitTemplate = " limit %d";
         strLimit = msSmallMalloc(strlen(strLimitTemplate) + 12);
         sprintf(strLimit, strLimitTemplate, layer->maxfeatures);
         strLimitLength = strlen(strLimit);
     }
-    
+
+    /* Populate strOffset, if necessary. */
+    if ( layerinfo->paging && layer->startindex > 0 ) {
+        static char *strOffsetTemplate = " offset %d";
+        strOffset = msSmallMalloc(strlen(strOffsetTemplate) + 12);
+        sprintf(strOffset, strOffsetTemplate, layer->maxfeatures);
+        strOffsetLength = strlen(strOffset);
+    }
+
     /* Populate strRect, if necessary. */
     if ( rect && layerinfo->geomcolumn ) {
         char *strBox = 0;
@@ -1936,7 +1947,8 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid) {
         strUidLength = strlen(strUid);
     }
 
-    bufferSize = strRectLength + 5 + strFilterLength + 5 + strUidLength + strLimitLength;
+    bufferSize = strRectLength + 5 + strFilterLength + 5 + strUidLength
+        + strLimitLength + strOffsetLength;
     strWhere = (char*)msSmallMalloc(bufferSize);
     *strWhere = '\0';
     if ( strRect ) {
@@ -1964,6 +1976,10 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid) {
         strlcat(strWhere, strLimit, bufferSize);
         free(strLimit);
     }
+    if ( strOffset ) {
+        strlcat(strWhere, strOffset, bufferSize);
+        free(strOffset);
+    }
 
     return strWhere;
 }
@@ -2219,7 +2235,7 @@ int msPostGISLayerOpen(layerObj *layer) {
     ** Initialize the layerinfo 
     **/
     layerinfo = msPostGISCreateLayerInfo();
-
+    
     if (((char*) &order_test)[0] == 1) {
         layerinfo->endian = LITTLE_ENDIAN;
     } else {
@@ -3282,6 +3298,41 @@ char *msPostGISEscapeSQLParam(layerObj *layer, const char *pszString)
 #endif
 }
 
+void msPostGISEnablePaging(layerObj *layer, int value) {
+
+    msPostGISLayerInfo *layerinfo = NULL;
+
+    if (layer->debug) {
+        msDebug("msPostGISEnablePaging called.\n");
+    }
+
+    if(!msPostGISLayerIsOpen(layer))
+      msPostGISLayerOpen(layer);
+
+    assert( layer->layerinfo != NULL);
+
+    layerinfo = (msPostGISLayerInfo *)layer->layerinfo;
+    layerinfo->paging = value;
+
+    return;
+}
+
+int msPostGISGetPaging(layerObj *layer) {
+
+    msPostGISLayerInfo *layerinfo = NULL;
+
+    if (layer->debug) {
+        msDebug("msPostGISGetPaging called.\n");
+    }
+
+    if(!msPostGISLayerIsOpen(layer))
+      return MS_TRUE;
+
+    assert( layer->layerinfo != NULL);
+
+    layerinfo = (msPostGISLayerInfo *)layer->layerinfo;
+    return layerinfo->paging;
+}
 
 int msPostGISLayerInitializeVirtualTable(layerObj *layer) {
     assert(layer != NULL);
@@ -3307,6 +3358,8 @@ int msPostGISLayerInitializeVirtualTable(layerObj *layer) {
     /* layer->vtable->LayerGetAutoProjection, use defaut*/  
 
     layer->vtable->LayerEscapeSQLParam = msPostGISEscapeSQLParam;
+    layer->vtable->LayerEnablePaging = msPostGISEnablePaging;
+    layer->vtable->LayerGetPaging = msPostGISGetPaging;        
 
     return MS_SUCCESS;
 }
diff --git a/mappostgis.h b/mappostgis.h
index 01221b0..e03a5c5 100644
--- a/mappostgis.h
+++ b/mappostgis.h
@@ -63,6 +63,7 @@ typedef struct {
     char        *fromsource; /* Specified record source, ed "thegeom from THETABLE" or "thegeom from (SELECT..) AS FOO" */
     int         endian;      /* Endianness of the mapserver host */
     int         version;     /* PostGIS version of the database */
+    int         paging;      /* Driver handling of pagination, enabled by default */
 }
 msPostGISLayerInfo;
 
diff --git a/mapquery.c b/mapquery.c
index c527572..fec372f 100644
--- a/mapquery.c
+++ b/mapquery.c
@@ -488,7 +488,7 @@ int msQueryByIndex(mapObj *map)
   }
 
   lp = (GET_LAYER(map, map->query.layer));
-
+  
   if(!msIsLayerQueryable(lp)) {
     msSetError(MS_QUERYERR, "Requested layer has no templates defined.", "msQueryByIndex()"); 
     return(MS_FAILURE);
@@ -505,6 +505,8 @@ int msQueryByIndex(mapObj *map)
   msLayerClose(lp); /* reset */
   status = msLayerOpen(lp);
   if(status != MS_SUCCESS) return(MS_FAILURE);
+  /* disable driver paging */
+  msLayerEnablePaging(lp, MS_FALSE);  
 
   /* build item list, we want *all* items */
   status = msLayerWhichItems(lp, MS_TRUE, NULL);
@@ -596,6 +598,7 @@ int msQueryByAttributes(mapObj *map)
   rectObj searchrect;
 
   shapeObj shape;
+  int paging;
   
   int nclasses = 0;
   int *classgroup = NULL;
@@ -651,12 +654,15 @@ int msQueryByAttributes(mapObj *map)
 
   msInitShape(&shape);
 
+  /* Paging could have been disabled before */ 
+  paging = msLayerGetPaging(lp);
   msLayerClose(lp); /* reset */
   status = msLayerOpen(lp);
   if(status != MS_SUCCESS) {
     msRestoreOldFilter(lp, old_filtertype, old_filteritem, old_filterstring); /* manually reset the filter */
     return(MS_FAILURE);
   }
+  msLayerEnablePaging(lp, paging);  
   
   /* build item list, we want *all* items */
   status = msLayerWhichItems(lp, MS_TRUE, NULL);
@@ -731,13 +737,18 @@ int msQueryByAttributes(mapObj *map)
 #endif
 
     addResult(lp->resultcache, &shape);
-    
     msFreeShape(&shape);
 
     if(map->query.mode == MS_QUERY_SINGLE) { /* no need to look any further */
       status = MS_DONE;
       break;
     }
+
+    /* check shape count */
+    if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+      status = MS_DONE;
+      break;
+    }
   }
 
   if (classgroup)
@@ -803,7 +814,7 @@ int msQueryByFilter(mapObj *map)
     /* conditions may have changed since this layer last drawn, so set 
        layer->project true to recheck projection needs (Bug #673) */ 
     lp->project = MS_TRUE; 
-
+    
     /* free any previous search results, do it now in case one of the next few tests fail */
     if(lp->resultcache) {
       if(lp->resultcache->results) free(lp->resultcache->results);
@@ -834,6 +845,8 @@ int msQueryByFilter(mapObj *map)
     msLayerClose(lp); /* reset */
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) goto query_error;
+    /* disable driver paging */
+    msLayerEnablePaging(lp, MS_FALSE);
 
     /* build item list, we want *all* items */
     status = msLayerWhichItems(lp, MS_TRUE, NULL);
@@ -912,6 +925,12 @@ int msQueryByFilter(mapObj *map)
 
       addResult(lp->resultcache, &shape);
       msFreeShape(&shape);
+
+      /* check shape count */
+      if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+        status = MS_DONE;
+        break;
+      }
     } /* next shape */
 
     if(classgroup) msFree(classgroup);
@@ -951,7 +970,8 @@ int msQueryByRect(mapObj *map)
   shapeObj shape, searchshape;
   rectObj searchrect;
   double layer_tolerance = 0, tolerance = 0;
-  
+
+  int paging;
   int nclasses = 0;
   int *classgroup = NULL;
   double minfeaturesize = -1;
@@ -1021,10 +1041,13 @@ int msQueryByRect(mapObj *map)
       continue;
     }
 
+    /* Paging could have been disabled before */ 
+    paging = msLayerGetPaging(lp);
     msLayerClose(lp); /* reset */
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) return(MS_FAILURE);
-
+    msLayerEnablePaging(lp, paging);
+    
     /* build item list, we want *all* items */
     status = msLayerWhichItems(lp, MS_TRUE, NULL);
     if(status != MS_SUCCESS) return(MS_FAILURE);
@@ -1108,8 +1131,13 @@ int msQueryByRect(mapObj *map)
 
       if(status == MS_TRUE)
 	addResult(lp->resultcache, &shape);
-
       msFreeShape(&shape);
+
+      /* check shape count */
+      if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+        status = MS_DONE;
+        break;
+      }
     } /* next shape */
       
     if (classgroup)
@@ -1231,6 +1259,7 @@ int msQueryByFeatures(mapObj *map)
     msLayerClose(lp); /* reset */
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) return(MS_FAILURE);
+    msLayerEnablePaging(lp, MS_FALSE);
     
     /* build item list, we want *all* items */
     status = msLayerWhichItems(lp, MS_TRUE, NULL);
@@ -1407,8 +1436,13 @@ int msQueryByFeatures(mapObj *map)
 
 	if(status == MS_TRUE)
 	  addResult(lp->resultcache, &shape);
-
 	msFreeShape(&shape);
+
+	/* check shape count */
+	if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+	  status = MS_DONE;
+	  break;
+	}
       } /* next shape */
 
       if (classgroup)
@@ -1456,6 +1490,7 @@ int msQueryByPoint(mapObj *map)
 
   layerObj *lp;
 
+  int paging;
   char status;
   rectObj rect, searchrect;
   shapeObj shape;
@@ -1481,7 +1516,7 @@ int msQueryByPoint(mapObj *map)
     /* conditions may have changed since this layer last drawn, so set 
        layer->project true to recheck projection needs (Bug #673) */ 
     lp->project = MS_TRUE; 
-
+    
     /* free any previous search results, do it now in case one of the next few tests fail */
     if(lp->resultcache) {
       if(lp->resultcache->results) free(lp->resultcache->results);
@@ -1532,10 +1567,13 @@ int msQueryByPoint(mapObj *map)
     rect.miny = map->query.point.y - t;
     rect.maxy = map->query.point.y + t;
 
+    /* Paging could have been disabled before */ 
+    paging = msLayerGetPaging(lp);    
     msLayerClose(lp); /* reset */
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) return(MS_FAILURE);
-
+    msLayerEnablePaging(lp, paging);
+    
     /* build item list, we want *all* items */
     status = msLayerWhichItems(lp, MS_TRUE, NULL);
     if(status != MS_SUCCESS) return(MS_FAILURE);
@@ -1618,6 +1656,12 @@ int msQueryByPoint(mapObj *map)
         status = MS_DONE;   /* got enough results for this layer */
         break;
       }
+
+      /* check shape count */
+      if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+        status = MS_DONE;
+        break;
+      }
     } /* next shape */
 
     if (classgroup)
@@ -1729,6 +1773,8 @@ int msQueryByShape(mapObj *map)
     msLayerClose(lp); /* reset */
     status = msLayerOpen(lp);
     if(status != MS_SUCCESS) return(MS_FAILURE);
+    /* disable driver paging */
+    msLayerEnablePaging(lp, MS_FALSE);        
 
     /* build item list, we want *all* items */
     status = msLayerWhichItems(lp, MS_TRUE, NULL);
@@ -1877,8 +1923,13 @@ int msQueryByShape(mapObj *map)
 
       if(status == MS_TRUE)
 	addResult(lp->resultcache, &shape);
-
       msFreeShape(&shape);
+
+      /* check shape count */
+      if(lp->maxfeatures > 0 && lp->maxfeatures == lp->resultcache->numresults) {
+        status = MS_DONE;
+        break;
+      }
     } /* next shape */
 
     if(status != MS_DONE) return(MS_FAILURE);
diff --git a/mapscript/swiginc/layer.i b/mapscript/swiginc/layer.i
index 772f633..0a945b0 100644
--- a/mapscript/swiginc/layer.i
+++ b/mapscript/swiginc/layer.i
@@ -313,6 +313,9 @@
         self->status = MS_ON;
         retval = msQueryByAttributes(map);
         self->status = status;
+        /* reset paginate property */
+        self->paginate = MS_FALSE;
+
         return retval;
     }
 
@@ -333,6 +336,9 @@
         self->status = MS_ON;
         retval = msQueryByPoint(map);
         self->status = status;
+        /* reset paginate property */
+        self->paginate = MS_FALSE;
+
         return retval;
     }
 
@@ -352,6 +358,9 @@
         self->status = MS_ON;
         retval = msQueryByRect(map);
         self->status = status;
+        /* reset paginate property */
+        self->paginate = MS_FALSE;
+
         return retval;
     }
 
diff --git a/mapserver.h b/mapserver.h
index 82e2988..0d24a85 100644
--- a/mapserver.h
+++ b/mapserver.h
@@ -1505,14 +1505,14 @@ typedef struct layer_obj {
   double mingeowidth, maxgeowidth; /* map width (in map units) at which the layer should be drawn */
 
   int sizeunits; /* applies to all classes */
-
+  
   int maxfeatures;      
   int startindex;
-
+  
   colorObj offsite; /* transparent pixel value for raster images */
-
+  
   int transform; /* does this layer have to be transformed to file coordinates */
-
+  
   int labelcache, postlabelcache; /* on or off */
 
   char *labelitem;
@@ -1737,7 +1737,7 @@ typedef struct map_obj{ /* structure for a map */
 /************************************************************************/
 #ifndef SWIG
 struct layerVTable {
-  int (*LayerSupportsCommonFilters)(layerObj *layer);
+  int (*LayerSupportsCommonFilters)(layerObj *layer);  
   int (*LayerInitItemInfo)(layerObj *layer);
   void (*LayerFreeItemInfo)(layerObj *layer);
   int (*LayerOpen)(layerObj *layer);
@@ -1757,6 +1757,8 @@ struct layerVTable {
   int (*LayerGetAutoProjection)(layerObj *layer, projectionObj *projection);
   char* (*LayerEscapeSQLParam)(layerObj *layer, const char* pszString);
   char* (*LayerEscapePropertyName)(layerObj *layer, const char* pszString);
+  void (*LayerEnablePaging)(layerObj *layer, int value);
+  int (*LayerGetPaging)(layerObj *layer);    
 };
 #endif /*SWIG*/
 
@@ -2199,6 +2201,9 @@ MS_DLL_EXPORT int msLayerGetNumFeatures(layerObj *layer);
 
 MS_DLL_EXPORT int msLayerSupportsPaging(layerObj *layer);
 
+MS_DLL_EXPORT void msLayerEnablePaging(layerObj *layer, int value);
+MS_DLL_EXPORT int msLayerGetPaging(layerObj *layer);
+
 MS_DLL_EXPORT int msLayerGetMaxFeaturesToDraw(layerObj *layer, outputFormatObj *format);
 
 MS_DLL_EXPORT char *msLayerEscapeSQLParam(layerObj *layer, const char* pszString);
diff --git a/mapshape.c b/mapshape.c
index 6924a36..c529a80 100644
--- a/mapshape.c
+++ b/mapshape.c
@@ -2554,19 +2554,6 @@ int msSHPLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery)
     return status;
   }
 
-  /* now apply the maxshapes criteria (NOTE: this ignores the filter so you could get less than maxfeatures) */
-  if(layer->maxfeatures > 0) {
-
-    for( i = (shpfile->numshapes - 1); i >= 0; i-- ) {
-      n2 = msGetBit(shpfile->status, i);
-      n1 += n2;
-      if( n2 && n1 > layer->maxfeatures ) {
-        msSetBit(shpfile->status, i, 0);
-      }
-    }
-
-  }
-    
   return MS_SUCCESS;
 }
 
diff --git a/mapwfs.c b/mapwfs.c
index 754af36..e298d36 100644
--- a/mapwfs.c
+++ b/mapwfs.c
@@ -2071,8 +2071,8 @@ int msWFSGetFeature(mapObj *map, wfsParamsObj *paramsObj, cgiRequestObj *req, ow
     startindex = paramsObj->nStartIndex;
 
 
-  /*maxfeatures set but no startindex*/
-  if (maxfeatures > 0 && startindex < 0)
+  /* maxfeatures set */
+  if (maxfeatures > 0)
   {
       for(j=0; j<map->numlayers; j++) 
       {
@@ -2088,32 +2088,12 @@ int msWFSGetFeature(mapObj *map, wfsParamsObj *paramsObj, cgiRequestObj *req, ow
       }
   }
   
-  /*no maxfeatures set but startindex set*/
-  if (maxfeatures <=0 && startindex > 0)
+  /* startindex set */
+  if (startindex > 0 &&
+      (nQueriedLayers == 1 && msLayerSupportsPaging(lpQueried)))
   {
-      if (nQueriedLayers == 1 && msLayerSupportsPaging(lpQueried))
-      {
-          lpQueried->startindex = startindex;
-          startindex = -1;
-      }
-  }
-
-  /*maxfeatures set and startindex set*/
-  if (maxfeatures >0 && startindex > 0)
-  {
-      if (nQueriedLayers == 1 && msLayerSupportsPaging(lpQueried))
-      {
           lpQueried->startindex = startindex;
-          if (lpQueried->maxfeatures <=0 || 
-              (lpQueried->maxfeatures > 0 && maxfeatures < lpQueried->maxfeatures))
-            lpQueried->maxfeatures = maxfeatures;
-          
-          startindex = -1;
-          maxfeatures = -1;
-      }
   }
-
-
   
   if (paramsObj->pszFilter) {
     bFilterSet = 1;
@@ -2235,21 +2215,13 @@ int msWFSGetFeature(mapObj *map, wfsParamsObj *paramsObj, cgiRequestObj *req, ow
 	  return msWFSException(map, "typename", "InvalidParameterValue", paramsObj->pszVersion);
 	}
 	psNode = FLTParseFilterEncoding(paszFilter[i]);
-	
-        /*if we have a complex filter, make sure that paging is done at the gml output level
-          and not at the driver level #3305*/
-        bComplexFilter = (!FLTIsSimpleFilter(psNode));
-        if (bComplexFilter && nQueriedLayers == 1 && lpQueried &&
-            msLayerSupportsPaging(lpQueried) && 
-            (lpQueried->startindex > 0 && lpQueried->maxfeatures > 0))
-        {
-            startindex = lpQueried->startindex;
-            lpQueried->startindex = -1;
 
-            maxfeatures = lpQueried->maxfeatures;
-            lpQueried->maxfeatures = -1;
+        /* Not querying a single layer? no driver pagination */
+        if (lpQueried && (nQueriedLayers > 1))
+        {
+          msLayerEnablePaging(lpQueried, MS_FALSE);
         }
-
+        
 	if (!psNode) {
 	  msSetError(MS_WFSERR, 
 		     "Invalid or Unsupported FILTER in GetFeature : %s", 
