// Path: src/main/java/com/github/davidmoten/rtree/geometry/internal/GeometryUtil.java
// public static double max(double a, double b) {
//     if (a < b)
//         return b;
//     else
//         return a;
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/internal/GeometryUtil.java
// public static double min(double a, double b) {
//     if (a < b)
//         return a;
//     else
//         return b;
// }
// 
// 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/ObjectsHelper.java
// public final class ObjectsHelper {
// 
//     private ObjectsHelper() {
//         // prevent instantiation
//     }
// 
//     @VisibleForTesting
//     static void instantiateForTestCoveragePurposesOnly() {
//         new ObjectsHelper();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T> Optional<T> asClass(Object object, Class<T> cls) {
//         if (object == null) {
//             return Optional.empty();
//         } else if (object.getClass() != cls) {
//             return Optional.empty();
//         } else {
//             return Optional.of((T) object);
//         }
//     }
// 
// }


import static com.github.davidmoten.rtree.geometry.internal.GeometryUtil.max;
import static com.github.davidmoten.rtree.geometry.internal.GeometryUtil.min;
import com.github.davidmoten.guavamini.Preconditions;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import com.github.davidmoten.rtree.internal.util.ObjectsHelper;
import java.util.Objects;
import java.util.Optional;
    }

    @Override
    public Rectangle add(Rectangle r) {
        if (r.isDoublePrecision()) {
            return RectangleDouble.create(min(x1, r.x1()), min(y1, r.y1()), max(x2, r.x2()),
                    max(y2, r.y2()));
        } else if (r instanceof RectangleFloat) {
            RectangleFloat rf = (RectangleFloat) r;
            return RectangleFloat.create(min(x1, rf.x1), min(y1, rf.y1), max(x2, rf.x2),
                    max(y2, rf.y2));
        } else {
            PointFloat rf = (PointFloat) r;
            return RectangleFloat.create(min(x1, rf.xFloat()), min(y1, rf.yFloat()),
                    max(x2, rf.xFloat()), max(y2, rf.yFloat()));
        }
    }

    @Override
    public boolean contains(double x, double y) {
        return x >= x1 && x <= x2 && y >= y1 && y <= y2;
    }

    @Override
    public boolean intersects(Rectangle r) {
        return GeometryUtil.intersects(x1, y1, x2, y2, r.x1(), r.y1(), r.x2(), r.y2());
    }

    @Override
    public double distance(Rectangle r) {
// Path: src/main/java/com/github/davidmoten/rtree/geometry/internal/GeometryUtil.java
// public static double max(double a, double b) {
//     if (a < b)
//         return b;
//     else
//         return a;
// }
// 
// Path: src/main/java/com/github/davidmoten/rtree/geometry/internal/GeometryUtil.java
// public static double min(double a, double b) {
//     if (a < b)
//         return a;
//     else
//         return b;
// }
// 
// 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/ObjectsHelper.java
// public final class ObjectsHelper {
// 
//     private ObjectsHelper() {
//         // prevent instantiation
//     }
// 
//     @VisibleForTesting
//     static void instantiateForTestCoveragePurposesOnly() {
//         new ObjectsHelper();
//     }
// 
//     @SuppressWarnings("unchecked")
//     public static <T> Optional<T> asClass(Object object, Class<T> cls) {
//         if (object == null) {
//             return Optional.empty();
//         } else if (object.getClass() != cls) {
//             return Optional.empty();
//         } else {
//             return Optional.of((T) object);
//         }
//     }
// 
// }


// Path: src/main/java/com/github/davidmoten/rtree/geometry/internal/RectangleFloat.java
import static com.github.davidmoten.rtree.geometry.internal.GeometryUtil.max;
import static com.github.davidmoten.rtree.geometry.internal.GeometryUtil.min;
import com.github.davidmoten.guavamini.Preconditions;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.Rectangle;
import com.github.davidmoten.rtree.internal.util.ObjectsHelper;
import java.util.Objects;
import java.util.Optional;

    }

    @Override
    public Rectangle add(Rectangle r) {
        if (r.isDoublePrecision()) {
            return RectangleDouble.create(min(x1, r.x1()), min(y1, r.y1()), max(x2, r.x2()),
                    max(y2, r.y2()));
        } else if (r instanceof RectangleFloat) {
            RectangleFloat rf = (RectangleFloat) r;
            return RectangleFloat.create(min(x1, rf.x1), min(y1, rf.y1), max(x2, rf.x2),
                    max(y2, rf.y2));
        } else {
            PointFloat rf = (PointFloat) r;
            return RectangleFloat.create(min(x1, rf.xFloat()), min(y1, rf.yFloat()),
                    max(x2, rf.xFloat()), max(y2, rf.yFloat()));
        }
    }

    @Override
    public boolean contains(double x, double y) {
        return x >= x1 && x <= x2 && y >= y1 && y <= y2;
    }

    @Override
    public boolean intersects(Rectangle r) {
        return GeometryUtil.intersects(x1, y1, x2, y2, r.x1(), r.y1(), r.x2(), r.y2());
    }

    @Override
    public double distance(Rectangle r) {
        return GeometryUtil.distance(x1, y1, x2, y2, r.x1(), r.y1(), r.x2(), r.y2());