// Path: src/main/java/com/github/davidmoten/rtree3d/geometry/Geometry.java
// public interface Geometry {
// 
//     /**
//      * <p>
//      * Returns the distance to the given {@link Box}. For a
//      * {@link Box} 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(Box r);
// 
//     /**
//      * Returns the minimum bounding rectangle of this geometry.
//      * 
//      * @return minimum bounding rectangle
//      */
//     Box mbb();
// 
//     boolean intersects(Box r);
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/geometry/HasGeometry.java
// public interface HasGeometry {
// 
//     Geometry geometry();
// }
// 
// Path: src/main/java/com/github/davidmoten/util/ObjectsHelper.java
// public final class ObjectsHelper {
// 
//     private ObjectsHelper() {
//         // prevent instantiation
//     }
// 
//     static void instantiateForTestCoveragePurposesOnly() {
//         new ObjectsHelper();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T> Optional<T> asClass(Object object, Class<T> cls) {
//         if (object == null)
//             return absent();
//         else if (object.getClass() != cls)
//             return absent();
//         else
//             return Optional.of((T) object);
//     }
// 
// }


import com.github.davidmoten.rtree3d.geometry.Geometry;
import com.github.davidmoten.rtree3d.geometry.HasGeometry;
import com.github.davidmoten.util.ObjectsHelper;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
package com.github.davidmoten.rtree3d;


/**
 * An entry in the R-tree which has a spatial representation.
 * 
 * @param <T>
 *            the type of Entry
 */
public final class Entry<T, S extends Geometry> implements HasGeometry {
    private final T value;
    private final S geometry;

    /**
     * Constructor.
     * 
     * @param value
     *            the value of the entry
     * @param geometry
     *            the geometry of the value
     */
    public Entry(T value, S geometry) {
        Preconditions.checkNotNull(geometry);
        this.value = value;
        this.geometry = geometry;
    }

    /**
     * Factory method.
     * 
     * @param <T>
     *            type of value
     * @param <S>
     *            type of geometry
     * @param value
     *            object being given a spatial context
     * @param geometry
     *            geometry associated with the value
     * @return entry wrapping value and associated geometry
     */
// Path: src/main/java/com/github/davidmoten/rtree3d/geometry/Geometry.java
// public interface Geometry {
// 
//     /**
//      * <p>
//      * Returns the distance to the given {@link Box}. For a
//      * {@link Box} 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(Box r);
// 
//     /**
//      * Returns the minimum bounding rectangle of this geometry.
//      * 
//      * @return minimum bounding rectangle
//      */
//     Box mbb();
// 
//     boolean intersects(Box r);
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/geometry/HasGeometry.java
// public interface HasGeometry {
// 
//     Geometry geometry();
// }
// 
// Path: src/main/java/com/github/davidmoten/util/ObjectsHelper.java
// public final class ObjectsHelper {
// 
//     private ObjectsHelper() {
//         // prevent instantiation
//     }
// 
//     static void instantiateForTestCoveragePurposesOnly() {
//         new ObjectsHelper();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T> Optional<T> asClass(Object object, Class<T> cls) {
//         if (object == null)
//             return absent();
//         else if (object.getClass() != cls)
//             return absent();
//         else
//             return Optional.of((T) object);
//     }
// 
// }


// Path: src/main/java/com/github/davidmoten/rtree3d/Entry.java
import com.github.davidmoten.rtree3d.geometry.Geometry;
import com.github.davidmoten.rtree3d.geometry.HasGeometry;
import com.github.davidmoten.util.ObjectsHelper;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

package com.github.davidmoten.rtree3d;


/**
 * An entry in the R-tree which has a spatial representation.
 * 
 * @param <T>
 *            the type of Entry
 */
public final class Entry<T, S extends Geometry> implements HasGeometry {
    private final T value;
    private final S geometry;

    /**
     * Constructor.
     * 
     * @param value
     *            the value of the entry
     * @param geometry
     *            the geometry of the value
     */
    public Entry(T value, S geometry) {
        Preconditions.checkNotNull(geometry);
        this.value = value;
        this.geometry = geometry;
    }

    /**
     * Factory method.
     * 
     * @param <T>
     *            type of value
     * @param <S>
     *            type of geometry
     * @param value
     *            object being given a spatial context
     * @param geometry
     *            geometry associated with the value
     * @return entry wrapping value and associated geometry
     */
    public static <T, S extends Geometry> Entry<T, S> entry(T value, S geometry) {