// Path: src/test/java/com/github/davidmoten/rtree/RTreeTest.java
// static Entry<Object, Rectangle> e(int n) {
//     return Entries.<Object, Rectangle>entry(n, r(n));
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/Geometry.java
// public interface Geometry {
// 
//     /**
//      * <p>
//      * Returns the distance to the given {@link Rectangle}. For a {@link Rectangle}
//      * this might be Euclidean distance but for an EPSG4326 lat-long Rectangle might
//      * be great-circle distance. The distance function should satisfy the following
//      * properties:
//      * </p>
//      * 
//      * <p>
//      * <code>distance(r) &gt;= 0</code>
//      * </p>
//      * 
//      * <p>
//      * <code>if r1 contains r2 then distance(r1)&lt;=distance(r2)</code>
//      * </p>
//      * 
//      * 
//      * @param r
//      *            rectangle to measure distance to
//      * @return distance to the rectangle r from the geometry
//      */
//     double distance(Rectangle r);
// 
//     /**
//      * Returns the minimum bounding rectangle of this geometry.
//      * 
//      * @return minimum bounding rectangle
//      */
//     Rectangle mbr();
// 
//     boolean intersects(Rectangle r);
// 
//     boolean isDoublePrecision();
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/Rectangle.java
// public interface Rectangle extends Geometry, HasGeometry {
// 
//     double x1();
// 
//     double y1();
// 
//     double x2();
// 
//     double y2();
// 
//     double area();
// 
//     double intersectionArea(Rectangle r);
// 
//     double perimeter();
// 
//     Rectangle add(Rectangle r);
// 
//     boolean contains(double x, double y);
//     
//     boolean isDoublePrecision();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/internal/util/ImmutableStack.java
// public final class ImmutableStack<T> implements Iterable<T> {
//     private final Optional<T> head;
//     private final Optional<ImmutableStack<T>> tail;
// 
//     private static ImmutableStack<?> EMPTY = new ImmutableStack<>();
// 
//     public ImmutableStack(final T head, final ImmutableStack<T> tail) {
//         this(of(head), of(tail));
//     }
// 
//     private ImmutableStack(Optional<T> head, Optional<ImmutableStack<T>> tail) {
//         this.head = head;
//         this.tail = tail;
//     }
// 
//     public static <T> ImmutableStack<T> create(T t) {
//         return new ImmutableStack<>(of(t), of(ImmutableStack.empty()));
//     }
// 
//     public ImmutableStack() {
//         this(Optional.empty(), Optional.empty());
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <S> ImmutableStack<S> empty() {
//         return (ImmutableStack<S>) EMPTY;
//     }
// 
//     public boolean isEmpty() {
//         return !head.isPresent();
//     }
// 
//     public T peek() {
//         // if (isEmpty())
//         // throw new RuntimeException("cannot peek on empty stack");
//         // else
//         return this.head.get();
//     }
// 
//     public ImmutableStack<T> pop() {
//         // if (isEmpty())
//         // throw new RuntimeException("cannot pop on empty stack");
//         // else
//         return this.tail.get();
//     }
// 
//     public ImmutableStack<T> push(T value) {
//         return new ImmutableStack<T>(value, this);
//     }
// 
//     @Override
//     public Iterator<T> iterator() {
//         return new StackIterator<T>(this);
//     }
// 
//     private static class StackIterator<U> implements Iterator<U> {
//         private ImmutableStack<U> stack;
// 
//         public StackIterator(final ImmutableStack<U> stack) {
//             this.stack = stack;
//         }
// 
//         @Override
//         public boolean hasNext() {
//             return !this.stack.isEmpty();
//         }
// 
//         @Override
//         public U next() {
//             final U result = this.stack.peek();
//             this.stack = this.stack.pop();
//             return result;
//         }
// 
//         @Override
//         public void remove() {
//             throw new RuntimeException("not supported");
//         }
//     }
// 
// }


import static com.github.davidmoten.rtree.RTreeTest.e;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.mockito.Mockito;
import com.github.davidmoten.junit.Asserts;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import com.github.davidmoten.rtree.internal.util.ImmutableStack;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Func1;
                .add(e(1)).add(e(3)).add(e(5)).add(e(7));

        Set<Entry<Object, Rectangle>> found = new HashSet<Entry<Object, Rectangle>>();
        tree.search(e(1).geometry()).subscribe(backpressureSubscriber(found));
        assertEquals(1, found.size());
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testRequestZero() {
        Subscriber<Object> sub = new Subscriber<Object>() {

            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(Object t) {

            }
        };
        sub.add(new Subscription() {
            volatile boolean subscribed = true;

            @Override
            public void unsubscribe() {
// Path: src/test/java/com/github/davidmoten/rtree/RTreeTest.java
// static Entry<Object, Rectangle> e(int n) {
//     return Entries.<Object, Rectangle>entry(n, r(n));
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/Geometry.java
// public interface Geometry {
// 
//     /**
//      * <p>
//      * Returns the distance to the given {@link Rectangle}. For a {@link Rectangle}
//      * this might be Euclidean distance but for an EPSG4326 lat-long Rectangle might
//      * be great-circle distance. The distance function should satisfy the following
//      * properties:
//      * </p>
//      * 
//      * <p>
//      * <code>distance(r) &gt;= 0</code>
//      * </p>
//      * 
//      * <p>
//      * <code>if r1 contains r2 then distance(r1)&lt;=distance(r2)</code>
//      * </p>
//      * 
//      * 
//      * @param r
//      *            rectangle to measure distance to
//      * @return distance to the rectangle r from the geometry
//      */
//     double distance(Rectangle r);
// 
//     /**
//      * Returns the minimum bounding rectangle of this geometry.
//      * 
//      * @return minimum bounding rectangle
//      */
//     Rectangle mbr();
// 
//     boolean intersects(Rectangle r);
// 
//     boolean isDoublePrecision();
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/Rectangle.java
// public interface Rectangle extends Geometry, HasGeometry {
// 
//     double x1();
// 
//     double y1();
// 
//     double x2();
// 
//     double y2();
// 
//     double area();
// 
//     double intersectionArea(Rectangle r);
// 
//     double perimeter();
// 
//     Rectangle add(Rectangle r);
// 
//     boolean contains(double x, double y);
//     
//     boolean isDoublePrecision();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/internal/util/ImmutableStack.java
// public final class ImmutableStack<T> implements Iterable<T> {
//     private final Optional<T> head;
//     private final Optional<ImmutableStack<T>> tail;
// 
//     private static ImmutableStack<?> EMPTY = new ImmutableStack<>();
// 
//     public ImmutableStack(final T head, final ImmutableStack<T> tail) {
//         this(of(head), of(tail));
//     }
// 
//     private ImmutableStack(Optional<T> head, Optional<ImmutableStack<T>> tail) {
//         this.head = head;
//         this.tail = tail;
//     }
// 
//     public static <T> ImmutableStack<T> create(T t) {
//         return new ImmutableStack<>(of(t), of(ImmutableStack.empty()));
//     }
// 
//     public ImmutableStack() {
//         this(Optional.empty(), Optional.empty());
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <S> ImmutableStack<S> empty() {
//         return (ImmutableStack<S>) EMPTY;
//     }
// 
//     public boolean isEmpty() {
//         return !head.isPresent();
//     }
// 
//     public T peek() {
//         // if (isEmpty())
//         // throw new RuntimeException("cannot peek on empty stack");
//         // else
//         return this.head.get();
//     }
// 
//     public ImmutableStack<T> pop() {
//         // if (isEmpty())
//         // throw new RuntimeException("cannot pop on empty stack");
//         // else
//         return this.tail.get();
//     }
// 
//     public ImmutableStack<T> push(T value) {
//         return new ImmutableStack<T>(value, this);
//     }
// 
//     @Override
//     public Iterator<T> iterator() {
//         return new StackIterator<T>(this);
//     }
// 
//     private static class StackIterator<U> implements Iterator<U> {
//         private ImmutableStack<U> stack;
// 
//         public StackIterator(final ImmutableStack<U> stack) {
//             this.stack = stack;
//         }
// 
//         @Override
//         public boolean hasNext() {
//             return !this.stack.isEmpty();
//         }
// 
//         @Override
//         public U next() {
//             final U result = this.stack.peek();
//             this.stack = this.stack.pop();
//             return result;
//         }
// 
//         @Override
//         public void remove() {
//             throw new RuntimeException("not supported");
//         }
//     }
// 
// }


// Path: src/test/java/com/github/davidmoten/rtree/BackpressureTest.java
import static com.github.davidmoten.rtree.RTreeTest.e;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.mockito.Mockito;
import com.github.davidmoten.junit.Asserts;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import com.github.davidmoten.rtree.internal.util.ImmutableStack;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Func1;

                .add(e(1)).add(e(3)).add(e(5)).add(e(7));

        Set<Entry<Object, Rectangle>> found = new HashSet<Entry<Object, Rectangle>>();
        tree.search(e(1).geometry()).subscribe(backpressureSubscriber(found));
        assertEquals(1, found.size());
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testRequestZero() {
        Subscriber<Object> sub = new Subscriber<Object>() {

            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(Object t) {

            }
        };
        sub.add(new Subscription() {
            volatile boolean subscribed = true;

            @Override
            public void unsubscribe() {
                subscribed = false;