// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static <T> Comparator<T> compose(final Comparator<T>... comparators) {
//     return new Comparator<T>() {
//         @Override
//         public int compare(T t1, T t2) {
//             for (Comparator<T> comparator : comparators) {
//                 int value = comparator.compare(t1, t2);
//                 if (value != 0)
//                     return value;
//             }
//             return 0;
//         }
//     };
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static Comparator<HasGeometry> volumeComparator(final Box r) {
//     return new Comparator<HasGeometry>() {
// 
//         @Override
//         public int compare(HasGeometry g1, HasGeometry g2) {
//             return ((Float) g1.geometry().mbb().add(r).volume()).compareTo(g2.geometry().mbb()
//                     .add(r).volume());
//         }
//     };
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static <T extends HasGeometry> Comparator<HasGeometry> volumeIncreaseComparator(
//         final Box r) {
//     return toComparator(Functions.volumeIncrease(r));
// }
// 
// 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);
// }


import static com.github.davidmoten.rtree3d.Comparators.compose;
import static com.github.davidmoten.rtree3d.Comparators.volumeComparator;
import static com.github.davidmoten.rtree3d.Comparators.volumeIncreaseComparator;
import static java.util.Collections.min;
import java.util.List;
import com.github.davidmoten.rtree3d.geometry.Geometry;
package com.github.davidmoten.rtree3d;




/**
 * Uses minimal area increase to select a node from a list.
 *
 */
public final class SelectorMinimalVolumeIncrease implements Selector {

    @SuppressWarnings("unchecked")
    @Override
    public <T, S extends Geometry> Node<T, S> select(Geometry g, List<? extends Node<T, S>> nodes) {
// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static <T> Comparator<T> compose(final Comparator<T>... comparators) {
//     return new Comparator<T>() {
//         @Override
//         public int compare(T t1, T t2) {
//             for (Comparator<T> comparator : comparators) {
//                 int value = comparator.compare(t1, t2);
//                 if (value != 0)
//                     return value;
//             }
//             return 0;
//         }
//     };
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static Comparator<HasGeometry> volumeComparator(final Box r) {
//     return new Comparator<HasGeometry>() {
// 
//         @Override
//         public int compare(HasGeometry g1, HasGeometry g2) {
//             return ((Float) g1.geometry().mbb().add(r).volume()).compareTo(g2.geometry().mbb()
//                     .add(r).volume());
//         }
//     };
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree3d/Comparators.java
// public static <T extends HasGeometry> Comparator<HasGeometry> volumeIncreaseComparator(
//         final Box r) {
//     return toComparator(Functions.volumeIncrease(r));
// }
// 
// 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/SelectorMinimalVolumeIncrease.java
import static com.github.davidmoten.rtree3d.Comparators.compose;
import static com.github.davidmoten.rtree3d.Comparators.volumeComparator;
import static com.github.davidmoten.rtree3d.Comparators.volumeIncreaseComparator;
import static java.util.Collections.min;
import java.util.List;
import com.github.davidmoten.rtree3d.geometry.Geometry;

package com.github.davidmoten.rtree3d;




/**
 * Uses minimal area increase to select a node from a list.
 *
 */
public final class SelectorMinimalVolumeIncrease implements Selector {

    @SuppressWarnings("unchecked")
    @Override
    public <T, S extends Geometry> Node<T, S> select(Geometry g, List<? extends Node<T, S>> nodes) {
        return min(nodes, compose(volumeIncreaseComparator(g.mbb()), volumeComparator(g.mbb())));