public void findIntersections(Rectangle query, Consumer<T> consumer)
    {
        IntArrayList todoNodes = new IntArrayList(levelOffsets.length * degree);
        IntArrayList todoLevels = new IntArrayList(levelOffsets.length * degree);

        int rootLevel = levelOffsets.length - 1;
        int rootIndex = levelOffsets[rootLevel];
        if (doesIntersect(query, rootIndex)) {
            todoNodes.push(rootIndex);
            todoLevels.push(rootLevel);
        }

        while (!todoNodes.isEmpty()) {
            int nodeIndex = todoNodes.popInt();
            int level = todoLevels.popInt();

            if (level == 0) {
                // This is a leaf node
                consumer.accept(items[nodeIndex / ENVELOPE_SIZE]);
            }
            else {
                int childrenOffset = getChildrenOffset(nodeIndex, level);
                for (int i = 0; i < degree; i++) {
                    int childIndex = childrenOffset + ENVELOPE_SIZE * i;
                    if (doesIntersect(query, childIndex)) {
                        todoNodes.push(childIndex);
                        todoLevels.push(level - 1);
                    }
                }
            }
        }
    }
@Test
    public void testOctagonTree()
    {
        OGCGeometryWrapper octagonA = new OGCGeometryWrapper(POLYGON_A);
        OGCGeometryWrapper octagonB = new OGCGeometryWrapper(POLYGON_B);

        OGCGeometryWrapper pointX = new OGCGeometryWrapper(POINT_X);
        OGCGeometryWrapper pointY = new OGCGeometryWrapper(POINT_Y);
        OGCGeometryWrapper pointZ = new OGCGeometryWrapper(POINT_Z);
        OGCGeometryWrapper pointW = new OGCGeometryWrapper(POINT_W);

        Flatbush<OGCGeometryWrapper> rtree = new Flatbush<>(new OGCGeometryWrapper[] {octagonA, octagonB});

        assertEquals(findIntersections(rtree, pointX.getExtent()), ImmutableList.of(octagonA));

        List<OGCGeometryWrapper> results = findIntersections(rtree, pointY.getExtent());
        assertEqualsSorted(results, ImmutableList.of(octagonA, octagonB), Comparator.naturalOrder());

        assertEquals(findIntersections(rtree, pointZ.getExtent()), ImmutableList.of(octagonB));

        assertEquals(findIntersections(rtree, pointW.getExtent()), ImmutableList.of());
    }