internal static int traverseForward(StorageImpl db, int pageId, ClassDescriptor.FieldType type, int height, object[] result, int pos)
 {
     Page pg = db.getPage(pageId);
     int oid;
     try
     {
         int i, n = getnItems(pg);
         if (--height != 0)
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i <= n; i++)
                 {
                     pos = traverseForward(db, getKeyStrOid(pg, i), type, height, result, pos);
                 }
             }
             else
             {
                 for (i = 0; i <= n; i++)
                 {
                     pos = traverseForward(db, getReference(pg, maxItems - i - 1), type, height, result, pos);
                 }
             }
         }
         else
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i < n; i++)
                 {
                     oid = getKeyStrOid(pg, i);
                     result[pos++] = db.lookupObject(oid, null);
                 }
             }
             else
             {
                 // page of scalars
                 for (i = 0; i < n; i++)
                 {
                     oid = getReference(pg, maxItems - 1 - i);
                     result[pos++] = db.lookupObject(oid, null);
                 }
             }
         }
         return pos;
     }
     finally
     {
         db.pool.unfix(pg);
     }
 }
 internal static bool prefixSearch(StorageImpl db, int pageId, string key,
                                   int height, ArrayList result)
 {
     Page pg = db.getPage(pageId);
     int l = 0, n = getnItems(pg), r = n;
     int oid;
     height -= 1;
     try 
     { 
         while (l < r)  
         {
             int i = (l+r) >> 1;
             if (comparePrefix(key, pg, i) > 0) 
             {
                 l = i + 1; 
             } 
             else 
             { 
                 r = i;
             }
         }
         Debug.Assert(r == l); 
         if (height == 0) 
         { 
             while (l < n) 
             { 
                 if (comparePrefix(key, pg, l) < 0) 
                 { 
                     return false;
                 }
                 oid = getKeyStrOid(pg, l);
                 result.Add(db.lookupObject(oid, null));
                 l += 1;
             }
         } 
         else 
         { 
             do 
             {
                 if (!prefixSearch(db, getKeyStrOid(pg, l), key, height, result)) 
                 {
                     return false;
                 }
                 if (l == n) 
                 { 
                     return true;
                 }
             } while (comparePrefix(key, pg, l++) >= 0);
             return false;
         }
     } 
     finally 
     { 
         db.pool.unfix(pg);
     }
     return true;
 }    
 internal static bool find(StorageImpl db, int pageId, Key firstKey, Key lastKey, Btree tree, int height, ArrayList result)
 {
     Page pg = db.getPage(pageId);
     int l = 0, n = getnItems(pg), r = n;
     int oid;
     height -= 1;
     try
     {
         if (tree.FieldType == ClassDescriptor.FieldType.tpString)
         {
             if (firstKey != null)
             {
                 while (l < r)
                 {
                     int i = (l + r) >> 1;
                     if (compareStr(firstKey, pg, i) >= firstKey.inclusion)
                     {
                         l = i + 1;
                     }
                     else
                     {
                         r = i;
                     }
                 }
                 Debug.Assert(r == l);
             }
             if (lastKey != null)
             {
                 if (height == 0)
                 {
                     while (l < n)
                     {
                         if (- compareStr(lastKey, pg, l) >= lastKey.inclusion)
                         {
                             return false;
                         }
                         oid = getKeyStrOid(pg, l);
                         result.Add(db.lookupObject(oid, null));
                         l += 1;
                     }
                 }
                 else
                 {
                     do 
                     {
                         if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                         {
                             return false;
                         }
                         if (l == n)
                         {
                             return true;
                         }
                     }
                     while (compareStr(lastKey, pg, l++) >= 0);
                     return false;
                 }
             }
             else
             {
                 if (height == 0)
                 {
                     while (l < n)
                     {
                         oid = getKeyStrOid(pg, l);
                         result.Add(db.lookupObject(oid, null));
                         l += 1;
                     }
                 }
                 else
                 {
                     do 
                     {
                         if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                         {
                             return false;
                         }
                     }
                     while (++l <= n);
                 }
             }
         }
         else if (tree.FieldType == ClassDescriptor.FieldType.tpArrayOfByte)
         {
             if (firstKey != null)
             {
                 while (l < r)
                 {
                     int i = (l + r) >> 1;
                     if (tree.compareByteArrays(firstKey, pg, i) >= firstKey.inclusion)
                     {
                         l = i + 1;
                     }
                     else
                     {
                         r = i;
                     }
                 }
                 Debug.Assert(r == l);
             }
             if (lastKey != null)
             {
                 if (height == 0)
                 {
                     while (l < n)
                     {
                         if (-tree.compareByteArrays(lastKey, pg, l) >= lastKey.inclusion)
                         {
                             return false;
                         }
                         oid = getKeyStrOid(pg, l);
                         result.Add(db.lookupObject(oid, null));
                         l += 1;
                     }
                 }
                 else
                 {
                     do 
                     {
                         if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                         {
                             return false;
                         }
                         if (l == n)
                         {
                             return true;
                         }
                     }
                     while (tree.compareByteArrays(lastKey, pg, l++) >= 0);
                     return false;
                 }
             }
             else
             {
                 if (height == 0)
                 {
                     while (l < n)
                     {
                         oid = getKeyStrOid(pg, l);
                         result.Add(db.lookupObject(oid, null));
                         l += 1;
                     }
                 }
                 else
                 {
                     do 
                     {
                         if (!find(db, getKeyStrOid(pg, l), firstKey, lastKey, tree, height, result))
                         {
                             return false;
                         }
                     }
                     while (++l <= n);
                 }
             }
         }
         else
         {
             if (firstKey != null)
             {
                 while (l < r)
                 {
                     int i = (l + r) >> 1;
                     if (compare(firstKey, pg, i) >= firstKey.inclusion)
                     {
                         l = i + 1;
                     }
                     else
                     {
                         r = i;
                     }
                 }
                 Debug.Assert(r == l);
             }
             if (lastKey != null)
             {
                 if (height == 0)
                 {
                     while (l < n)
                     {
                         if (- compare(lastKey, pg, l) >= lastKey.inclusion)
                         {
                             return false;
                         }
                         oid = getReference(pg, maxItems - 1 - l);
                         result.Add(db.lookupObject(oid, null));
                         l += 1;
                     }
                     return true;
                 }
                 else
                 {
                     do 
                     {
                         if (!find(db, getReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result))
                         {
                             return false;
                         }
                         if (l == n)
                         {
                             return true;
                         }
                     }
                     while (compare(lastKey, pg, l++) >= 0);
                     return false;
                 }
             }
             if (height == 0)
             {
                 while (l < n)
                 {
                     oid = getReference(pg, maxItems - 1 - l);
                     result.Add(db.lookupObject(oid, null));
                     l += 1;
                 }
             }
             else
             {
                 do 
                 {
                     if (!find(db, getReference(pg, maxItems - 1 - l), firstKey, lastKey, tree, height, result))
                     {
                         return false;
                     }
                 }
                 while (++l <= n);
             }
         }
     }
     finally
     {
         db.pool.unfix(pg);
     }
     return true;
 }