You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2013/01/18 19:31:23 UTC

svn commit: r1435287 [23/41] - in /lucene/dev/branches/LUCENE-2878: ./ dev-tools/ dev-tools/eclipse/ dev-tools/idea/.idea/libraries/ dev-tools/idea/lucene/analysis/icu/ dev-tools/maven/ dev-tools/maven/lucene/benchmark/ dev-tools/maven/solr/ dev-tools/...

Modified: lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanOrQueryNodeBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanOrQueryNodeBuilder.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanOrQueryNodeBuilder.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanOrQueryNodeBuilder.java Fri Jan 18 18:30:54 2013
@@ -35,6 +35,7 @@ import org.apache.lucene.search.spans.Sp
  */
 public class SpanOrQueryNodeBuilder implements StandardQueryBuilder {
 
+  @Override
   public SpanOrQuery build(QueryNode node) throws QueryNodeException {
 
     // validates node

Modified: lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanTermQueryNodeBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanTermQueryNodeBuilder.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanTermQueryNodeBuilder.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/SpanTermQueryNodeBuilder.java Fri Jan 18 18:30:54 2013
@@ -30,6 +30,7 @@ import org.apache.lucene.search.spans.Sp
  */
 public class SpanTermQueryNodeBuilder implements StandardQueryBuilder {
 
+  @Override
   public SpanTermQuery build(QueryNode node) throws QueryNodeException {
     FieldQueryNode fieldQueryNode = (FieldQueryNode) node;
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/UniqueFieldAttributeImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/UniqueFieldAttributeImpl.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/UniqueFieldAttributeImpl.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/spans/UniqueFieldAttributeImpl.java Fri Jan 18 18:30:54 2013
@@ -42,10 +42,12 @@ public class UniqueFieldAttributeImpl ex
     this.uniqueField = "";
   }
 
+  @Override
   public void setUniqueField(CharSequence uniqueField) {
     this.uniqueField = uniqueField;
   }
 
+  @Override
   public CharSequence getUniqueField() {
     return this.uniqueField;
   }

Modified: lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestMultiFieldQPHelper.java Fri Jan 18 18:30:54 2013
@@ -18,6 +18,7 @@ package org.apache.lucene.queryparser.fl
  */
 
 import java.io.Reader;
+import java.io.StringReader;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -35,6 +36,7 @@ import org.apache.lucene.search.IndexSea
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 
 /**
@@ -339,9 +341,9 @@ public class TestMultiFieldQPHelper exte
   }
 
   /**
-   * Return empty tokens for field "f1".
+   * Return no tokens for field "f1".
    */
-  private static final class AnalyzerReturningNull extends Analyzer {
+  private static class AnalyzerReturningNull extends Analyzer {
     MockAnalyzer stdAnalyzer = new MockAnalyzer(random());
 
     public AnalyzerReturningNull() {
@@ -349,13 +351,21 @@ public class TestMultiFieldQPHelper exte
     }
 
     @Override
-    public TokenStreamComponents createComponents(String fieldName, Reader reader) {
+    protected Reader initReader(String fieldName, Reader reader) {
       if ("f1".equals(fieldName)) {
-        return new TokenStreamComponents(new EmptyTokenizer(reader));
+        // we don't use the reader, so close it:
+        IOUtils.closeWhileHandlingException(reader);
+        // return empty reader, so MockTokenizer returns no tokens:
+        return new StringReader("");
       } else {
-        return stdAnalyzer.createComponents(fieldName, reader);
+        return super.initReader(fieldName, reader);
       }
     }
+
+    @Override
+    public TokenStreamComponents createComponents(String fieldName, Reader reader) {
+      return stdAnalyzer.createComponents(fieldName, reader);
+    }
   }
 
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/Test02Boolean.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/Test02Boolean.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/Test02Boolean.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/queryparser/src/test/org/apache/lucene/queryparser/surround/query/Test02Boolean.java Fri Jan 18 18:30:54 2013
@@ -39,6 +39,7 @@ public class Test02Boolean extends Lucen
     "a c e a b c"
   };
 
+  @Override
   public void setUp() throws Exception {
     super.setUp();
     db1 = new SingleFieldTestDb(random(), docs1, fieldName);

Modified: lucene/dev/branches/LUCENE-2878/lucene/sandbox/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/sandbox/build.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/sandbox/build.xml (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/sandbox/build.xml Fri Jan 18 18:30:54 2013
@@ -24,7 +24,7 @@
   <import file="../module-build.xml"/>
 
   <path id="classpath">
-    <pathelement path="lib/jakarta-regexp-1.4.jar"/>
+    <fileset dir="lib"/>
     <path refid="base.classpath"/>
   </path>
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/DuplicateFilter.java Fri Jan 18 18:30:54 2013
@@ -102,7 +102,7 @@ public class DuplicateFilter extends Fil
       if (currTerm == null) {
         break;
       } else {
-        docs = termsEnum.docs(acceptDocs, docs, 0);
+        docs = termsEnum.docs(acceptDocs, docs, DocsEnum.FLAG_NONE);
         int doc = docs.nextDoc();
         if (doc != DocIdSetIterator.NO_MORE_DOCS) {
           if (keepMode == KeepMode.KM_USE_FIRST_OCCURRENCE) {
@@ -142,7 +142,7 @@ public class DuplicateFilter extends Fil
       } else {
         if (termsEnum.docFreq() > 1) {
           // unset potential duplicates
-          docs = termsEnum.docs(acceptDocs, docs, 0);
+          docs = termsEnum.docs(acceptDocs, docs, DocsEnum.FLAG_NONE);
           int doc = docs.nextDoc();
           if (doc != DocIdSetIterator.NO_MORE_DOCS) {
             if (keepMode == KeepMode.KM_USE_FIRST_OCCURRENCE) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JakartaRegexpCapabilities.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JakartaRegexpCapabilities.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JakartaRegexpCapabilities.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JakartaRegexpCapabilities.java Fri Jan 18 18:30:54 2013
@@ -81,6 +81,7 @@ public class JakartaRegexpCapabilities i
     this.flags = flags;
   }
   
+  @Override
   public RegexCapabilities.RegexMatcher compile(String regex) {
     return new JakartaRegexMatcher(regex, flags);
   }
@@ -115,18 +116,22 @@ public class JakartaRegexpCapabilities i
     private final CharsRef utf16 = new CharsRef(10);
     private final CharacterIterator utf16wrapper = new CharacterIterator() {
 
+      @Override
       public char charAt(int pos) {
         return utf16.chars[pos];
       }
 
+      @Override
       public boolean isEnd(int pos) {
         return pos >= utf16.length;
       }
 
+      @Override
       public String substring(int beginIndex) {
         return substring(beginIndex, utf16.length);
       }
 
+      @Override
       public String substring(int beginIndex, int endIndex) {
         return new String(utf16.chars, beginIndex, endIndex - beginIndex);
       }
@@ -137,11 +142,13 @@ public class JakartaRegexpCapabilities i
       regexp = new RE(regex, flags);
     }
     
+    @Override
     public boolean match(BytesRef term) {
       UnicodeUtil.UTF8toUTF16(term.bytes, term.offset, term.length, utf16);
       return regexp.match(utf16wrapper, 0);
     }
 
+    @Override
     public String prefix() {
       try {
         final char[] prefix;

Modified: lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JavaUtilRegexCapabilities.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JavaUtilRegexCapabilities.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JavaUtilRegexCapabilities.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/JavaUtilRegexCapabilities.java Fri Jan 18 18:30:54 2013
@@ -72,6 +72,7 @@ public class JavaUtilRegexCapabilities i
     this.flags = flags;
   }
   
+  @Override
   public RegexCapabilities.RegexMatcher compile(String regex) {
     return new JavaUtilRegexMatcher(regex, flags);
   }
@@ -110,11 +111,13 @@ public class JavaUtilRegexCapabilities i
       this.matcher = this.pattern.matcher(utf16);
     }
     
+    @Override
     public boolean match(BytesRef term) {
       UnicodeUtil.UTF8toUTF16(term.bytes, term.offset, term.length, utf16);
       return matcher.reset().matches();
     }
 
+    @Override
     public String prefix() {
       return null;
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexQuery.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/regex/RegexQuery.java Fri Jan 18 18:30:54 2013
@@ -51,10 +51,12 @@ public class RegexQuery extends MultiTer
     return term;
   }
 
+  @Override
   public void setRegexImplementation(RegexCapabilities impl) {
     this.regexImpl = impl;
   }
 
+  @Override
   public RegexCapabilities getRegexImplementation() {
     return regexImpl;
   }

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/build.xml?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/build.xml (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/build.xml Fri Jan 18 18:30:54 2013
@@ -7,7 +7,7 @@
   <import file="../module-build.xml"/>
 
   <path id="spatialjar">
-     <pathelement path="lib/spatial4j-0.3.jar"/>
+     <fileset dir="lib"/>
   </path>
 
   <path id="classpath">

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/SpatialStrategy.java Fri Jan 18 18:30:54 2013
@@ -26,6 +26,7 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.queries.function.valuesource.ReciprocalFloatFunction;
 import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.query.SpatialArgs;
 
 /**
@@ -108,7 +109,7 @@ public abstract class SpatialStrategy {
   public abstract ValueSource makeDistanceValueSource(Point queryPoint);
 
   /**
-   * Make a (ConstantScore) Query based principally on {@link org.apache.lucene.spatial.query.SpatialOperation}
+   * Make a Query based principally on {@link org.apache.lucene.spatial.query.SpatialOperation}
    * and {@link Shape} from the supplied {@code args}.
    * The default implementation is
    * <pre>return new ConstantScoreQuery(makeFilter(args));</pre>
@@ -117,7 +118,7 @@ public abstract class SpatialStrategy {
    * @throws org.apache.lucene.spatial.query.UnsupportedSpatialOperation If the strategy does not support the {@link
    * org.apache.lucene.spatial.query.SpatialOperation} in {@code args}.
    */
-  public ConstantScoreQuery makeQuery(SpatialArgs args) {
+  public Query makeQuery(SpatialArgs args) {
     return new ConstantScoreQuery(makeFilter(args));
   }
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java Fri Jan 18 18:30:54 2013
@@ -89,6 +89,7 @@ public class BBoxSimilarityValueSource e
         }
       }
 
+      @Override
       public Explanation explain(int doc) {
         // make sure it has minX and area
         if (validMinX.get(doc) && validMaxX.get(doc)) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PointPrefixTreeFieldCacheProvider.java Fri Jan 18 18:30:54 2013
@@ -45,6 +45,8 @@ public class PointPrefixTreeFieldCachePr
   @Override
   protected Point readShape(BytesRef term) {
     scanCell = grid.getNode(term.bytes, term.offset, term.length, scanCell);
-    return scanCell.isLeaf() ? scanCell.getShape().getCenter() : null;
+    if (scanCell.getLevel() == grid.getMaxLevels() && !scanCell.isLeaf())
+      return scanCell.getCenter();
+    return null;
   }
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java Fri Jan 18 18:30:54 2013
@@ -45,7 +45,7 @@ import java.util.concurrent.ConcurrentHa
  * <h4>Characteristics:</h4>
  * <ul>
  * <li>Can index any shape; however only {@link RecursivePrefixTreeStrategy}
- * can effectively search non-point shapes. <em>Not tested.</em></li>
+ * can effectively search non-point shapes.</li>
  * <li>Can index a variable number of shapes per field value. This strategy
  * can do it via multiple calls to {@link #createIndexableFields(com.spatial4j.core.shape.Shape)}
  * for a document or by giving it some sort of Shape aggregate (e.g. JTS
@@ -57,8 +57,9 @@ import java.util.concurrent.ConcurrentHa
  * is supported.  If only points are indexed then this is effectively equivalent
  * to IsWithin.</li>
  * <li>The strategy supports {@link #makeDistanceValueSource(com.spatial4j.core.shape.Point)}
- * even for multi-valued data.  However, <em>it will likely be removed in the
- * future</em> in lieu of using another strategy with a more scalable
+ * even for multi-valued data, so long as the indexed data is all points; the
+ * behavior is undefined otherwise.  However, <em>it will likely be removed in
+ * the future</em> in lieu of using another strategy with a more scalable
  * implementation.  Use of this call is the only
  * circumstance in which a cache is used.  The cache is simple but as such
  * it doesn't scale to large numbers of points nor is it real-time-search
@@ -123,20 +124,12 @@ public abstract class PrefixTreeStrategy
   public Field[] createIndexableFields(Shape shape, double distErr) {
     int detailLevel = grid.getLevelForDistance(distErr);
     List<Node> cells = grid.getNodes(shape, detailLevel, true);//true=intermediates cells
-    //If shape isn't a point, add a full-resolution center-point so that
-    // PointPrefixTreeFieldCacheProvider has the center-points.
-    //TODO index each point of a multi-point or other aggregate.
-    //TODO remove this once support for a distance ValueSource is removed.
-    if (!(shape instanceof Point)) {
-      Point ctr = shape.getCenter();
-      //TODO should be smarter; don't index 2 tokens for this in CellTokenStream. Harmless though.
-      cells.add(grid.getNodes(ctr,grid.getMaxLevels(),false).get(0));
-    }
 
     //TODO is CellTokenStream supposed to be re-used somehow? see Uwe's comments:
     //  http://code.google.com/p/lucene-spatial-playground/issues/detail?id=4
 
-    Field field = new Field(getFieldName(), new CellTokenStream(cells.iterator()), FIELD_TYPE);
+    Field field = new Field(getFieldName(),
+        new CellTokenStream(cells.iterator()), FIELD_TYPE);
     return new Field[]{field};
   }
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java Fri Jan 18 18:30:54 2013
@@ -19,7 +19,11 @@ package org.apache.lucene.spatial.prefix
 
 import com.spatial4j.core.shape.Shape;
 import com.spatial4j.core.shape.SpatialRelation;
-import org.apache.lucene.index.*;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Filter;
@@ -110,23 +114,28 @@ RE "scan" threshold:
     while(!cells.isEmpty()) {
       final Node cell = cells.removeFirst();
       final BytesRef cellTerm = new BytesRef(cell.getTokenBytes());
-      TermsEnum.SeekStatus seekStat = termsEnum.seekCeil(cellTerm);
-      if (seekStat == TermsEnum.SeekStatus.END)
-        break;
-      if (seekStat == TermsEnum.SeekStatus.NOT_FOUND)
+      if (!termsEnum.seekExact(cellTerm, true))
         continue;
       if (cell.getLevel() == detailLevel || cell.isLeaf()) {
-        docsEnum = termsEnum.docs(acceptDocs, docsEnum, 0);
+        docsEnum = termsEnum.docs(acceptDocs, docsEnum, DocsEnum.FLAG_NONE);
         addDocs(docsEnum,bits);
       } else {//any other intersection
-        //If the next indexed term is the leaf marker, then add all of them
+        assert cell.getLevel() < detailLevel; //assertions help clarify logic
+        assert !cell.isLeaf();
+        //If the next indexed term just adds a leaf marker ('+') to cell,
+        // then add all of those docs
         BytesRef nextCellTerm = termsEnum.next();
+        if (nextCellTerm == null)
+          break;
         assert StringHelper.startsWith(nextCellTerm, cellTerm);
         scanCell = grid.getNode(nextCellTerm.bytes, nextCellTerm.offset, nextCellTerm.length, scanCell);
-        if (scanCell.isLeaf()) {
-          docsEnum = termsEnum.docs(acceptDocs, docsEnum, 0);
+        if (scanCell.getLevel() == cell.getLevel() && scanCell.isLeaf()) {
+          docsEnum = termsEnum.docs(acceptDocs, docsEnum, DocsEnum.FLAG_NONE);
           addDocs(docsEnum,bits);
-          termsEnum.next();//move pointer to avoid potential redundant addDocs() below
+          //increment pointer to avoid potential redundant addDocs() below
+          nextCellTerm = termsEnum.next();
+          if (nextCellTerm == null)
+            break;
         }
 
         //Decide whether to continue to divide & conquer, or whether it's time to scan through terms beneath this cell.
@@ -144,12 +153,17 @@ RE "scan" threshold:
             if (termLevel > detailLevel)
               continue;
             if (termLevel == detailLevel || scanCell.isLeaf()) {
-              //TODO should put more thought into implications of box vs point
-              Shape cShape = termLevel == grid.getMaxLevels() ? scanCell.getCenter() : scanCell.getShape();
+              Shape cShape;
+              //if this cell represents a point, use the cell center vs the box
+              // (points never have isLeaf())
+              if (termLevel == grid.getMaxLevels() && !scanCell.isLeaf())
+                cShape = scanCell.getCenter();
+              else
+                cShape = scanCell.getShape();
               if(queryShape.relate(cShape) == SpatialRelation.DISJOINT)
                 continue;
 
-              docsEnum = termsEnum.docs(acceptDocs, docsEnum, 0);
+              docsEnum = termsEnum.docs(acceptDocs, docsEnum, DocsEnum.FLAG_NONE);
               addDocs(docsEnum,bits);
             }
           }//term loop

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java Fri Jan 18 18:30:54 2013
@@ -101,11 +101,11 @@ public class GeohashPrefixTree extends S
 
   class GhCell extends Node {
     GhCell(String token) {
-      super(GeohashPrefixTree.this, token);
+      super(token);
     }
 
     GhCell(byte[] bytes, int off, int len) {
-      super(GeohashPrefixTree.this, bytes, off, len);
+      super(bytes, off, len);
     }
 
     @Override

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java Fri Jan 18 18:30:54 2013
@@ -44,11 +44,14 @@ public abstract class Node implements Co
 
   private String token;//this is the only part of equality
 
-  protected SpatialRelation shapeRel;//set in getSubCells(filter), and via setLeaf().
-  private SpatialPrefixTree spatialPrefixTree;
+  /** When set via getSubCells(filter), it is the relationship between this
+   * cell and the given shape filter.  If set via setLeaf() (to WITHIN), it is
+   * meant to indicate no further sub-cells are going to be provided because
+   * maxLevels or a detailLevel is hit. It's always null for points.
+   */
+  protected SpatialRelation shapeRel;
 
-  protected Node(SpatialPrefixTree spatialPrefixTree, String token) {
-    this.spatialPrefixTree = spatialPrefixTree;
+  protected Node(String token) {
     this.token = token;
     if (token.length() > 0 && token.charAt(token.length() - 1) == (char) LEAF_BYTE) {
       this.token = token.substring(0, token.length() - 1);
@@ -59,8 +62,7 @@ public abstract class Node implements Co
       getShape();//ensure any lazy instantiation completes to make this threadsafe
   }
 
-  protected Node(SpatialPrefixTree spatialPrefixTree, byte[] bytes, int off, int len) {
-    this.spatialPrefixTree = spatialPrefixTree;
+  protected Node(byte[] bytes, int off, int len) {
     this.bytes = bytes;
     this.b_off = off;
     this.b_len = len;
@@ -78,11 +80,10 @@ public abstract class Node implements Co
   }
 
   private void b_fixLeaf() {
+    //note that non-point shapes always have the maxLevels cell set with setLeaf
     if (bytes[b_off + b_len - 1] == LEAF_BYTE) {
       b_len--;
       setLeaf();
-    } else if (getLevel() == spatialPrefixTree.getMaxLevels()) {
-      setLeaf();
     }
   }
 
@@ -90,6 +91,10 @@ public abstract class Node implements Co
     return shapeRel;
   }
 
+  /**
+   * For points, this is always false.  Otherwise this is true if there are no
+   * further cells with this prefix for the shape (always true at maxLevels).
+   */
   public boolean isLeaf() {
     return shapeRel == SpatialRelation.WITHIN;
   }
@@ -133,8 +138,14 @@ public abstract class Node implements Co
   //public Cell getParent();
 
   /**
-   * Like {@link #getSubCells()} but with the results filtered by a shape. If that shape is a {@link com.spatial4j.core.shape.Point} then it
-   * must call {@link #getSubCell(com.spatial4j.core.shape.Point)};
+   * Like {@link #getSubCells()} but with the results filtered by a shape. If
+   * that shape is a {@link com.spatial4j.core.shape.Point} then it
+   * must call {@link #getSubCell(com.spatial4j.core.shape.Point)}.
+   * The returned cells should have their {@link Node#shapeRel} set to their
+   * relation with {@code shapeFilter} for non-point. As such,
+   * {@link org.apache.lucene.spatial.prefix.tree.Node#isLeaf()} should be
+   * accurate.
+   * <p/>
    * Precondition: Never called when getLevel() == maxLevel.
    *
    * @param shapeFilter an optional filter for the returned cells.

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java Fri Jan 18 18:30:54 2013
@@ -228,16 +228,16 @@ public class QuadPrefixTree extends Spat
   class QuadCell extends Node {
 
     public QuadCell(String token) {
-      super(QuadPrefixTree.this, token);
+      super(token);
     }
 
     public QuadCell(String token, SpatialRelation shapeRel) {
-      super(QuadPrefixTree.this, token);
+      super(token);
       this.shapeRel = shapeRel;
     }
 
     QuadCell(byte[] bytes, int off, int len) {
-      super(QuadPrefixTree.this, bytes, off, len);
+      super(bytes, off, len);
     }
 
     @Override

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java Fri Jan 18 18:30:54 2013
@@ -156,7 +156,7 @@ public abstract class SpatialPrefixTree 
     }
     final Collection<Node> subCells = node.getSubCells(shape);
     if (node.getLevel() == detailLevel - 1) {
-      if (subCells.size() < node.getSubCellsSize()) {
+      if (subCells.size() < node.getSubCellsSize() || node.getLevel() == 0) {
         if (inclParents)
           result.add(node);
         for (Node subCell : subCells) {
@@ -164,7 +164,7 @@ public abstract class SpatialPrefixTree 
         }
         result.addAll(subCells);
       } else {//a bottom level (i.e. detail level) optimization where all boxes intersect, so use parent cell.
-        node.setLeaf();
+        node.setLeaf();//the cell may not be strictly within but its close
         result.add(node);
       }
     } else {

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java Fri Jan 18 18:30:54 2013
@@ -17,6 +17,9 @@ package org.apache.lucene.spatial.query;
  * limitations under the License.
  */
 
+import com.spatial4j.core.shape.Shape;
+import com.spatial4j.core.shape.SpatialRelation;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -25,14 +28,16 @@ import java.util.Locale;
 import java.util.Map;
 
 /**
- * A clause that compares a stored geometry to a supplied geometry.
+ * A clause that compares a stored geometry to a supplied geometry. For more
+ * explanation of each operation, consider looking at the source implementation
+ * of {@link #evaluate(com.spatial4j.core.shape.Shape, com.spatial4j.core.shape.Shape)}.
  *
  * @see <a href="http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm">
  *   ESRIs docs on spatial relations</a>
  *
  * @lucene.experimental
  */
-public class SpatialOperation implements Serializable {
+public abstract class SpatialOperation implements Serializable {
   // Private registry
   private static final Map<String, SpatialOperation> registry = new HashMap<String, SpatialOperation>();
   private static final List<SpatialOperation> list = new ArrayList<SpatialOperation>();
@@ -40,15 +45,55 @@ public class SpatialOperation implements
   // Geometry Operations
 
   /** Bounding box of the *indexed* shape. */
-  public static final SpatialOperation BBoxIntersects = new SpatialOperation("BBoxIntersects", true, false, false);
+  public static final SpatialOperation BBoxIntersects = new SpatialOperation("BBoxIntersects", true, false, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.getBoundingBox().relate(queryShape).intersects();
+    }
+  };
   /** Bounding box of the *indexed* shape. */
-  public static final SpatialOperation BBoxWithin     = new SpatialOperation("BBoxWithin", true, false, false);
-  public static final SpatialOperation Contains       = new SpatialOperation("Contains", true, true, false);
-  public static final SpatialOperation Intersects     = new SpatialOperation("Intersects", true, false, false);
-  public static final SpatialOperation IsEqualTo      = new SpatialOperation("IsEqualTo", false, false, false);
-  public static final SpatialOperation IsDisjointTo   = new SpatialOperation("IsDisjointTo", false, false, false);
-  public static final SpatialOperation IsWithin       = new SpatialOperation("IsWithin", true, false, true);
-  public static final SpatialOperation Overlaps       = new SpatialOperation("Overlaps", true, false, true);
+  public static final SpatialOperation BBoxWithin     = new SpatialOperation("BBoxWithin", true, false, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.getBoundingBox().relate(queryShape) == SpatialRelation.WITHIN;
+    }
+  };
+  public static final SpatialOperation Contains       = new SpatialOperation("Contains", true, true, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.hasArea() && indexedShape.relate(queryShape) == SpatialRelation.CONTAINS;
+    }
+  };
+  public static final SpatialOperation Intersects     = new SpatialOperation("Intersects", true, false, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.relate(queryShape).intersects();
+    }
+  };
+  public static final SpatialOperation IsEqualTo      = new SpatialOperation("IsEqualTo", false, false, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return indexedShape.equals(queryShape);
+    }
+  };
+  public static final SpatialOperation IsDisjointTo   = new SpatialOperation("IsDisjointTo", false, false, false) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return ! indexedShape.relate(queryShape).intersects();
+    }
+  };
+  public static final SpatialOperation IsWithin       = new SpatialOperation("IsWithin", true, false, true) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return queryShape.hasArea() && indexedShape.relate(queryShape) == SpatialRelation.WITHIN;
+    }
+  };
+  public static final SpatialOperation Overlaps       = new SpatialOperation("Overlaps", true, false, true) {
+    @Override
+    public boolean evaluate(Shape indexedShape, Shape queryShape) {
+      return queryShape.hasArea() && indexedShape.relate(queryShape).intersects();
+    }
+  };
 
   // Member variables
   private final boolean scoreIsMeaningful;
@@ -90,6 +135,11 @@ public class SpatialOperation implements
     return false;
   }
 
+  /**
+   * Returns whether the relationship between indexedShape and queryShape is
+   * satisfied by this operation.
+   */
+  public abstract boolean evaluate(Shape indexedShape, Shape queryShape);
 
   // ================================================= Getters / Setters =============================================
 

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeFieldCacheProvider.java Fri Jan 18 18:30:54 2013
@@ -70,7 +70,7 @@ public abstract class ShapeFieldCachePro
       while (term != null) {
         T shape = readShape(term);
         if( shape != null ) {
-          docs = te.docs(null, docs, 0);
+          docs = te.docs(null, docs, DocsEnum.FLAG_NONE);
           Integer docid = docs.nextDoc();
           while (docid != DocIdSetIterator.NO_MORE_DOCS) {
             idx.add( docid, shape );

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java Fri Jan 18 18:30:54 2013
@@ -29,6 +29,7 @@ import org.apache.lucene.index.Directory
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.StoredDocument;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
@@ -54,6 +55,8 @@ import java.io.IOException;
  */
 public class SpatialExample extends LuceneTestCase {
 
+  //Note: Test invoked via TestTestFramework.spatialExample()
+
   public static void main(String[] args) throws IOException {
     new SpatialExample().test();
   }
@@ -148,14 +151,27 @@ public class SpatialExample extends Luce
       Filter filter = strategy.makeFilter(args);
       TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), filter, 10, idSort);
       assertDocMatchedIds(indexSearcher, docs, 2);
+      //Now, lets get the distance for the 1st doc via computing from stored point value:
+      // (this computation is usually not redundant)
+      StoredDocument doc1 = indexSearcher.doc(docs.scoreDocs[0].doc);
+      String doc1Str = doc1.getField(strategy.getFieldName()).stringValue();
+      Point doc1Point = (Point) ctx.readShape(doc1Str);
+      double doc1DistDEG = ctx.getDistCalc().distance(args.getShape().getCenter(), doc1Point);
+      assertEquals(121.6d, DistanceUtils.degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
     }
-    //--Match all, order by distance
+    //--Match all, order by distance ascending
     {
       Point pt = ctx.makePoint(60, -50);
       ValueSource valueSource = strategy.makeDistanceValueSource(pt);//the distance (in degrees)
-      Sort reverseDistSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);//true=asc dist
-      TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, reverseDistSort);
+      Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);//false=asc dist
+      TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, distSort);
       assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
+      //To get the distance, we could compute from stored values like earlier.
+      // However in this example we sorted on it, and the distance will get
+      // computed redundantly.  If the distance is only needed for the top-X
+      // search results then that's not a big deal. Alternatively, try wrapping
+      // the ValueSource with CachingDoubleValueSource then retrieve the value
+      // from the ValueSource now. See LUCENE-4541 for an example.
     }
     //demo arg parsing
     {

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestCase.java Fri Jan 18 18:30:54 2013
@@ -1,3 +1,5 @@
+package org.apache.lucene.spatial;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,8 +17,9 @@
  * limitations under the License.
  */
 
-package org.apache.lucene.spatial;
-
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.RandomIndexWriter;
@@ -35,6 +38,10 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomGaussian;
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
+
+/** A base test class for spatial lucene. It's mostly Lucene generic. */
 public abstract class SpatialTestCase extends LuceneTestCase {
 
   private DirectoryReader indexReader;
@@ -42,6 +49,8 @@ public abstract class SpatialTestCase ex
   private Directory directory;
   protected IndexSearcher indexSearcher;
 
+  protected SpatialContext ctx;//subclass must initialize
+
   @Override
   @Before
   public void setUp() throws Exception {
@@ -100,6 +109,63 @@ public abstract class SpatialTestCase ex
     }
   }
 
+  protected Point randomPoint() {
+    final Rectangle WB = ctx.getWorldBounds();
+    return ctx.makePoint(
+        randomIntBetween((int) WB.getMinX(), (int) WB.getMaxX()),
+        randomIntBetween((int) WB.getMinY(), (int) WB.getMaxY()));
+  }
+
+  protected Rectangle randomRectangle() {
+    final Rectangle WB = ctx.getWorldBounds();
+    int rW = (int) randomGaussianMeanMax(10, WB.getWidth());
+    double xMin = randomIntBetween((int) WB.getMinX(), (int) WB.getMaxX() - rW);
+    double xMax = xMin + rW;
+
+    int yH = (int) randomGaussianMeanMax(Math.min(rW, WB.getHeight()), WB.getHeight());
+    double yMin = randomIntBetween((int) WB.getMinY(), (int) WB.getMaxY() - yH);
+    double yMax = yMin + yH;
+
+    return ctx.makeRectangle(xMin, xMax, yMin, yMax);
+  }
+
+  private double randomGaussianMinMeanMax(double min, double mean, double max) {
+    assert mean > min;
+    return randomGaussianMeanMax(mean - min, max - min) + min;
+  }
+
+  /**
+   * Within one standard deviation (68% of the time) the result is "close" to
+   * mean. By "close": when greater than mean, it's the lesser of 2*mean or half
+   * way to max, when lesser than mean, it's the greater of max-2*mean or half
+   * way to 0. The other 32% of the time it's in the rest of the range, touching
+   * either 0 or max but never exceeding.
+   */
+  private double randomGaussianMeanMax(double mean, double max) {
+    // DWS: I verified the results empirically
+    assert mean <= max && mean >= 0;
+    double g = randomGaussian();
+    double mean2 = mean;
+    double flip = 1;
+    if (g < 0) {
+      mean2 = max - mean;
+      flip = -1;
+      g *= -1;
+    }
+    // pivot is the distance from mean2 towards max where the boundary of
+    // 1 standard deviation alters the calculation
+    double pivotMax = max - mean2;
+    double pivot = Math.min(mean2, pivotMax / 2);//from 0 to max-mean2
+    assert pivot >= 0 && pivotMax >= pivot && g >= 0;
+    double pivotResult;
+    if (g <= 1)
+      pivotResult = pivot * g;
+    else
+      pivotResult = Math.min(pivotMax, (g - 1) * (pivotMax - pivot) + pivot);
+
+    return mean + flip * pivotResult;
+  }
+
   // ================================================= Inner Classes =================================================
 
   protected static class SearchResults {
@@ -116,7 +182,7 @@ public abstract class SpatialTestCase ex
       StringBuilder str = new StringBuilder();
       str.append("found: ").append(numFound).append('[');
       for(SearchResult r : results) {
-        String id = r.document.get("id");
+        String id = r.getId();
         str.append(id).append(", ");
       }
       str.append(']');
@@ -138,6 +204,10 @@ public abstract class SpatialTestCase ex
       this.score = score;
       this.document = storedDocument;
     }
+
+    public String getId() {
+      return document.get("id");
+    }
     
     @Override
     public String toString() {

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialTestQuery.java Fri Jan 18 18:30:54 2013
@@ -82,6 +82,8 @@ public class SpatialTestQuery {
 
   @Override
   public String toString() {
-    return line;
+    if (line != null)
+      return line;
+    return args.toString()+" "+ids;
   }
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java Fri Jan 18 18:30:54 2013
@@ -31,8 +31,9 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.search.CheckHits;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.spatial.query.SpatialArgs;
 import org.apache.lucene.spatial.query.SpatialArgsParser;
-import org.junit.Assert;
+import org.apache.lucene.spatial.query.SpatialOperation;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -42,6 +43,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
 
@@ -64,7 +66,6 @@ public abstract class StrategyTestCase e
   protected final SpatialArgsParser argsParser = new SpatialArgsParser();
 
   protected SpatialStrategy strategy;
-  protected SpatialContext ctx;
   protected boolean storeShape = true;
 
   protected void executeQueries(SpatialMatchConcern concern, String... testQueryFile) throws IOException {
@@ -82,7 +83,10 @@ public abstract class StrategyTestCase e
   }
 
   protected List<Document> getDocuments(String testDataFile) throws IOException {
-    Iterator<SampleData> sampleData = getSampleData(testDataFile);
+    return getDocuments(getSampleData(testDataFile));
+  }
+
+  protected List<Document> getDocuments(Iterator<SampleData> sampleData) {
     List<Document> documents = new ArrayList<Document>();
     while (sampleData.hasNext()) {
       SampleData data = sampleData.next();
@@ -128,50 +132,52 @@ public abstract class StrategyTestCase e
       SpatialMatchConcern concern) {
     while (queries.hasNext()) {
       SpatialTestQuery q = queries.next();
+      runTestQuery(concern, q);
+    }
+  }
+
+  public void runTestQuery(SpatialMatchConcern concern, SpatialTestQuery q) {
+    String msg = q.toString(); //"Query: " + q.args.toString(ctx);
+    SearchResults got = executeQuery(strategy.makeQuery(q.args), Math.max(100, q.ids.size()+1));
+    if (storeShape && got.numFound > 0) {
+      //check stored value is there & parses
+      assertNotNull(ctx.readShape(got.results.get(0).document.get(strategy.getFieldName())));
+    }
+    if (concern.orderIsImportant) {
+      Iterator<String> ids = q.ids.iterator();
+      for (SearchResult r : got.results) {
+        String id = r.document.get("id");
+        if (!ids.hasNext()) {
+          fail(msg + " :: Did not get enough results.  Expect" + q.ids + ", got: " + got.toDebugString());
+        }
+        assertEquals("out of order: " + msg, ids.next(), id);
+      }
 
-      String msg = q.line; //"Query: " + q.args.toString(ctx);
-      SearchResults got = executeQuery(strategy.makeQuery(q.args), 100);
-      if (storeShape && got.numFound > 0) {
-        //check stored value is there & parses
-        assertNotNull(ctx.readShape(got.results.get(0).document.get(strategy.getFieldName())));
+      if (ids.hasNext()) {
+        fail(msg + " :: expect more results then we got: " + ids.next());
       }
-      if (concern.orderIsImportant) {
-        Iterator<String> ids = q.ids.iterator();
+    } else {
+      // We are looking at how the results overlap
+      if (concern.resultsAreSuperset) {
+        Set<String> found = new HashSet<String>();
         for (SearchResult r : got.results) {
-          String id = r.document.get("id");
-          if(!ids.hasNext()) {
-            Assert.fail(msg + " :: Did not get enough results.  Expect" + q.ids+", got: "+got.toDebugString());
-          }
-          Assert.assertEquals( "out of order: " + msg, ids.next(), id);
+          found.add(r.document.get("id"));
         }
-        
-        if (ids.hasNext()) {
-          Assert.fail(msg + " :: expect more results then we got: " + ids.next());
+        for (String s : q.ids) {
+          if (!found.contains(s)) {
+            fail("Results are mising id: " + s + " :: " + found);
+          }
         }
       } else {
-        // We are looking at how the results overlap
-        if( concern.resultsAreSuperset ) {
-          Set<String> found = new HashSet<String>();
-          for (SearchResult r : got.results) {
-            found.add(r.document.get("id"));
-          }
-          for( String s : q.ids ) {
-            if( !found.contains( s ) ) {
-              Assert.fail( "Results are mising id: "+s + " :: " + found );
-            }
-          }
+        List<String> found = new ArrayList<String>();
+        for (SearchResult r : got.results) {
+          found.add(r.document.get("id"));
         }
-        else {
-          List<String> found = new ArrayList<String>();
-          for (SearchResult r : got.results) {
-            found.add(r.document.get("id"));
-          }
 
-          // sort both so that the order is not important
-          Collections.sort(q.ids);
-          Collections.sort(found);
-          Assert.assertEquals(msg, q.ids.toString(), found.toString());
-        }
+        // sort both so that the order is not important
+        Collections.sort(q.ids);
+        Collections.sort(found);
+        assertEquals(msg, q.ids.toString(), found.toString());
       }
     }
   }
@@ -218,4 +224,19 @@ public abstract class StrategyTestCase e
     CheckHits.checkExplanations(q, "", indexSearcher);
   }
 
+  protected void assertOperation(Map<String,Shape> indexedDocs,
+                                 SpatialOperation operation, Shape queryShape) {
+    //Generate truth via brute force
+    Set<String> expectedIds = new HashSet<String>();
+    for (Map.Entry<String, Shape> stringShapeEntry : indexedDocs.entrySet()) {
+      if (operation.evaluate(stringShapeEntry.getValue(), queryShape))
+        expectedIds.add(stringShapeEntry.getKey());
+    }
+
+    SpatialTestQuery testQuery = new SpatialTestQuery();
+    testQuery.args = new SpatialArgs(operation, queryShape);
+    testQuery.ids = new ArrayList<String>(expectedIds);
+    runTestQuery(SpatialMatchConcern.FILTER, testQuery);
+  }
+
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java Fri Jan 18 18:30:54 2013
@@ -59,4 +59,11 @@ public class TestTestFramework extends L
     Assert.assertEquals( SpatialOperation.Intersects, sf.args.getOperation() );
   }
 
+  @Test
+  public void spatialExample() throws IOException {
+    //kind of a hack so that SpatialExample is tested despite
+    // it not starting or ending with "Test".
+    SpatialExample.main(null);
+  }
+
 }

Modified: lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java Fri Jan 18 18:30:54 2013
@@ -31,6 +31,7 @@ public class SpatialPrefixTreeTest exten
   private SpatialContext ctx;
   private SpatialPrefixTree trie;
 
+  @Override
   @Before
   public void setUp() throws Exception {
     super.setUp();

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/DirectSpellChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/DirectSpellChecker.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/DirectSpellChecker.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/DirectSpellChecker.java Fri Jan 18 18:30:54 2013
@@ -17,20 +17,12 @@ package org.apache.lucene.search.spell;
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.PriorityQueue;
-
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.MultiFields;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Terms;
-import org.apache.lucene.search.FuzzyTermsEnum;
 import org.apache.lucene.search.BoostAttribute;
+import org.apache.lucene.search.FuzzyTermsEnum;
 import org.apache.lucene.search.MaxNonCompetitiveBoostAttribute;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.AttributeSource;
@@ -39,6 +31,14 @@ import org.apache.lucene.util.CharsRef;
 import org.apache.lucene.util.UnicodeUtil;
 import org.apache.lucene.util.automaton.LevenshteinAutomata;
 
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.PriorityQueue;
+
 /**
  * Simple automaton-based spellchecker.
  * <p>
@@ -384,9 +384,22 @@ public class DirectSpellChecker {
     }
     return suggestions;
   }
-  
-  private Collection<ScoreTerm> suggestSimilar(Term term, int numSug, 
-      IndexReader ir, int docfreq, int editDistance, float accuracy, final CharsRef spare) throws IOException {
+
+  /**
+   * Provide spelling corrections based on several parameters.
+   *
+   * @param term The term to suggest spelling corrections for
+   * @param numSug The maximum number of spelling corrections
+   * @param ir The index reader to fetch the candidate spelling corrections from
+   * @param docfreq The minimum document frequency a potential suggestion need to have in order to be included
+   * @param editDistance The maximum edit distance candidates are allowed to have
+   * @param accuracy The minimum accuracy a suggested spelling correction needs to have in order to be included
+   * @param spare a chars scratch
+   * @return a collection of spelling corrections sorted by <code>ScoreTerm</code>'s natural order.
+   * @throws IOException If I/O related errors occur
+   */
+  protected Collection<ScoreTerm> suggestSimilar(Term term, int numSug, IndexReader ir, int docfreq, int editDistance,
+                                                 float accuracy, final CharsRef spare) throws IOException {
     
     AttributeSource atts = new AttributeSource();
     MaxNonCompetitiveBoostAttribute maxBoostAtt =
@@ -449,15 +462,44 @@ public class DirectSpellChecker {
       
     return stQueue;
   }
-  
-  private static class ScoreTerm implements Comparable<ScoreTerm> {
+
+  /**
+   * Holds a spelling correction for internal usage inside {@link DirectSpellChecker}.
+   */
+  protected static class ScoreTerm implements Comparable<ScoreTerm> {
+
+    /**
+     * The actual spellcheck correction.
+     */
     public BytesRef term;
+
+    /**
+     * The boost representing the similarity from the FuzzyTermsEnum (internal similarity score)
+     */
     public float boost;
+
+    /**
+     * The df of the spellcheck correction.
+     */
     public int docfreq;
-    
+
+    /**
+     * The spellcheck correction represented as string, can be <code>null</code>.
+     */
     public String termAsString;
+
+    /**
+     * The similarity score.
+     */
     public float score;
-    
+
+    /**
+     * Constructor.
+     */
+    public ScoreTerm() {
+    }
+
+    @Override
     public int compareTo(ScoreTerm other) {
       if (term.bytesEquals(other.term))
         return 0; // consistent with equals

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/HighFrequencyDictionary.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/HighFrequencyDictionary.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/HighFrequencyDictionary.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/HighFrequencyDictionary.java Fri Jan 18 18:30:54 2013
@@ -55,6 +55,7 @@ public class HighFrequencyDictionary imp
     this.thresh = thresh;
   }
 
+  @Override
   public final BytesRefIterator getWordsIterator() throws IOException {
     return new HighFrequencyIterator();
   }
@@ -79,6 +80,7 @@ public class HighFrequencyDictionary imp
       return freq >= minNumDocs;
     }
     
+    @Override
     public long weight() {
       return freq;
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/JaroWinklerDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/JaroWinklerDistance.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/JaroWinklerDistance.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/JaroWinklerDistance.java Fri Jan 18 18:30:54 2013
@@ -92,6 +92,7 @@ public class JaroWinklerDistance impleme
     return new int[] { matches, transpositions / 2, prefix, max.length() };
   }
 
+  @Override
   public float getDistance(String s1, String s2) {
     int[] mtp = matches(s1, s2);
     float m = mtp[0];

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LevensteinDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LevensteinDistance.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LevensteinDistance.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LevensteinDistance.java Fri Jan 18 18:30:54 2013
@@ -33,6 +33,7 @@ public final class LevensteinDistance im
     //*****************************
     // Compute Levenshtein distance: see org.apache.commons.lang.StringUtils#getLevenshteinDistance(String, String)
     //*****************************
+    @Override
     public float getDistance (String target, String other) {
       char[] sa;
       int n;

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LuceneDictionary.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LuceneDictionary.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LuceneDictionary.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/LuceneDictionary.java Fri Jan 18 18:30:54 2013
@@ -41,6 +41,7 @@ public class LuceneDictionary implements
     this.field = field;
   }
 
+  @Override
   public final BytesRefIterator getWordsIterator() throws IOException {
     final Terms terms = MultiFields.getTerms(reader, field);
     if (terms != null) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/NGramDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/NGramDistance.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/NGramDistance.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/NGramDistance.java Fri Jan 18 18:30:54 2013
@@ -50,6 +50,7 @@ public class NGramDistance implements St
     this(2);
   }
   
+  @Override
   public float getDistance(String source, String target) {
     final int sl = source.length();
     final int tl = target.length();

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/PlainTextDictionary.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/PlainTextDictionary.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/PlainTextDictionary.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/PlainTextDictionary.java Fri Jan 18 18:30:54 2013
@@ -63,6 +63,7 @@ public class PlainTextDictionary impleme
     in = new BufferedReader(reader);
   }
 
+  @Override
   public BytesRefIterator getWordsIterator() throws IOException {
     return new FileIterator();
   }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SpellChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SpellChecker.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SpellChecker.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SpellChecker.java Fri Jan 18 18:30:54 2013
@@ -635,6 +635,7 @@ public class SpellChecker implements jav
    * @throws IOException if the close operation causes an {@link IOException}
    * @throws AlreadyClosedException if the {@link SpellChecker} is already closed
    */
+  @Override
   public void close() throws IOException {
     synchronized (searcherLock) {
       ensureOpen();

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordFrequencyComparator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordFrequencyComparator.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordFrequencyComparator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordFrequencyComparator.java Fri Jan 18 18:30:54 2013
@@ -31,6 +31,7 @@ public class SuggestWordFrequencyCompara
    */
   public SuggestWordFrequencyComparator() {}
 
+  @Override
   public int compare(SuggestWord first, SuggestWord second) {
     // first criteria: the frequency
     if (first.freq > second.freq) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordScoreComparator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordScoreComparator.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordScoreComparator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/SuggestWordScoreComparator.java Fri Jan 18 18:30:54 2013
@@ -31,6 +31,7 @@ public class SuggestWordScoreComparator 
    */
   public SuggestWordScoreComparator() {}
 
+  @Override
   public int compare(SuggestWord first, SuggestWord second) {
     // first criteria: the distance
     if (first.score > second.score) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/TermFreqIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/TermFreqIterator.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/TermFreqIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/TermFreqIterator.java Fri Jan 18 18:30:54 2013
@@ -46,10 +46,12 @@ public interface TermFreqIterator extend
       this.wrapped = wrapped;
     }
 
+    @Override
     public long weight() {
       return 1;
     }
 
+    @Override
     public BytesRef next() throws IOException {
       return wrapped.next();
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/WordBreakSpellChecker.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/WordBreakSpellChecker.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/WordBreakSpellChecker.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/spell/WordBreakSpellChecker.java Fri Jan 18 18:30:54 2013
@@ -180,35 +180,32 @@ public class WordBreakSpellChecker {
         queueInitialCapacity, queueComparator);
     
     int thisTimeEvaluations = 0;
-    BytesRef reuse = new BytesRef();
     for (int i = 0; i < terms.length - 1; i++) {
       if (terms[i].equals(SEPARATOR_TERM)) {
         continue;
-      }
-      
-      int byteLength = terms[i].bytes().length;
-      if (byteLength > maxCombineWordLength) {
-        continue;
-      }
-      
-      reuse.grow(byteLength);
-      reuse.length = byteLength;
-      System.arraycopy(terms[i].bytes().bytes, terms[i].bytes().offset,
-          reuse.bytes, 0, byteLength);
-      
+      }      
+      String leftTermText = terms[i].text();
+      int leftTermLength = leftTermText.codePointCount(0, leftTermText.length());
+      if (leftTermLength > maxCombineWordLength) {
+       continue;
+      } 
       int maxFreq = 0;
       int minFreq = Integer.MAX_VALUE;
       if (origFreqs != null) {
         maxFreq = origFreqs[i];
         minFreq = origFreqs[i];
-      }
-      
+      } 
+      String combinedTermText = leftTermText;
+      int combinedLength = leftTermLength;
       for (int j = i + 1; j < terms.length && j - i <= maxChanges; j++) {
         if (terms[j].equals(SEPARATOR_TERM)) {
           break;
         }
-        byteLength += terms[j].bytes().length;
-        if (byteLength > maxCombineWordLength) {
+        String rightTermText = terms[j].text();
+        int rightTermLength = rightTermText.codePointCount(0, rightTermText.length());
+        combinedTermText += rightTermText;
+        combinedLength +=rightTermLength;
+        if (combinedLength > maxCombineWordLength) {
           break;
         }
         
@@ -216,13 +213,8 @@ public class WordBreakSpellChecker {
           maxFreq = Math.max(maxFreq, origFreqs[j]);
           minFreq = Math.min(minFreq, origFreqs[j]);
         }
-        
-        reuse.grow(byteLength);
-        System.arraycopy(terms[j].bytes().bytes, terms[j].bytes().offset,
-            reuse.bytes, reuse.length, terms[j].bytes().length);
-        reuse.length = byteLength;
-        
-        Term combinedTerm = new Term(terms[0].field(), reuse);
+                
+        Term combinedTerm = new Term(terms[0].field(), combinedTermText);
         int combinedTermFreq = ir.docFreq(combinedTerm);
         
         if (suggestMode != SuggestMode.SUGGEST_MORE_POPULAR
@@ -268,24 +260,25 @@ public class WordBreakSpellChecker {
       SuggestWord[] prefix, Queue<SuggestWordArrayWrapper> suggestions,
       int totalEvaluations, BreakSuggestionSortMethod sortMethod)
       throws IOException {
-    int termLength = term.bytes().length;
+    String termText = term.text();
+    int termLength = termText.codePointCount(0, termText.length());
     int useMinBreakWordLength = minBreakWordLength;
     if (useMinBreakWordLength < 1) {
       useMinBreakWordLength = 1;
     }
-    if (termLength <= (useMinBreakWordLength * 2)) {
+    if (termLength < (useMinBreakWordLength * 2)) {
       return 0;
-    }
+    }    
     
     int thisTimeEvaluations = 0;
-    BytesRef termBytes = term.bytes().clone();
-    for (int i = useMinBreakWordLength; i < (termLength - useMinBreakWordLength); i++) {
-      SuggestWord leftWord = generateSuggestWord(ir, termBytes, 0, i, term
-          .field());
+    for (int i = useMinBreakWordLength; i <= (termLength - useMinBreakWordLength); i++) {
+      int end = termText.offsetByCodePoints(0, i);
+      String leftText = termText.substring(0, end);
+      String rightText = termText.substring(end);
+      SuggestWord leftWord = generateSuggestWord(ir, term.field(), leftText);
       
       if (leftWord.freq >= useMinSuggestionFrequency) {
-        SuggestWord rightWord = generateSuggestWord(ir, termBytes, i,
-            termLength - i, term.field());
+        SuggestWord rightWord = generateSuggestWord(ir, term.field(), rightText);
         if (rightWord.freq >= useMinSuggestionFrequency) {
           SuggestWordArrayWrapper suggestion = new SuggestWordArrayWrapper(
               newSuggestion(prefix, leftWord, rightWord));
@@ -293,8 +286,7 @@ public class WordBreakSpellChecker {
           if (suggestions.size() > maxSuggestions) {
             suggestions.poll();
           }
-        }
-        
+        }        
         int newNumberBreaks = numberBreaks + 1;
         if (newNumberBreaks <= maxChanges) {
           int evaluations = generateBreakUpSuggestions(new Term(term.field(),
@@ -304,6 +296,7 @@ public class WordBreakSpellChecker {
           totalEvaluations += evaluations;
         }
       }
+      
       thisTimeEvaluations++;
       totalEvaluations++;
       if (totalEvaluations >= maxEvaluations) {
@@ -338,16 +331,13 @@ public class WordBreakSpellChecker {
     return newSuggestion;
   }
   
-  private SuggestWord generateSuggestWord(IndexReader ir, BytesRef bytes,
-      int offset, int length, String fieldname) throws IOException {
-    bytes.offset = offset;
-    bytes.length = length;
-    Term term = new Term(fieldname, bytes);
+  private SuggestWord generateSuggestWord(IndexReader ir, String fieldname, String text) throws IOException {
+    Term term = new Term(fieldname, text);
     int freq = ir.docFreq(term);
     SuggestWord word = new SuggestWord();
     word.freq = freq;
     word.score = 1;
-    word.string = term.text();
+    word.string = text;
     return word;
   }
   

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/BufferingTermFreqIteratorWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/BufferingTermFreqIteratorWrapper.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/BufferingTermFreqIteratorWrapper.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/BufferingTermFreqIteratorWrapper.java Fri Jan 18 18:30:54 2013
@@ -53,6 +53,7 @@ public class BufferingTermFreqIteratorWr
    
   }
 
+  @Override
   public long weight() {
     return freqs[curPos];
   }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/FileDictionary.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/FileDictionary.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/FileDictionary.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/FileDictionary.java Fri Jan 18 18:30:54 2013
@@ -57,6 +57,7 @@ public class FileDictionary implements D
     in = new BufferedReader(reader);
   }
 
+  @Override
   public TermFreqIterator getWordsIterator() {
     return new FileIterator();
   }
@@ -66,6 +67,7 @@ public class FileDictionary implements D
     private final BytesRef spare = new BytesRef();
     
    
+    @Override
     public long weight() {
       return curFreq;
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/Lookup.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/Lookup.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/Lookup.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/Lookup.java Fri Jan 18 18:30:54 2013
@@ -56,6 +56,7 @@ public abstract class Lookup {
     }
 
     /** Compare alphabetically. */
+    @Override
     public int compareTo(LookupResult o) {
       return CHARSEQUENCE_COMPARATOR.compare(key, o.key);
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingSuggester.java Fri Jan 18 18:30:54 2013
@@ -587,7 +587,7 @@ public class AnalyzingSuggester extends 
 
       //System.out.println("  prefixPaths: " + prefixPaths.size());
 
-      BytesReader bytesReader = fst.getBytesReader(0);
+      BytesReader bytesReader = fst.getBytesReader();
 
       FST.Arc<Pair<Long,BytesRef>> scratchArc = new FST.Arc<Pair<Long,BytesRef>>();
 
@@ -799,6 +799,7 @@ public class AnalyzingSuggester extends 
   }
    
   static final Comparator<Pair<Long,BytesRef>> weightComparator = new Comparator<Pair<Long,BytesRef>> () {
+    @Override
     public int compare(Pair<Long,BytesRef> left, Pair<Long,BytesRef> right) {
       return left.output1.compareTo(right.output1);
     }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FSTUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FSTUtil.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FSTUtil.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/FSTUtil.java Fri Jan 18 18:30:54 2013
@@ -77,7 +77,7 @@ public class FSTUtil {
         new IntsRef()));
     
     final FST.Arc<T> scratchArc = new FST.Arc<T>();
-    final FST.BytesReader fstReader = fst.getBytesReader(0);
+    final FST.BytesReader fstReader = fst.getBytesReader();
     
     while (queue.size() != 0) {
       final Path<T> path = queue.remove(queue.size() - 1);

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/ExternalRefSorter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/ExternalRefSorter.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/ExternalRefSorter.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/ExternalRefSorter.java Fri Jan 18 18:30:54 2013
@@ -52,6 +52,7 @@ public class ExternalRefSorter implement
     writer.write(utf8);
   }
   
+  @Override
   public BytesRefIterator iterator() throws IOException {
     if (sorted == null) {
       closeWriter();

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletion.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletion.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletion.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletion.java Fri Jan 18 18:30:54 2013
@@ -58,6 +58,7 @@ public class FSTCompletion {
     }
 
     /** @see BytesRef#compareTo(BytesRef) */
+    @Override
     public int compareTo(Completion o) {
       return this.utf8.compareTo(o.utf8);
     }
@@ -138,7 +139,7 @@ public class FSTCompletion {
     try {
       List<Arc<Object>> rootArcs = new ArrayList<Arc<Object>>();
       Arc<Object> arc = automaton.getFirstArc(new Arc<Object>());
-      FST.BytesReader fstReader = automaton.getBytesReader(0);
+      FST.BytesReader fstReader = automaton.getBytesReader();
       automaton.readFirstTargetArc(arc, arc, fstReader);
       while (true) {
         rootArcs.add(new Arc<Object>().copyFrom(arc));
@@ -172,7 +173,7 @@ public class FSTCompletion {
     // Get the UTF-8 bytes representation of the input key.
     try {
       final FST.Arc<Object> scratch = new FST.Arc<Object>();
-      FST.BytesReader fstReader = automaton.getBytesReader(0);
+      FST.BytesReader fstReader = automaton.getBytesReader();
       for (; rootArcIndex < rootArcs.length; rootArcIndex++) {
         final FST.Arc<Object> rootArc = rootArcs[rootArcIndex];
         final FST.Arc<Object> arc = scratch.copyFrom(rootArc);
@@ -337,7 +338,7 @@ public class FSTCompletion {
     final int max = utf8.offset + utf8.length;
     // Cannot save as instance var since multiple threads
     // can use FSTCompletion at once...
-    final FST.BytesReader fstReader = automaton.getBytesReader(0);
+    final FST.BytesReader fstReader = automaton.getBytesReader();
     for (int i = utf8.offset; i < max; i++) {
       if (automaton.findTargetArc(utf8.bytes[i] & 0xff, arc, arc, fstReader) == null) {
         // No matching prefixes, return an empty result.
@@ -361,7 +362,7 @@ public class FSTCompletion {
     }
     assert output.offset == 0;
     output.bytes[output.length++] = (byte) arc.label;
-    FST.BytesReader fstReader = automaton.getBytesReader(0);
+    FST.BytesReader fstReader = automaton.getBytesReader();
     automaton.readFirstTargetArc(arc, arc, fstReader);
     while (true) {
       if (arc.label == FST.END_LABEL) {

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletionBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletionBuilder.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletionBuilder.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/FSTCompletionBuilder.java Fri Jan 18 18:30:54 2013
@@ -24,6 +24,7 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefIterator;
 import org.apache.lucene.util.IntsRef;
 import org.apache.lucene.util.fst.*;
+import org.apache.lucene.util.packed.PackedInts;
 
 /**
  * Finite state automata based implementation of "autocomplete" functionality.
@@ -237,7 +238,8 @@ public class FSTCompletionBuilder {
     final Object empty = outputs.getNoOutput();
     final Builder<Object> builder = new Builder<Object>(
         FST.INPUT_TYPE.BYTE1, 0, 0, true, true, 
-        shareMaxTailLength, outputs, null, false);
+        shareMaxTailLength, outputs, null, false, 
+        PackedInts.DEFAULT, true, 15);
     
     BytesRef scratch = new BytesRef();
     BytesRef entry;

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/Sort.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/Sort.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/Sort.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/Sort.java Fri Jan 18 18:30:54 2013
@@ -344,6 +344,7 @@ public final class Sort {
     ByteSequencesWriter out = new ByteSequencesWriter(outputFile);
 
     PriorityQueue<FileAndTop> queue = new PriorityQueue<FileAndTop>(merges.size()) {
+      @Override
       protected boolean lessThan(FileAndTop a, FileAndTop b) {
         return comparator.compare(a.current, b.current) < 0;
       }

Modified: lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java?rev=1435287&r1=1435286&r2=1435287&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/suggest/src/java/org/apache/lucene/search/suggest/fst/WFSTCompletionLookup.java Fri Jan 18 18:30:54 2013
@@ -200,7 +200,7 @@ public class WFSTCompletionLookup extend
   private Long lookupPrefix(BytesRef scratch, Arc<Long> arc) throws /*Bogus*/IOException {
     assert 0 == fst.outputs.getNoOutput().longValue();
     long output = 0;
-    BytesReader bytesReader = fst.getBytesReader(0);
+    BytesReader bytesReader = fst.getBytesReader();
     
     fst.getFirstArc(arc);
     
@@ -278,6 +278,7 @@ public class WFSTCompletionLookup extend
   }
   
   static final Comparator<Long> weightComparator = new Comparator<Long> () {
+    @Override
     public int compare(Long left, Long right) {
       return left.compareTo(right);
     }