Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Point2D.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Point2D.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Point2D.java	Fri Dec 18 12:54:29 CET 2009
@@ -24,6 +24,10 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class has been replaced by the immutable {@link org.apache.lucene.spatial.geometry.Point} class,
+ *             and will be removed
+ * @see org.apache.lucene.spatial.geometry.Point
  */
 public class Point2D {
   private double x;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/Point.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/Point.java	Fri Dec 18 12:51:23 CET 2009
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/Point.java	Fri Dec 18 12:51:23 CET 2009
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.geometry;
+
+/**
+ * Class representing a point consisting simply of an x and y coordinate
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
+ */
+public class Point {
+
+  private final double x;
+  private final double y;
+
+  /**
+   * Constructs a new point consisting of the given x and y coordinates
+   *
+   * @param x x coordinate of point
+   * @param y y coordinate of point
+   */
+  public Point(double x, double y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  // =============================================== Getters / Setters ===============================================
+
+  /**
+   * Returns the x coordinate
+   *
+   * @return x coordinate
+   */
+  public double getX() {
+    return x;
+  }
+
+  /**
+   * Returns the y coordinate
+   *
+   * @return y coordinate
+   */
+  public double getY() {
+    return y;
+  }
+}
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java	(revision 810951)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java	Fri Dec 18 12:06:34 CET 2009
@@ -24,6 +24,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This interface is unnecessary and will be removed
  */
 public interface Geometry2D {
   /**
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java	Fri Dec 18 12:09:44 CET 2009
@@ -25,6 +25,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class has been replaced by the immutable Point class, and will be removed
  */
 public class CartesianPoint {
   private int x;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java	(revision 811070)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java	Fri Dec 18 12:06:21 CET 2009
@@ -24,6 +24,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unused and will be removed
  */
 public class Ellipse implements Geometry2D {
   private Point2D center;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java	(revision 833867)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java	Fri Dec 18 12:50:07 CET 2009
@@ -17,144 +17,229 @@
 
 package org.apache.lucene.spatial.geometry;
 
+/**
+ * Class representing a latitude longitude pair.
+ *
+ * Note, this class was previous abstract with 2 implementations.  Both of these have been deprecated and the useful logic
+ * has been moved to this class.
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
+ */
+public class LatLng {
 
+  private final static int LONGITUDE_DECIMAL_DEGREE_RANGE = 360;
+  private final static int LATITUDE_DECIMAL_DEGREE_RANGE = 180;
+  private final double lat;
+  private final double lng;
+  private boolean normalized;
+
-/**
+  /**
- * Abstract base lat-lng class which can manipulate fixed point or floating
- * point based coordinates. Instances are immutable.
+   * Creates a new LatLng with the given latitude and longitude
- * 
+   *
- * @see FloatLatLng
+   * @param lat Latitude part of the LatLng
+   * @param lng Longitude part of the LatLng
+   */
+  public LatLng(double lat, double lng) {
+    if (lat > 90.0 || lat < -90.0) {
+      throw new IllegalArgumentException("Illegal latitude value " + lat);
+    }
+    this.lat = lat;
+    this.lng = lng;
+  }
+
+  /**
+   * Calculates the distance between two lat/lng's in miles.
- *
+   *
- * <p><font color="red"><b>NOTE:</b> This API is still in
- * flux and might change in incompatible ways in the next
- * release.</font>
+   * @param ll2 Second lat,lng position to calculate distance to.
+   * @return Returns the distance in miles.
- */
+   */
-public abstract class LatLng {
+  public double arcDistance(LatLng ll2) {
+    return arcDistance(ll2, DistanceUnits.MILES);
+  }
 
-  public abstract boolean isNormalized();
+  /**
+   * Calculates the distance between two lat/lng's in miles or kilometres
+   *
+   * @param targetLatLng Second lat,lng position to calculate distance to.
+   * @param distanceUnit Units to calculate distace, defaults to miles
+   * @return Returns the distance in meters or miles.
+   */
+  public double arcDistance(LatLng targetLatLng, DistanceUnits distanceUnit) {
+    LatLng srcLatLng = normalize();
+    targetLatLng = targetLatLng.normalize();
 
-  public abstract boolean isFixedPoint();
+    double srcLat = Math.toRadians(srcLatLng.getLat());
+    double srcLng = Math.toRadians(srcLatLng.getLng());
+    double targetLat = Math.toRadians(targetLatLng.getLat());
+    double targetLng = Math.toRadians(targetLatLng.getLng());
 
-  public abstract LatLng normalize();
+    return Math.acos(Math.sin(srcLat) * Math.sin(targetLat) + Math.cos(srcLat) * Math.cos(targetLat) * Math.cos(targetLng - srcLng)) * distanceUnit.earthRadius();
+  }
 
-  public abstract int getFixedLat();
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int hashCode() {
+    return new Double(lng).hashCode() ^ new Double(lat).hashCode();
+  }
 
-  public abstract int getFixedLng();
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (!LatLng.class.isInstance(obj)) {
+      return false;
+    }
 
-  public abstract double getLat();
+    LatLng latLng = (LatLng) obj;
+    return latLng.getLat() == lat && latLng.getLng() == lng;
+  }
 
-  public abstract double getLng();
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    return "[" + getLat() + "," + getLng() + "]";
+  }
 
-  public abstract LatLng copy();
+  // ================================================= Helper Methods ================================================
 
-  public abstract FixedLatLng toFixed();
+  /**
+   * Checks if {@code this} has already been normalized
+   *
+   * @return {@code true} if {@code this} is normalized, {@code false} otherwise
+   */
+  protected boolean isNormalized() {
+    return normalized || ((lng >= -180) && (lng <= 180));
+  }
 
-  public abstract FloatLatLng toFloat();
+  /**
+   * Normalizes the latitude/longitude of {@code this}, returning a new instance if any values have to change
+   *
+   * @return {@code this} if no normalization has to occur, otherwise a new instance with the normalized latitude and longitude
+   */
+  protected LatLng normalize() {
+    if (isNormalized()) {
+      return this;
+    }
-  
+
+    double newLng = ((lng + LONGITUDE_DECIMAL_DEGREE_RANGE) % LONGITUDE_DECIMAL_DEGREE_RANGE) - LONGITUDE_DECIMAL_DEGREE_RANGE / 2.0;
+
+    LatLng ret = new LatLng(lat, newLng);
+    ret.normalized = true;
+    return ret;
+  }
+
+  // ================================================= Getters / Setters =============================================
+
   /**
+   * Returns the latitude part of the LatLng
+   *
+   * @return Latitude part of the LatLng
+   */
+  public double getLat() {
+    return this.lat;
+  }
+
+  /**
+   * Returns the longitude part of the LatLng
+   *
+   * @return Longitude part of the LatLng
+   */
+  public double getLng() {
+    return this.lng;
+  }
+
+  // ================================================= Deprecated Methods =============================================
+
+  /**
+   * @deprecated Method is unnecessary and will be removed
+   */
+  public boolean isFixedPoint() {
+    return false;
+  }
+
+  /**
+   * @deprecated Method is unnecessary and will be removed
+   */
+  public int getFixedLat() {
+    return -1;
+  }
+
+  /**
+   * @deprecated Method is unnecessary and will be removed
+   */
+  public int getFixedLng() {
+    return -1;
+  }
+
+  /**
+   * @deprecated Method is unnecessary and will be removed
+   */
+  public LatLng copy() {
+    return null;
+  }
+
+  /**
+   * @return
+   * @deprecated Method is unnecesary and will be removed
+   */
+  public FixedLatLng toFixed() {
+    return null;
+  }
+
+  /**
+   * @deprecated Method is unnecessary and will be removed
+   */
+  public FloatLatLng toFloat() {
+    return null;
+  }
+
+  /**
    * Convert the lat/lng into the cartesian coordinate plane such that all
    * world coordinates are represented in the first quadrant.
    * The x dimension corresponds to latitude and y corresponds to longitude.
-   * The translation starts with the normalized latlng and adds 180 to the latitude and 
+   * The translation starts with the normalized latlng and adds 180 to the latitude and
    * 90 to the longitude (subject to fixed point scaling).
+   *
+   * @deprecated Method is unnecessary and will be removed
    */
   public CartesianPoint toCartesian() {
-    LatLng ll=normalize();
+    LatLng ll = normalize();
-    
+
-    int lat=ll.getFixedLat();
+    int lat = ll.getFixedLat();
-    int lng=ll.getFixedLng();
+    int lng = ll.getFixedLng();
-    
+
     return new CartesianPoint(
-        lng+180*FixedLatLng.SCALE_FACTOR_INT,
+        lng + 180 * FixedLatLng.SCALE_FACTOR_INT,
-        lat+90*FixedLatLng.SCALE_FACTOR_INT
+        lat + 90 * FixedLatLng.SCALE_FACTOR_INT
     );
   }
-  
+
   /**
    * The inverse of toCartesian().  Always returns a FixedLatLng.
+   *
    * @param pt
+   * @deprecated Method is unnecessary and will be removed
    */
   public static LatLng fromCartesian(CartesianPoint pt) {
-    int lat=pt.getY() - 90 * FixedLatLng.SCALE_FACTOR_INT;
+    int lat = pt.getY() - 90 * FixedLatLng.SCALE_FACTOR_INT;
-    int lng=pt.getX() - 180 * FixedLatLng.SCALE_FACTOR_INT;
+    int lng = pt.getX() - 180 * FixedLatLng.SCALE_FACTOR_INT;
-    
+
     return new FixedLatLng(lat, lng);
   }
-  
+
   /**
-   * Calculates the distance between two lat/lng's in miles.
-   * Imported from mq java client.
+   * Calculate the midpoint between this point an another.  Respects fixed vs floating point
-   * 
+   *
-   * @param ll2
-   *            Second lat,lng position to calculate distance to.
-   * 
-   * @return Returns the distance in miles.
+   * @param other
+   * @deprecated Method is unnecessary and will be removed
    */
-  public double arcDistance(LatLng ll2) {
-    return arcDistance(ll2, DistanceUnits.MILES);
+  public LatLng calculateMidpoint(LatLng other) {
+    return null;
   }
 
-  /**
-   * Calculates the distance between two lat/lng's in miles or meters.
-   * Imported from mq java client.  Variable references changed to match.
-   * 
-   * @param ll2
-   *            Second lat,lng position to calculate distance to.
-   * @param lUnits
-   *            Units to calculate distance, defaults to miles
-   * 
-   * @return Returns the distance in meters or miles.
-   */
-  public double arcDistance(LatLng ll2, DistanceUnits lUnits) {
-    LatLng ll1 = normalize();
-    ll2 = ll2.normalize();
-
-    double lat1 = ll1.getLat(), lng1 = ll1.getLng();
-    double lat2 = ll2.getLat(), lng2 = ll2.getLng();
-
-    // Check for same position
-    if (lat1 == lat2 && lng1 == lng2)
-      return 0.0;
-
-    // Get the m_dLongitude difference. Don't need to worry about
-    // crossing 180 since cos(x) = cos(-x)
-    double dLon = lng2 - lng1;
-
-    double a = radians(90.0 - lat1);
-    double c = radians(90.0 - lat2);
-    double cosB = (Math.cos(a) * Math.cos(c))
-        + (Math.sin(a) * Math.sin(c) * Math.cos(radians(dLon)));
-
-    double radius = (lUnits == DistanceUnits.MILES) ? 3963.205/* MILERADIUSOFEARTH */
-    : 6378.160187/* KMRADIUSOFEARTH */;
-
-    // Find angle subtended (with some bounds checking) in radians and
-    // multiply by earth radius to find the arc distance
-    if (cosB < -1.0)
-      return 3.14159265358979323846/* PI */* radius;
-    else if (cosB >= 1.0)
-      return 0;
-    else
-      return Math.acos(cosB) * radius;
-  }
+}
-
-  private double radians(double a) {
-    return a * 0.01745329251994;
-  }
-
-  @Override
-  public String toString() {
-    return "[" + getLat() + "," + getLng() + "]";
-  }
-
-  /**
-   * Calculate the midpoint between this point an another.  Respects fixed vs floating point
-   * @param other
-   */
-  public abstract LatLng calculateMidpoint(LatLng other);
-  
-  @Override
-  public abstract int hashCode();
-
-  @Override
-  public abstract boolean equals(Object obj);
-}
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LineSegment.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LineSegment.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LineSegment.java	Fri Dec 18 12:06:58 CET 2009
@@ -24,6 +24,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unnecessary and will be removed
  */
 public class LineSegment {
   public final Point2D A = new Point2D();
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/IntersectCase.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/IntersectCase.java	(revision 810951)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/IntersectCase.java	Fri Dec 18 12:06:47 CET 2009
@@ -22,6 +22,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This enum is unnecessary and will be removed
  */
 public enum IntersectCase {
   WITHIN,
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FloatLatLng.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FloatLatLng.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FloatLatLng.java	Fri Dec 18 12:41:18 CET 2009
@@ -21,6 +21,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unnecessary since most of the logic has been moved to LatLng.  It will be moved. 
  */
 public class FloatLatLng extends LatLng {
   private double lat;
@@ -28,12 +30,14 @@
   private boolean normalized;
   
   public FloatLatLng(double lat, double lng) {
+    super(lat, lng);
     if (lat>90.0 || lat<-90.0) throw new IllegalArgumentException("Illegal latitude value " + lat);
     this.lat=lat;
     this.lng=lng;
   }
   
   public FloatLatLng(LatLng ll) {
+    super(ll.getLat(), ll.getLng());
     this.lat=ll.getLat();
     this.lng=ll.getLng();
   }
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Vector2D.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Vector2D.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Vector2D.java	Fri Dec 18 12:08:03 CET 2009
@@ -24,6 +24,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unnecessary and will be removed
  */
 public class Vector2D {
   private double x;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java	(revision 817456)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java	Fri Dec 18 12:54:01 CET 2009
@@ -28,6 +28,10 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class has been replaced by the much improved {@link org.apache.lucene.spatial.geometry.LatLngRectangle},
+ *             and will be removed
+ * @see org.apache.lucene.spatial.geometry.LatLngRectangle
  */
 public class LLRect {
   private LatLng ll, ur;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLngRectangle.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLngRectangle.java	Fri Dec 18 12:52:37 CET 2009
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLngRectangle.java	Fri Dec 18 12:52:37 CET 2009
@@ -0,0 +1,144 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.geometry;
+
+/**
+ * Rectangle based on latitude and longitudes
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in flux and might change in incompatible ways in the next release.</font>
+ */
+public class LatLngRectangle {
+
+  private final LatLng lowerLeft;
+  private final LatLng upperRight;
+
+  /**
+   * Creates a new LatLngRectangle with the given lowerLeft latitude/longitude and upperRight latitude/longitude
+   *
+   * @param lowerLeft Latitude & longitude of the lower left point of the Rectangle
+   * @param upperRight Latitude & longitude of the upper right point of the Rectangle
+   */
+  public LatLngRectangle(LatLng lowerLeft, LatLng upperRight) {
+    this.lowerLeft = lowerLeft;
+    this.upperRight = upperRight;
+  }
+
+  /**
+   * Creates a new LatLngRectangle with the given latitude/longitude as its centre, and the given width as both its width
+   * and height (creating a square box)
+   *
+   * @param centre Latitude and longitude of the centre of the box
+   * @param width Width/height of the box
+   * @return LatLngRectangle representing a box with the given centre and width
+   */
+  public static LatLngRectangle createBox(LatLng centre, double width) {
+    LatLng upperRight = boxCorner(centre, width, 45.0);
+    LatLng lowerLeft = boxCorner(centre, width, 225.0);
+    return new LatLngRectangle(lowerLeft, upperRight);
+  }
+
+  // =============================================== Helper methods ==================================================
+
+  /**
+   * Calculates the corner (defined by the given degrees) of a box with the given LatLng at its centre, the given widths
+   *
+   * @param centre LatLng that is the centre of the box
+   * @param width Width of the box
+   * @param degrees Degrees of the corner whose LatLng is to be calculated
+   * @return LatLng of the corner at the given degrees in the box
+   */
+  private static LatLng boxCorner(LatLng centre, double width, double degrees) {
+    double a = centre.getLat();
+    double b = centre.getLng();
+    double R = DistanceUnits.MILES.earthRadius();
+    double brng = Math.PI * degrees / 180;
+    double lat1 = Math.PI * a / 180;
+    double lng1 = Math.PI * b / 180;
+
+    double lat2 = Math.asin(Math.sin(lat1) * Math.cos(width / R) + Math.cos(lat1) * Math.sin(width / R) * Math.cos(brng));
+    double lng2 = lng1 + Math.atan2(Math.sin(brng) * Math.sin(width / R) * Math.cos(lat1), Math.cos(width / R) - Math.sin(lat1) * Math.sin(lat2));
+
+    lat2 = (lat2 * 180) / Math.PI;
+    lng2 = (lng2 * 180) / Math.PI;
+
+    LatLng latLng = normLng(lat2, lng2);
+    return normLat(latLng.getLat(), latLng.getLng());
+  }
+
+  /**
+   * Normalises the given latitude and creates a new LatLng
+   *
+   * @param lat Latitude to normalise
+   * @param lng Longitude that will be part of the new LatLng
+   * @return LatLng created from the given lng and the normalisation of the lat
+   */
+  private static LatLng normLat(double lat, double lng) {
+    if (lat > 90.0) {
+      lat = 90.0 - (lat - 90.0);
+      if (lng < 0) {
+        lng = lng + 180;
+      } else {
+        lng = lng - 180;
+      }
+    } else if (lat < -90.0) {
+      lat = -90.0 - (lat + 90.0);
+      if (lng < 0) {
+        lng = lng + 180;
+      } else {
+        lng = lng - 180;
+      }
+    }
+    return new LatLng(lat, lng);
+  }
+
+  /**
+   * Normalises the given longitude and creates a new LatLng
+   *
+   * @param lat Latitude that will be part of the new LatLng
+   * @param lng Longitude to normalise
+   * @return LatLng created from the given lat and the normalisation of the lng
+   */
+  private static LatLng normLng(double lat, double lng) {
+    if (lng > 180.0) {
+      lng = -1.0 * (180.0 - (lng - 180.0));
+    } else if (lng < -180.0) {
+      lng = (lng + 180.0) + 180.0;
+    }
+    return new LatLng(lat, lng);
+  }
+
+  // =============================================== Getter / Setters ================================================
+
+  /**
+   * Returns the lower left LatLng
+   *
+   * @return Lower left LatLng
+   */
+  public LatLng getLowerLeft() {
+    return lowerLeft;
+  }
+
+  /**
+   * Returns the upper right corner LatLng
+   *
+   * @return Upper right corner LatLng
+   */
+  public LatLng getUpperRight() {
+    return upperRight;
+  }
+}
Index: contrib/spatial/src/test/org/apache/lucene/spatial/geometry/TestLatLng.java
===================================================================
--- contrib/spatial/src/test/org/apache/lucene/spatial/geometry/TestLatLng.java	Fri Dec 18 12:57:33 CET 2009
+++ contrib/spatial/src/test/org/apache/lucene/spatial/geometry/TestLatLng.java	Fri Dec 18 12:57:33 CET 2009
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.geometry;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link org.apache.lucene.spatial.geometry.LatLng}
+ */
+public class TestLatLng extends TestCase {
+
+  /**
+   * Pass condition: Distances between 2 lat/lngs calculated by arcDistance match expectations 
+   */
+  public void testArcDistance() {
+    LatLng p1 = new LatLng(7.06, 171.2);
+    LatLng p2 = new LatLng(21.6032207, -158.0);
+
+    double miles = p1.arcDistance(p2, DistanceUnits.MILES);
+
+    assertEquals(2286.396493233481, miles);
+
+    LatLng p3 = new LatLng(41.6032207, -73.087749);
+    LatLng p4 = new LatLng(55.0, 4.0);
+
+    miles = p3.arcDistance(p4, DistanceUnits.MILES);
+
+    assertEquals(3470.6454194206517, miles);
+  }
+}
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Rectangle.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Rectangle.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Rectangle.java	Fri Dec 18 12:07:49 CET 2009
@@ -24,6 +24,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unnecessary and will be removed
  */
 public class Rectangle implements Geometry2D {
   private Point2D ptMin, ptMax;
Index: contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FixedLatLng.java
===================================================================
--- contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FixedLatLng.java	(revision 812248)
+++ contrib/spatial/src/java/org/apache/lucene/spatial/geometry/FixedLatLng.java	Fri Dec 18 12:40:48 CET 2009
@@ -21,6 +21,8 @@
  * <p><font color="red"><b>NOTE:</b> This API is still in
  * flux and might change in incompatible ways in the next
  * release.</font>
+ *
+ * @deprecated This class is unnecessary since much of the logic has been moved to LatLng.  It will be removed
  */
 public class FixedLatLng extends LatLng {
   public static final double SCALE_FACTOR=1000000;
@@ -30,11 +32,13 @@
   private boolean normalized;
   
   public FixedLatLng(int lat, int lng) {
+    super(lat, lng);
     setLat(lat);
     setLng(lng);
   }
   
   public FixedLatLng(LatLng ll) {
+    super(ll.getLat(), ll.getLng());
     this.lat=ll.getFixedLat();
     this.lng=ll.getFixedLng();
   }
