// Path: src/main/java/com/github/davidmoten/rtree/Context.java
// public final class Context<T, S extends Geometry> {
// 
//     private final int maxChildren;
//     private final int minChildren;
//     private final Splitter splitter;
//     private final Selector selector;
//     private final Factory<T, S> factory;
// 
//     /**
//      * Constructor.
//      * 
//      * @param minChildren
//      *            minimum number of children per node (at least 1)
//      * @param maxChildren
//      *            max number of children per node (minimum is 3)
//      * @param selector
//      *            algorithm to select search path
//      * @param splitter
//      *            algorithm to split the children across two new nodes
//      * @param factory
//      *            node creation factory
//      */
//     public Context(int minChildren, int maxChildren, Selector selector, Splitter splitter,
//             Factory<T, S> factory) {
//         Preconditions.checkNotNull(splitter);
//         Preconditions.checkNotNull(selector);
//         Preconditions.checkArgument(maxChildren > 2);
//         Preconditions.checkArgument(minChildren >= 1);
//         Preconditions.checkArgument(minChildren < maxChildren);
//         Preconditions.checkNotNull(factory);
//         this.selector = selector;
//         this.maxChildren = maxChildren;
//         this.minChildren = minChildren;
//         this.splitter = splitter;
//         this.factory = factory;
//     }
// 
//     public int maxChildren() {
//         return maxChildren;
//     }
// 
//     public int minChildren() {
//         return minChildren;
//     }
// 
//     public Splitter splitter() {
//         return splitter;
//     }
// 
//     public Selector selector() {
//         return selector;
//     }
// 
//     public Factory<T, S> factory() {
//         return factory;
//     }
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/Entry.java
// public interface Entry<T, S extends Geometry> extends HasGeometry {
// 
//     T value();
// 
//     @Override
//     S geometry();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/Node.java
// public interface Node<T, S extends Geometry> extends HasGeometry {
// 
//     List<Node<T, S>> add(Entry<? extends T, ? extends S> entry);
// 
//     NodeAndEntries<T, S> delete(Entry<? extends T, ? extends S> entry, boolean all);
// 
//     /**
//      * Run when a search requests Long.MAX_VALUE results. This is the
//      * no-backpressure fast path.
//      * 
//      * @param criterion
//      *            function that returns true if the geometry is a search match
//      * @param subscriber
//      *            the subscriber to report search findings to
//      */
//     void searchWithoutBackpressure(Func1<? super Geometry, Boolean> criterion,
//             Subscriber<? super Entry<T, S>> subscriber);
// 
//     int count();
// 
//     Context<T, S> context();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/NonLeaf.java
// public interface NonLeaf<T, S extends Geometry> extends Node<T, S> {
// 
//     Node<T, S> child(int i);
// 
//     /**
//      * Returns a list of children nodes. For accessing individual children the
//      * child(int) method should be used to ensure good performance. To avoid
//      * copying an existing list though this method can be used.
//      * 
//      * @return list of children nodes
//      */
//     List<Node<T, S>> children();
// 
// }
// 
// 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();
// 
// }


import java.util.List;
import com.github.davidmoten.guavamini.Preconditions;
import com.github.davidmoten.rtree.Context;
import com.github.davidmoten.rtree.Entry;
import com.github.davidmoten.rtree.Node;
import com.github.davidmoten.rtree.NonLeaf;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import rx.Subscriber;
import rx.functions.Func1;
package com.github.davidmoten.rtree.internal;




public final class NonLeafDefault<T, S extends Geometry> implements NonLeaf<T, S> {

    private final List<? extends Node<T, S>> children;
    private final Rectangle mbr;
    private final Context<T, S> context;

    public NonLeafDefault(List<? extends Node<T, S>> children, Context<T, S> context) {
        Preconditions.checkArgument(!children.isEmpty());
// Path: src/main/java/com/github/davidmoten/rtree/Context.java
// public final class Context<T, S extends Geometry> {
// 
//     private final int maxChildren;
//     private final int minChildren;
//     private final Splitter splitter;
//     private final Selector selector;
//     private final Factory<T, S> factory;
// 
//     /**
//      * Constructor.
//      * 
//      * @param minChildren
//      *            minimum number of children per node (at least 1)
//      * @param maxChildren
//      *            max number of children per node (minimum is 3)
//      * @param selector
//      *            algorithm to select search path
//      * @param splitter
//      *            algorithm to split the children across two new nodes
//      * @param factory
//      *            node creation factory
//      */
//     public Context(int minChildren, int maxChildren, Selector selector, Splitter splitter,
//             Factory<T, S> factory) {
//         Preconditions.checkNotNull(splitter);
//         Preconditions.checkNotNull(selector);
//         Preconditions.checkArgument(maxChildren > 2);
//         Preconditions.checkArgument(minChildren >= 1);
//         Preconditions.checkArgument(minChildren < maxChildren);
//         Preconditions.checkNotNull(factory);
//         this.selector = selector;
//         this.maxChildren = maxChildren;
//         this.minChildren = minChildren;
//         this.splitter = splitter;
//         this.factory = factory;
//     }
// 
//     public int maxChildren() {
//         return maxChildren;
//     }
// 
//     public int minChildren() {
//         return minChildren;
//     }
// 
//     public Splitter splitter() {
//         return splitter;
//     }
// 
//     public Selector selector() {
//         return selector;
//     }
// 
//     public Factory<T, S> factory() {
//         return factory;
//     }
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/Entry.java
// public interface Entry<T, S extends Geometry> extends HasGeometry {
// 
//     T value();
// 
//     @Override
//     S geometry();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/Node.java
// public interface Node<T, S extends Geometry> extends HasGeometry {
// 
//     List<Node<T, S>> add(Entry<? extends T, ? extends S> entry);
// 
//     NodeAndEntries<T, S> delete(Entry<? extends T, ? extends S> entry, boolean all);
// 
//     /**
//      * Run when a search requests Long.MAX_VALUE results. This is the
//      * no-backpressure fast path.
//      * 
//      * @param criterion
//      *            function that returns true if the geometry is a search match
//      * @param subscriber
//      *            the subscriber to report search findings to
//      */
//     void searchWithoutBackpressure(Func1<? super Geometry, Boolean> criterion,
//             Subscriber<? super Entry<T, S>> subscriber);
// 
//     int count();
// 
//     Context<T, S> context();
// 
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/NonLeaf.java
// public interface NonLeaf<T, S extends Geometry> extends Node<T, S> {
// 
//     Node<T, S> child(int i);
// 
//     /**
//      * Returns a list of children nodes. For accessing individual children the
//      * child(int) method should be used to ensure good performance. To avoid
//      * copying an existing list though this method can be used.
//      * 
//      * @return list of children nodes
//      */
//     List<Node<T, S>> children();
// 
// }
// 
// 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/NonLeafDefault.java
import java.util.List;
import com.github.davidmoten.guavamini.Preconditions;
import com.github.davidmoten.rtree.Context;
import com.github.davidmoten.rtree.Entry;
import com.github.davidmoten.rtree.Node;
import com.github.davidmoten.rtree.NonLeaf;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import rx.Subscriber;
import rx.functions.Func1;

package com.github.davidmoten.rtree.internal;




public final class NonLeafDefault<T, S extends Geometry> implements NonLeaf<T, S> {

    private final List<? extends Node<T, S>> children;
    private final Rectangle mbr;
    private final Context<T, S> context;

    public NonLeafDefault(List<? extends Node<T, S>> children, Context<T, S> context) {
        Preconditions.checkArgument(!children.isEmpty());
        this.context = context;