Index: java/src/com/vividsolutions/jts/index/kdtree/KdTree.java
===================================================================
--- java/src/com/vividsolutions/jts/index/kdtree/KdTree.java	(revision 1067)
+++ java/src/com/vividsolutions/jts/index/kdtree/KdTree.java	(working copy)
@@ -187,8 +187,26 @@
    * @return the best matching node
    * @return null if no match was found
    */
-  private KdNode findBestMatchNode(Coordinate p) {
-    BestMatchVisitor visitor = new BestMatchVisitor(p, tolerance);
+  private KdNode findBestMatchNode(Coordinate p ) {
+	  return findBestMatchNode(p, tolerance);
+  }
+  
+  /**
+   * Finds the node in the tree which is the best match for a point
+   * being inserted.
+   * The match is made deterministic by returning the lowest of any nodes which
+   * lie the same distance from the point.
+   * There may be no match if the point is not within the distance tolerance of any
+   * existing node.
+   * 
+   * @param p the point being inserted
+   * @param searchTolerance
+   *           the maximum distance that the node should be away 
+   * @return the best matching node
+   * @return null if no match was found
+   */
+  private KdNode findBestMatchNode(Coordinate p, double searchTolerance ) {
+    BestMatchVisitor visitor = new BestMatchVisitor(p, searchTolerance);
     query(visitor.queryEnvelope(), visitor);
     return visitor.getNode();
   }
@@ -206,6 +224,11 @@
     }
     
     public Envelope queryEnvelope() {
+
+    	if (tolerance == Double.MAX_VALUE)
+    	  return new Envelope(Double.MIN_VALUE, Double.MAX_VALUE, 
+    			              Double.MIN_VALUE, Double.MAX_VALUE);
+
       Envelope queryEnv = new Envelope(p);
       queryEnv.expandBy(tolerance);
       return queryEnv;
@@ -368,4 +391,16 @@
       
     });
   }
+  
+  /**
+   * Performs a nearest neighbor search of the points in the index.
+   * 
+   * @param p
+   *          the point to search from
+   * @return
+   *          the node closest to {@link p}
+   */
+  public KdNode nearestNeighbor(Coordinate p) {
+	  return findBestMatchNode(p, Double.MAX_VALUE);
+  }
 }
\ No newline at end of file
Index: java/test/com/vividsolutions/jts/index/kdtree/KdTreeTest.java
===================================================================
--- java/test/com/vividsolutions/jts/index/kdtree/KdTreeTest.java	(revision 1067)
+++ java/test/com/vividsolutions/jts/index/kdtree/KdTreeTest.java	(working copy)
@@ -24,6 +24,47 @@
     super(name);
   }
 
+  public void testEndlessLoop()
+  {
+      KdTree kd = new KdTree();
+      kd.insert(new Coordinate(383, 381), "A");
+      kd.insert(new Coordinate(349, 168), "B");
+      kd.insert(new Coordinate(473, 223), "C");
+      kd.insert(new Coordinate(227, 44), "D");
+      kd.insert(new Coordinate(273, 214), "E");
+      kd.insert(new Coordinate(493, 87), "F");
+      kd.insert(new Coordinate(502, 290), "G");
+
+
+      KdNode res = kd.nearestNeighbor(new Coordinate(297, 133)); //Should be B
+      assertEquals("B", res.getData());
+      res = kd.nearestNeighbor(new Coordinate(272, 216)); //Should be E        }
+      assertEquals("E", res.getData());
+      res = kd.nearestNeighbor(new Coordinate(635, 377)); //Should be G
+      assertEquals("G", res.getData());
+  }
+
+  public void testNearestNeighbor()
+  {
+	  KdTree kd = new KdTree();
+      kd.insert(new Coordinate(12, 16), "A");
+      kd.insert(new Coordinate(15, 8), "B");
+      kd.insert(new Coordinate(5, 18), "C");
+      kd.insert(new Coordinate(18, 5), "D");
+      kd.insert(new Coordinate(16, 15), "E");
+      kd.insert(new Coordinate(2, 5), "F");
+      kd.insert(new Coordinate(7, 10), "G");
+      kd.insert(new Coordinate(8, 7), "H");
+      kd.insert(new Coordinate(5, 5), "I");
+      kd.insert(new Coordinate(19, 12), "J");
+      kd.insert(new Coordinate(10, 2), "K");
+
+      KdNode res = kd.nearestNeighbor(new Coordinate(13, 2));
+
+      assertEquals("K", res.getData());
+  }
+  
+  
   public void testSinglePoint() {
     KdTree index = new KdTree(.001);
 
