static boolean 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.type == ClassDescriptor.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;
                        }
                    }
                    Assert.that(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.type == ClassDescriptor.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;
                        }
                    }
                    Assert.that(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;
                        }
                    }
                    Assert.that(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;
    }