Index: maptree.c
===================================================================
--- maptree.c	(revision 7526)
+++ maptree.c	(working copy)
@@ -768,10 +768,14 @@
   int i;
   rectObj shape_rect;
 
-  for(i=0;i<shp->numshapes;i++) { /* for each shape */
-    if(msGetBit(status, i)) {
-      if(msSHPReadBounds(shp->hSHP, i, &shape_rect) == MS_SUCCESS)
-	if(msRectOverlap(&shape_rect, &search_rect) != MS_TRUE) msSetBit(status, i, 0);
+  i = msGetNextBit(status, 0, shp->numshapes);
+  while(i >= 0) {
+    if(msSHPReadBounds(shp->hSHP, i, &shape_rect) == MS_SUCCESS) {
+	    if(msRectOverlap(&shape_rect, &search_rect) != MS_TRUE) {
+	      msSetBit(status, i, 0);
+      }
     }
+    i = msGetNextBit(status, i+1, shp->numshapes);
   }
+
 }
Index: mapserver.h
===================================================================
--- mapserver.h	(revision 7526)
+++ mapserver.h	(working copy)
@@ -1722,6 +1722,7 @@
 MS_DLL_EXPORT int msGetBit(char *array, int index);
 MS_DLL_EXPORT void msSetBit(char *array, int index, int value);
 MS_DLL_EXPORT void msFlipBit(char *array, int index);
+MS_DLL_EXPORT int msGetNextBit(char *array, int index, int size);
 
 MS_DLL_EXPORT int msLayerInitItemInfo(layerObj *layer);
 MS_DLL_EXPORT void msLayerFreeItemInfo(layerObj *layer); 
Index: mapbits.c
===================================================================
--- mapbits.c	(revision 7526)
+++ mapbits.c	(working copy)
@@ -53,6 +53,47 @@
   return (*array & (1 << (index % CHAR_BIT))) != 0;    /* 0 or 1 */
 }
 
+/*
+** msGetNextBit( status, start, size)
+**
+** Quickly find the next bit set. If start == 0 and 0 is set, will return 0.
+** If hits end of bitmap without finding set bit, will return -1.
+**
+*/
+int msGetNextBit(char *array, int index, int size) { 
+  char *ptr;
+  ptr = array;
+  int i = 0;
+  
+  ptr += index / CHAR_BIT;
+  
+  /* Check the starting byte for set bits, if necessary. */
+  if(*ptr & (0xff << (index % CHAR_BIT))) {
+    /* a bit in this byte is set, figure out which one */
+    for( i = index; i < index + CHAR_BIT - (index % CHAR_BIT); i++ ) {
+      if ( msGetBit( array, i ) )
+        return i;
+    }
+  }
+
+  /* scroll forwards bytewise to the next byte with a bit set */
+  do {
+    ptr++;
+  } while( ((CHAR_BIT * (ptr - array)) < size) && *ptr == 0 ) ;
+
+  /* check the first non-zero byte for the location of the set bit */
+  if( *ptr ) {
+    /* a bit in this byte is set, figure out which one */
+    for( i = CHAR_BIT * (ptr - array); i < CHAR_BIT * (ptr - array) + CHAR_BIT; i++ ) {
+      if ( msGetBit( array, i ) )
+        return i;
+    }
+  }
+  
+  /* got to the last byte with no hits! */
+  return -1;
+}
+
 void msSetBit(char *array, int index, int value)
 {
   array += index / CHAR_BIT;
Index: mapshape.c
===================================================================
--- mapshape.c	(revision 7526)
+++ mapshape.c	(working copy)
@@ -1632,8 +1632,9 @@
     shpfile->status = msSearchDiskTree(filename, rect, debug);
     free(filename);
 
-    if(shpfile->status) /* index  */
+    if(shpfile->status) { /* index  */
       msFilterTreeSearch(shpfile, shpfile->status, rect);
+    }
     else { /* no index  */
       shpfile->status = msAllocBitArray(shpfile->numshapes);
       if(!shpfile->status) {
@@ -2303,18 +2304,15 @@
 
   /* now apply the maxshapes criteria (NOTE: this ignores the filter so you could get less than maxfeatures) */
   if(layer->maxfeatures > 0) {
-    for(i=0; i<shpfile->numshapes; i++) {
-      n1 += msGetBit(shpfile->status,i);
-    }
 
-    if(n1 > layer->maxfeatures) {
-      for(i=0; i<shpfile->numshapes; i++) {
-        if(msGetBit(shpfile->status,i) && (n2 < (n1 - layer->maxfeatures))) {
-          msSetBit(shpfile->status,i,0);
-          n2++;
-        }
+    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;
@@ -2331,14 +2329,14 @@
   if(!shpfile) {
     msSetError(MS_SHPERR, "Shapefile layer has not been opened.", "msLayerNextShape()");
     return MS_FAILURE;
-  }
-
+  }    
+  
   do {
-    i = shpfile->lastshape + 1;
-    while(i<shpfile->numshapes && !msGetBit(shpfile->status,i)) i++; /* next "in" shape */
+    i = msGetNextBit(shpfile->status, shpfile->lastshape + 1, shpfile->numshapes);
+
     shpfile->lastshape = i;
 
-    if(i == shpfile->numshapes) return(MS_DONE); /* nothing else to read */
+    if(i == -1) return(MS_DONE); /* nothing else to read */
 
     filter_passed = MS_TRUE;  /* By default accept ANY shape */
     if(layer->numitems > 0 && layer->iteminfo) {

