You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by do...@apache.org on 2009/07/29 20:04:24 UTC

svn commit: r798995 [19/35] - in /incubator/lucene.net/trunk/C#/src: Lucene.Net/ Lucene.Net/Analysis/ Lucene.Net/Analysis/Standard/ Lucene.Net/Document/ Lucene.Net/Index/ Lucene.Net/QueryParser/ Lucene.Net/Search/ Lucene.Net/Search/Function/ Lucene.Net...

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hits.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Hits.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hits.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hits.cs Wed Jul 29 18:04:12 2009
@@ -37,7 +37,20 @@
 	/// is thrown when accessing hit <code>n</code> &ge; current_{@link #Length()} 
 	/// (but <code>n</code> &lt; {@link #Length()}_at_start). 
 	/// </summary>
-	public sealed class Hits
+    ///
+	///  <pre>
+	///    TopDocCollector collector = new TopDocCollector(hitsPerPage);
+	///    searcher.search(query, collector);
+	///    ScoreDoc[] hits = collector.topDocs().scoreDocs;
+	///    for (int i = 0; i < hits.length; i++) {
+	///      int docId = hits[i].doc;
+	///      Document d = searcher.doc(docId);
+	///      // do something with current hit
+	///      ...
+	///  </pre>
+    /// 
+	[System.Obsolete("Hits will be removed in Lucene 3.0.  Insead used TopDocCollector and TopDocs.")]
+    public sealed class Hits
 	{
 		private Weight weight;
 		private Searcher searcher;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/IndexSearcher.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/IndexSearcher.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/IndexSearcher.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/IndexSearcher.cs Wed Jul 29 18:04:12 2009
@@ -169,17 +169,41 @@
 		// inherit javadoc
 		public override void  Search(Weight weight, Filter filter, HitCollector results)
 		{
-			HitCollector collector = results;
-			if (filter != null)
-			{
-				System.Collections.BitArray bits = filter.Bits(reader);
-				collector = new AnonymousClassHitCollector(bits, results, this);
-			}
-			
-			Scorer scorer = weight.Scorer(reader);
-			if (scorer == null)
-				return ;
-			scorer.Score(collector);
+            Scorer scorer = weight.Scorer(reader);
+            if (scorer == null)
+                return;
+
+            if (filter == null)
+            {
+                scorer.Score(results);
+                return;
+            }
+
+            DocIdSetIterator filterDocIdIterator = filter.GetDocIdSet(reader).Iterator(); // CHECKME: use ConjunctionScorer here?
+
+            bool more = filterDocIdIterator.Next() && scorer.SkipTo(filterDocIdIterator.Doc());
+
+            while (more)
+            {
+                int filterDocId = filterDocIdIterator.Doc();
+                if (filterDocId > scorer.Doc() && !scorer.SkipTo(filterDocId))
+                {
+                    more = false;
+                }
+                else
+                {
+                    int scorerDocId = scorer.Doc();
+                    if (scorerDocId == filterDocId) // permitted by filter
+                    {
+                        results.Collect(scorerDocId, scorer.Score());
+                        more = filterDocIdIterator.Next();
+                    }
+                    else
+                    {
+                        more = filterDocIdIterator.SkipTo(scorerDocId);
+                    }
+                }
+            }
 		}
 		
 		public override Query Rewrite(Query original)

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MatchAllDocsQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/MatchAllDocsQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MatchAllDocsQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MatchAllDocsQuery.cs Wed Jul 29 18:04:12 2009
@@ -23,15 +23,12 @@
 namespace Lucene.Net.Search
 {
 	
-	/// <summary> A query that matches all documents.
-	/// 
+	/// <summary>
+    /// A query that matches all documents.
 	/// </summary>
-	/// <author>  John Wang
-	/// </author>
 	[Serializable]
 	public class MatchAllDocsQuery : Query
 	{
-		
 		public MatchAllDocsQuery()
 		{
 		}
@@ -190,7 +187,7 @@
 			return buffer.ToString();
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is MatchAllDocsQuery))
 				return false;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiPhraseQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/MultiPhraseQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiPhraseQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiPhraseQuery.cs Wed Jul 29 18:04:12 2009
@@ -32,12 +32,7 @@
 	/// add(Term) on the term "Microsoft", then find all terms that have "app" as
 	/// prefix using IndexReader.terms(Term), and use MultiPhraseQuery.add(Term[]
 	/// terms) to add them to the query.
-	/// 
 	/// </summary>
-	/// <author>  Anders Nielsen
-	/// </author>
-	/// <version>  1.0
-	/// </version>
 	[Serializable]
 	public class MultiPhraseQuery : Query
 	{
@@ -102,7 +97,7 @@
 			
 			for (int i = 0; i < terms.Length; i++)
 			{
-				if ((System.Object) terms[i].Field() != (System.Object) field)
+				if ((object) terms[i].Field() != (object) field)
 				{
 					throw new System.ArgumentException("All phrase terms must be in the same field (" + field + "): " + terms[i]);
 				}
@@ -368,7 +363,7 @@
 		
 		
 		/// <summary>Returns true if <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is MultiPhraseQuery))
 				return false;
@@ -401,4 +396,4 @@
             return BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0) ^ slop ^ termArrays.GetHashCode() ^ positions.GetHashCode() ^ 0x4AC65113;
 		}
 	}
-}
+}
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiTermQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/MultiTermQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiTermQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/MultiTermQuery.cs Wed Jul 29 18:04:12 2009
@@ -95,7 +95,7 @@
 			return buffer.ToString();
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ParallelMultiSearcher.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ParallelMultiSearcher.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ParallelMultiSearcher.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ParallelMultiSearcher.cs Wed Jul 29 18:04:12 2009
@@ -98,7 +98,7 @@
 				{
 					msta[i].Join();
 				}
-				catch (System.Threading.ThreadInterruptedException ie)
+				catch (System.Threading.ThreadInterruptedException)
 				{
 					; // TODO: what should we do with this???
 				}
@@ -150,7 +150,7 @@
 				{
 					msta[i].Join();
 				}
-				catch (System.Threading.ThreadInterruptedException ie)
+				catch (System.Threading.ThreadInterruptedException)
 				{
 					; // TODO: what should we do with this???
 				}
@@ -177,8 +177,7 @@
 		
 		/// <summary>Lower-level search API.
 		/// 
-		/// <p>{@link HitCollector#Collect(int,float)} is called for every non-zero
-		/// scoring document.
+		/// <p>{@link HitCollector#Collect(int,float)} is called for every matching document.
 		/// 
 		/// <p>Applications should only use this if they need <i>all</i> of the
 		/// matching documents.  The high-level search API ({@link

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/BoostingTermQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Payload/BoostingTermQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/BoostingTermQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/BoostingTermQuery.cs Wed Jul 29 18:04:12 2009
@@ -88,7 +88,7 @@
 				return new BoostingSpanScorer(this, (TermSpans) query.GetSpans(reader), this, similarity, reader.Norms(query.GetField()));
 			}
 			
-			internal class BoostingSpanScorer : SpanScorer
+			protected internal class BoostingSpanScorer : SpanScorer
 			{
 				private void  InitBlock(BoostingTermWeight enclosingInstance)
 				{
@@ -163,7 +163,7 @@
 				
 				public override Explanation Explain(int doc)
 				{
-					Explanation result = new Explanation();
+					ComplexExplanation result = new ComplexExplanation();
 					Explanation nonPayloadExpl = base.Explain(doc);
 					result.AddDetail(nonPayloadExpl);
 					//QUESTION: Is there a wau to avoid this skipTo call?  We need to know whether to load the payload or not
@@ -181,13 +181,14 @@
 					payloadBoost.SetDescription("scorePayload(...)");
 					result.SetValue(nonPayloadExpl.GetValue() * avgPayloadScore);
 					result.SetDescription("btq, product of:");
+                    result.SetMatch(nonPayloadExpl.GetValue() == 0 ? false : true); // LUCENE-1303
 					return result;
 				}
 			}
 		}
 		
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is BoostingTermQuery))
 				return false;

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/PayloadSpanUtil.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Payload/PayloadSpanUtil.cs?rev=798995&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/PayloadSpanUtil.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Payload/PayloadSpanUtil.cs Wed Jul 29 18:04:12 2009
@@ -0,0 +1,213 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using Term = Lucene.Net.Index.Term;
+using BooleanClause = Lucene.Net.Search.BooleanClause;
+using BooleanQuery = Lucene.Net.Search.BooleanQuery;
+using DisjunctionMaxQuery = Lucene.Net.Search.DisjunctionMaxQuery;
+using FilteredQuery = Lucene.Net.Search.FilteredQuery;
+using MultiPhraseQuery = Lucene.Net.Search.MultiPhraseQuery;
+using PhraseQuery = Lucene.Net.Search.PhraseQuery;
+using Query = Lucene.Net.Search.Query;
+using TermQuery = Lucene.Net.Search.TermQuery;
+using PayloadSpans = Lucene.Net.Search.Spans.PayloadSpans;
+using SpanNearQuery = Lucene.Net.Search.Spans.SpanNearQuery;
+using SpanOrQuery = Lucene.Net.Search.Spans.SpanOrQuery;
+using SpanQuery = Lucene.Net.Search.Spans.SpanQuery;
+using SpanTermQuery = Lucene.Net.Search.Spans.SpanTermQuery;
+
+using System.Collections.Generic;
+
+namespace Lucene.Net.Search.Payloads
+{
+    /// <summary>
+    /// Experimental class to get set of payloads for most standard Lucene queries.
+    /// Operates like Highlighter - IndexReader should only contain doc of interest,
+    /// best to use MemoryIndex.
+    /// 
+    /// <p/>
+    /// <font color="#FF0000">
+    /// WARNING: The status of the <b>Payloads</b> feature is experimental.
+    /// The APIs introduced here might change in the future and will not be
+    /// supported anymore in such a case.</font>
+    /// 
+    /// </summary>
+    public class PayloadSpanUtil
+    {
+        private IndexReader reader;
+
+        /// <summary>
+        /// @param reader
+        /// that contains doc with payloads to extract
+        /// </summary>
+        public PayloadSpanUtil(IndexReader reader)
+        {
+            this.reader = reader;
+        }
+
+        /// <summary>
+        /// Query should be rewritten for wild/fuzzy support.
+        /// 
+        /// @param query
+        /// @return payloads Collection
+        /// @throws IOException
+        /// </summary>
+        public ICollection<byte[]> GetPayloadsForQuery(Query query)
+        {
+            ICollection<byte[]> payloads = new List<byte[]>();
+            QueryToSpanQuery(query, payloads);
+            return payloads;
+        }
+
+        private void QueryToSpanQuery(Query query, ICollection<byte[]> payloads)
+        {
+            if (query is BooleanQuery)
+            {
+                BooleanClause[] queryClauses = ((BooleanQuery)query).GetClauses();
+
+                for (int i = 0; i < queryClauses.Length; i++)
+                {
+                    if (!queryClauses[i].IsProhibited())
+                    {
+                        QueryToSpanQuery(queryClauses[i].GetQuery(), payloads);
+                    }
+                }
+            }
+            else if (query is PhraseQuery)
+            {
+                Term[] phraseQueryTerms = ((PhraseQuery)query).GetTerms();
+                SpanQuery[] clauses = new SpanQuery[phraseQueryTerms.Length];
+                for (int i = 0; i < phraseQueryTerms.Length; i++)
+                {
+                    clauses[i] = new SpanTermQuery(phraseQueryTerms[i]);
+                }
+
+                int slop = ((PhraseQuery)query).GetSlop();
+                bool inorder = false;
+
+                if (slop == 0)
+                {
+                    inorder = true;
+                }
+
+                SpanNearQuery sp = new SpanNearQuery(clauses, slop, inorder);
+                sp.SetBoost(query.GetBoost());
+                GetPayloads(payloads, sp);
+            }
+            else if (query is TermQuery)
+            {
+                SpanTermQuery stq = new SpanTermQuery(((TermQuery)query).GetTerm());
+                stq.SetBoost(query.GetBoost());
+                GetPayloads(payloads, stq);
+            }
+            else if (query is SpanQuery)
+            {
+                GetPayloads(payloads, (SpanQuery)query);
+            }
+            else if (query is FilteredQuery)
+            {
+                QueryToSpanQuery(((FilteredQuery)query).GetQuery(), payloads);
+            }
+            else if (query is DisjunctionMaxQuery)
+            {
+                for (System.Collections.IEnumerator iterator = ((DisjunctionMaxQuery)query).Iterator(); iterator.MoveNext(); )
+                {
+                    QueryToSpanQuery((Query)iterator.Current, payloads);
+                }
+            }
+            else if (query is MultiPhraseQuery)
+            {
+                MultiPhraseQuery mpq = (MultiPhraseQuery)query;
+                System.Collections.IList termArrays = mpq.GetTermArrays();
+                int[] positions = mpq.GetPositions();
+                if (positions.Length > 0)
+                {
+                    int maxPosition = positions[positions.Length - 1];
+                    for (int i = 0; i < positions.Length - 1; ++i)
+                    {
+                        if (positions[i] > maxPosition)
+                        {
+                            maxPosition = positions[i];
+                        }
+                    }
+
+                    System.Collections.ArrayList[] disjunctLists = new System.Collections.ArrayList[maxPosition + 1];
+                    int distinctPositions = 0;
+
+                    for (int i = 0; i < termArrays.Count; ++i)
+                    {
+                        Term[] termArray = (Term[])termArrays[i];
+                        System.Collections.ArrayList disjuncts = disjunctLists[positions[i]];
+                        if (disjuncts == null)
+                        {
+                            disjuncts = (disjunctLists[positions[i]] = new System.Collections.ArrayList(termArray.Length));
+                            ++distinctPositions;
+                        }
+                        for (int j = 0; j < termArray.Length; ++j)
+                        {
+                            disjuncts.Add(new SpanTermQuery(termArray[j]));
+                        }
+                    }
+
+                    int positionGaps = 0;
+                    int position = 0;
+                    SpanQuery[] clauses = new SpanQuery[distinctPositions];
+                    for (int i = 0; i < disjunctLists.Length; ++i)
+                    {
+                        System.Collections.ArrayList disjuncts = disjunctLists[i];
+                        if (disjuncts != null)
+                        {
+                            clauses[position++] = new SpanOrQuery((SpanQuery[])(disjuncts.ToArray(typeof (SpanQuery[]))));
+                        }
+                        else
+                        {
+                            ++positionGaps;
+                        }
+                    }
+
+                    int slop = mpq.GetSlop();
+                    bool inorder = (slop == 0);
+
+                    SpanNearQuery sp = new SpanNearQuery(clauses, slop + positionGaps, inorder);
+                    sp.SetBoost(query.GetBoost());
+                    GetPayloads(payloads, sp);
+                }
+            }
+        }
+
+        private void GetPayloads(ICollection<byte[]> payloads, SpanQuery query)
+        {
+            PayloadSpans spans = query.GetPayloadSpans(reader);
+
+            while (spans.Next() == true)
+            {
+                if (spans.IsPayloadAvailable())
+                {
+                    ICollection<byte[]> payload = spans.GetPayload();
+                    IEnumerator<byte[]> it = payload.GetEnumerator();
+                    while (it.MoveNext())
+                    {
+                        byte[] bytes = it.Current;
+                        payloads.Add(bytes);
+                    }
+                }
+            }
+        }
+
+    }
+}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PhraseQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQuery.cs Wed Jul 29 18:04:12 2009
@@ -34,8 +34,9 @@
 	public class PhraseQuery : Query
 	{
 		private System.String field;
-		private System.Collections.ArrayList terms = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
-		private System.Collections.ArrayList positions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
+		private System.Collections.ArrayList terms = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(4));
+		private System.Collections.ArrayList positions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(4));
+        private int maxPosition = 0;
 		private int slop = 0;
 		
 		/// <summary>Constructs an empty phrase query. </summary>
@@ -97,7 +98,9 @@
 			}
 			
 			terms.Add(term);
-			positions.Add((System.Int32) position);
+			positions.Add(position);
+            if (position > maxPosition)
+                maxPosition = position;
 		}
 		
 		/// <summary>Returns the set of terms in this phrase. </summary>
@@ -298,34 +301,51 @@
 		public override System.String ToString(System.String f)
 		{
 			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
-			if (!field.Equals(f))
+			if (field != null && !field.Equals(f))
 			{
 				buffer.Append(field);
 				buffer.Append(":");
 			}
 			
 			buffer.Append("\"");
+            string[] pieces = new string[maxPosition + 1];
 			for (int i = 0; i < terms.Count; i++)
 			{
-				buffer.Append(((Term) terms[i]).Text());
-				if (i != terms.Count - 1)
-					buffer.Append(" ");
-			}
+                int pos = (int) positions[i];
+                string s = pieces[pos];
+                if (s == null)
+                {
+                    s = ((Term)terms[i]).Text();
+                }
+                else
+                {
+                    s = s + "|" + ((Term)terms[i]).Text();
+                }
+                pieces[pos] = s;
+            }
+            for (int i = 0; i < pieces.Length; i++)
+            {
+                if (i > 0)
+                    buffer.Append(' ');
+
+                string s = pieces[i];
+                if (s == null)
+                    buffer.Append('?');
+                else
+                    buffer.Append(s);
+            }
 			buffer.Append("\"");
-			
-			if (slop != 0)
-			{
-				buffer.Append("~");
-				buffer.Append(slop);
-			}
-			
-			buffer.Append(ToStringUtils.Boost(GetBoost()));
-			
-			return buffer.ToString();
-		}
+
+            if (slop != 0)
+                buffer.Append("~").Append(slop);
+
+            buffer.Append(ToStringUtils.Boost(GetBoost()));
+
+            return buffer.ToString();
+        }
 		
         /// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-        public  override bool Equals(System.Object o)
+        public  override bool Equals(object o)
         {
             if (!(o is PhraseQuery))
                 return false;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQueue.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PhraseQueue.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQueue.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseQueue.cs Wed Jul 29 18:04:12 2009
@@ -29,7 +29,7 @@
 			Initialize(size);
 		}
 		
-		public override bool LessThan(System.Object o1, System.Object o2)
+		public override bool LessThan(object o1, object o2)
 		{
 			PhrasePositions pp1 = (PhrasePositions) o1;
 			PhrasePositions pp2 = (PhrasePositions) o2;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PrefixFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixFilter.cs Wed Jul 29 18:04:12 2009
@@ -17,6 +17,7 @@
 
 using System;
 
+using OpenBitSet = Lucene.Net.Util.OpenBitSet;
 using Term = Lucene.Net.Index.Term;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using TermEnum = Lucene.Net.Index.TermEnum;
@@ -57,8 +58,35 @@
 				bitSet.Set(doc, true);
 			}
 		}
-		
-		protected internal Term prefix;
+
+        private class AnonymousClassPrefixGenerator2 : PrefixGenerator
+        {
+            private void InitBlock(OpenBitSet bitSet, PrefixFilter enclosingInstance)
+            {
+                this.bitSet = bitSet;
+                this.enclosingInstance = enclosingInstance;
+            }
+            private OpenBitSet bitSet;
+            private PrefixFilter enclosingInstance;
+            public PrefixFilter Enclosing_Instance
+            {
+                get
+                {
+                    return enclosingInstance;
+                }
+            }
+            internal AnonymousClassPrefixGenerator2(OpenBitSet bitSet, PrefixFilter enclosingInstance, Lucene.Net.Index.Term Param1)
+                : base(Param1)
+            {
+                InitBlock(bitSet, enclosingInstance);
+            }
+            public override void HandleDoc(int doc)
+            {
+                bitSet.Set(doc);
+            }
+        }
+
+        protected internal Term prefix;
 		
 		public PrefixFilter(Term prefix)
 		{
@@ -70,14 +98,22 @@
 			return prefix;
 		}
 		
+        [System.Obsolete()]
 		public override System.Collections.BitArray Bits(IndexReader reader)
 		{
 			System.Collections.BitArray bitSet = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
 			new AnonymousClassPrefixGenerator(bitSet, this, prefix).Generate(reader);
 			return bitSet;
 		}
-		
-		/// <summary>Prints a user-readable version of this query. </summary>
+
+        public override DocIdSet GetDocIdSet(IndexReader reader)
+        {
+            OpenBitSet bitSet = new OpenBitSet((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
+            new AnonymousClassPrefixGenerator2(bitSet, this, prefix).Generate(reader);
+            return bitSet;
+        }
+
+        /// <summary>Prints a user-readable version of this query. </summary>
 		public override System.String ToString()
 		{
 			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
@@ -120,7 +156,7 @@
 				do 
 				{
 					Term term = enumerator.Term();
-					if (term != null && term.Text().StartsWith(prefixText) && (System.Object) term.Field() == (System.Object) prefixField)
+					if (term != null && term.Text().StartsWith(prefixText) && (object) term.Field() == (object) prefixField)
 					// interned comparison
 					{
 						termDocs.Seek(term);

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PrefixQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PrefixQuery.cs Wed Jul 29 18:04:12 2009
@@ -98,7 +98,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is PrefixQuery))
 				return false;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Query.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Query.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Query.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Query.cs Wed Jul 29 18:04:12 2009
@@ -229,7 +229,7 @@
 		}
 		
 		/// <summary>Returns a clone of this query. </summary>
-		public virtual System.Object Clone()
+		public virtual object Clone()
 		{
 			try
 			{

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/QueryFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryFilter.cs Wed Jul 29 18:04:12 2009
@@ -43,7 +43,7 @@
 		{
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			return base.Equals((QueryFilter) o);
 		}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryTermVector.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/QueryTermVector.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryTermVector.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryTermVector.cs Wed Jul 29 18:04:12 2009
@@ -55,13 +55,13 @@
 				TokenStream stream = analyzer.TokenStream("", new System.IO.StringReader(queryString));
 				if (stream != null)
 				{
-					Token next = null;
 					System.Collections.ArrayList terms = new System.Collections.ArrayList();
 					try
 					{
-						while ((next = stream.Next()) != null)
-						{
-							terms.Add(next.TermText());
+                        Token reusableToken = new Token();
+                        for (Token nextToken = stream.Next(reusableToken); nextToken != null; nextToken = stream.Next(reusableToken))
+                        {
+							terms.Add(nextToken.Term());
 						}
 						ProcessTerms((System.String[]) terms.ToArray(typeof(System.String)));
 					}
@@ -85,7 +85,7 @@
 				for (int i = 0; i < queryTerms.Length; i++)
 				{
 					System.String term = queryTerms[i];
-					System.Object tmpPosition = tmpSet[term];
+					object tmpPosition = tmpSet[term];
 					if (tmpPosition == null)
 					{
 						tmpSet[term] = (System.Int32) j++;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryWrapperFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/QueryWrapperFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryWrapperFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/QueryWrapperFilter.cs Wed Jul 29 18:04:12 2009
@@ -17,6 +17,7 @@
 
 using System;
 
+using OpenBitSet = Lucene.Net.Util.OpenBitSet;
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search
@@ -63,7 +64,35 @@
 				bits.Set(doc, true);
 			}
 		}
-		private Query query;
+
+        private class AnonymousClassHitCollector2 : HitCollector
+        {
+            public AnonymousClassHitCollector2(OpenBitSet bits, QueryWrapperFilter enclosingInstance)
+            {
+                InitBlock(bits, enclosingInstance);
+            }
+            private void InitBlock(OpenBitSet bits, QueryWrapperFilter enclosingInstance)
+            {
+                this.bits = bits;
+                this.enclosingInstance = enclosingInstance;
+            }
+            private OpenBitSet bits;
+            private QueryWrapperFilter enclosingInstance;
+            public QueryWrapperFilter Enclosing_Instance
+            {
+                get
+                {
+                    return enclosingInstance;
+                }
+
+            }
+            public override void Collect(int doc, float score)
+            {
+                bits.Set(doc);
+            }
+        }
+
+        private Query query;
 		
 		/// <summary>Constructs a filter which only matches documents matching
 		/// <code>query</code>.
@@ -73,20 +102,27 @@
 			this.query = query;
 		}
 		
+        [System.Obsolete("Use getDocIdSet(IndexReader) instead.")]
 		public override System.Collections.BitArray Bits(IndexReader reader)
 		{
 			System.Collections.BitArray bits = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
-			
 			new IndexSearcher(reader).Search(query, new AnonymousClassHitCollector(bits, this));
 			return bits;
 		}
-		
-		public override System.String ToString()
+
+        public override DocIdSet GetDocIdSet(IndexReader reader)
+        {
+            OpenBitSet bits = new OpenBitSet((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
+            new IndexSearcher(reader).Search(query, new AnonymousClassHitCollector2(bits, this));
+            return bits;
+        }
+
+        public override System.String ToString()
 		{
 			return "QueryWrapperFilter(" + query + ")";
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (!(o is QueryWrapperFilter))
 				return false;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/RangeFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeFilter.cs Wed Jul 29 18:04:12 2009
@@ -16,11 +16,13 @@
  */
 
 using System;
+using CompareInfo = System.Globalization.CompareInfo;
 
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using TermDocs = Lucene.Net.Index.TermDocs;
 using TermEnum = Lucene.Net.Index.TermEnum;
+using OpenBitSet = Lucene.Net.Util.OpenBitSet;
 
 namespace Lucene.Net.Search
 {
@@ -42,6 +44,7 @@
 		private System.String upperTerm;
 		private bool includeLower;
 		private bool includeUpper;
+        private CompareInfo collator;
 		
 		/// <param name="fieldName">The field this range applies to
 		/// </param>
@@ -78,7 +81,26 @@
 				throw new System.ArgumentException("The upper bound must be non-null to be inclusive");
 			}
 		}
-		
+
+        /// <summary>
+        /// WARNING: Using this constructor and supplying a non-null
+        /// value in the collator paramter will cause every single
+        /// index Term in the Field referenced by lowerTerm and/or upperTerm
+        /// to be examined.  Depending on the number of index Terms in this 
+        /// Field, the operation could be very slow.
+        /// </summary>
+        /// <param name="fieldName"></param>
+        /// <param name="lowerTerm">lower bound</param>
+        /// <param name="upperTerm">upper bound</param>
+        /// <param name="includeLower">is lower bound inclusive</param>
+        /// <param name="includeUpper">is upper bound inclusive</param>
+        /// <param name="collator">the collator that determines range inclusion; when set to null Unicode code point ordering is used</param>
+        public RangeFilter(string fieldName, string lowerTerm, string upperTerm, bool includeLower, bool includeUpper, CompareInfo collator)
+            : this(fieldName, lowerTerm, upperTerm, includeLower, includeUpper)
+        {
+            this.collator = collator;
+        }
+
 		/// <summary> Constructs a filter for field <code>fieldName</code> matching
 		/// less than or equal to <code>upperTerm</code>.
 		/// </summary>
@@ -99,10 +121,15 @@
 		/// permitted in search results, and false for those that should
 		/// not.
 		/// </summary>
+        [Obsolete("use GetDocIdSet(IndexReader) instead")]
 		public override System.Collections.BitArray Bits(IndexReader reader)
 		{
-			System.Collections.BitArray bits = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
-			TermEnum enumerator = (null != lowerTerm ? reader.Terms(new Term(fieldName, lowerTerm)) : reader.Terms(new Term(fieldName, "")));
+			System.Collections.BitArray bits = new System.Collections.BitArray(
+                (reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
+
+			TermEnum enumerator = (null != lowerTerm && collator == null ?
+                reader.Terms(new Term(fieldName, lowerTerm)) : 
+                reader.Terms(new Term(fieldName)));
 			
 			try
 			{
@@ -111,49 +138,72 @@
 				{
 					return bits;
 				}
-				
-				bool checkLower = false;
-				if (!includeLower)
-					// make adjustments to set to exclusive
-					checkLower = true;
-				
-				TermDocs termDocs = reader.TermDocs();
-				try
-				{
-					
-					do 
-					{
-						Term term = enumerator.Term();
-						if (term != null && term.Field().Equals(fieldName))
-						{
-							if (!checkLower || null == lowerTerm || String.CompareOrdinal(term.Text(), lowerTerm) > 0)
-							{
-								checkLower = false;
-								if (upperTerm != null)
-								{
-									int compare = String.CompareOrdinal(upperTerm, term.Text());
-									/* if beyond the upper term, or is exclusive and
-									* this is equal to the upper term, break out */
-									if ((compare < 0) || (!includeUpper && compare == 0))
-									{
-										break;
-									}
-								}
-								/* we have a good term, find the docs */
-								
-								termDocs.Seek(enumerator.Term());
-								while (termDocs.Next())
-								{
-									bits.Set(termDocs.Doc(), true);
-								}
-							}
-						}
-						else
-						{
-							break;
-						}
-					}
-					while (enumerator.Next());
+
+                TermDocs termDocs = reader.TermDocs();
+                try
+                {
+                    if (collator != null)
+                    {
+                        do
+                        {
+                            Term term = enumerator.Term();
+                            if (term != null && term.Field().Equals(fieldName))
+                            {
+                                if ((lowerTerm == null ||
+                                    (includeLower ? collator.Compare(term.Text(), lowerTerm) >= 0 : collator.Compare(term.Text(), lowerTerm) > 0)) &&
+                                    (upperTerm == null ||
+                                    (includeUpper ? collator.Compare(term.Text(), upperTerm) <= 0 : collator.Compare(term.Text(), upperTerm) < 0)))
+                                {
+                                    // term in range, lookup docs
+                                    termDocs.Seek(enumerator.Term());
+                                    while (termDocs.Next())
+                                    {
+                                        bits.Set(termDocs.Doc(), true);
+                                    }
+                                }
+                            }
+                        }
+                        while (enumerator.Next());
+                    }
+                    else // null collator; using Unicode code point ordering
+                    {
+                        bool checkLower = false;
+                        if (!includeLower) // make adjustments to set to exclusive
+                            checkLower = true;
+                        do
+                        {
+                            Term term = enumerator.Term();
+                            if (term != null && term.Field().Equals(fieldName))
+                            {
+                                if (!checkLower || null == lowerTerm || String.CompareOrdinal(term.Text(), lowerTerm) > 0)
+                                {
+                                    checkLower = false;
+                                    if (upperTerm != null)
+                                    {
+                                        int compare = String.CompareOrdinal(upperTerm, term.Text());
+                                        /* if beyond the upper term, or is exclusive and
+                                        * this is equal to the upper term, break out */
+                                        if ((compare < 0) || (!includeUpper && compare == 0))
+                                        {
+                                            break;
+                                        }
+                                    }
+                                    /* we have a good term, find the docs */
+
+                                    termDocs.Seek(enumerator.Term());
+                                    while (termDocs.Next())
+                                    {
+                                        bits.Set(termDocs.Doc(), true);
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                break;
+                            }
+                        }
+                        while (enumerator.Next());
+                    }
 				}
 				finally
 				{
@@ -167,8 +217,106 @@
 			
 			return bits;
 		}
-		
-		public override System.String ToString()
+
+        /// <summary> Returns a DocIdSet with documents that should be
+        /// permitted in search results.
+        /// </summary>
+        public override DocIdSet GetDocIdSet(IndexReader reader)
+        {
+            OpenBitSet bits = new OpenBitSet(reader.MaxDoc());
+
+            TermEnum enumerator = (null != lowerTerm && collator == null ?
+                reader.Terms(new Term(fieldName, lowerTerm)) :
+                reader.Terms(new Term(fieldName)));
+
+            try
+            {
+
+                if (enumerator.Term() == null)
+                {
+                    return bits;
+                }
+
+                TermDocs termDocs = reader.TermDocs();
+                try
+                {
+                    if (collator != null)
+                    {
+                        do
+                        {
+                            Term term = enumerator.Term();
+                            if (term != null && term.Field().Equals(fieldName))
+                            {
+                                if ((lowerTerm == null ||
+                                    (includeLower ? collator.Compare(term.Text(), lowerTerm) >= 0 : collator.Compare(term.Text(), lowerTerm) > 0)) &&
+                                    (upperTerm == null ||
+                                    (includeUpper ? collator.Compare(term.Text(), upperTerm) <= 0 : collator.Compare(term.Text(), upperTerm) < 0)))
+                                {
+                                    // term in range, lookup docs
+                                    termDocs.Seek(enumerator.Term());
+                                    while (termDocs.Next())
+                                    {
+                                        bits.Set(termDocs.Doc());
+                                    }
+                                }
+                            }
+                        }
+                        while (enumerator.Next());
+                    }
+                    else // null collator; using Unicode code point ordering
+                    {
+                        bool checkLower = false;
+                        if (!includeLower) // make adjustments to set to exclusive
+                            checkLower = true;
+                        do
+                        {
+                            Term term = enumerator.Term();
+                            if (term != null && term.Field().Equals(fieldName))
+                            {
+                                if (!checkLower || null == lowerTerm || String.CompareOrdinal(term.Text(), lowerTerm) > 0)
+                                {
+                                    checkLower = false;
+                                    if (upperTerm != null)
+                                    {
+                                        int compare = String.CompareOrdinal(upperTerm, term.Text());
+                                        /* if beyond the upper term, or is exclusive and
+                                        * this is equal to the upper term, break out */
+                                        if ((compare < 0) || (!includeUpper && compare == 0))
+                                        {
+                                            break;
+                                        }
+                                    }
+                                    /* we have a good term, find the docs */
+
+                                    termDocs.Seek(enumerator.Term());
+                                    while (termDocs.Next())
+                                    {
+                                        bits.Set(termDocs.Doc());
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                break;
+                            }
+                        }
+                        while (enumerator.Next());
+                    }
+                }
+                finally
+                {
+                    termDocs.Close();
+                }
+            }
+            finally
+            {
+                enumerator.Close();
+            }
+
+            return bits;
+        }
+
+        public override System.String ToString()
 		{
 			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
 			buffer.Append(fieldName);
@@ -188,7 +336,7 @@
 		}
 		
 		/// <summary>Returns true if <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;
@@ -196,7 +344,10 @@
 				return false;
 			RangeFilter other = (RangeFilter) o;
 			
-			if (!this.fieldName.Equals(other.fieldName) || this.includeLower != other.includeLower || this.includeUpper != other.includeUpper)
+			if (!this.fieldName.Equals(other.fieldName) ||
+                this.includeLower != other.includeLower ||
+                this.includeUpper != other.includeUpper ||
+                (this.collator != null && !this.collator.Equals(other.collator)))
 			{
 				return false;
 			}
@@ -215,6 +366,7 @@
 			h = (h << 1) | (SupportClass.Number.URShift(h, 31)); // rotate to distinguish lower from upper
 			h ^= (upperTerm != null ? (upperTerm.GetHashCode()) : unchecked((int) 0x91BEC2C2));         // {{Aroush-1.9}} is this OK?!
 			h ^= (includeLower ? unchecked((int) 0xD484B933) : 0) ^ (includeUpper ? 0x6AE423AC : 0);    // {{Aroush-1.9}} is this OK?!
+            h ^= collator != null ? collator.GetHashCode() : 0;
 			return h;
 		}
 	}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/RangeQuery.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeQuery.cs Wed Jul 29 18:04:12 2009
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using CompareInfo = System.Globalization.CompareInfo;
 using Term = Lucene.Net.Index.Term;
 using TermEnum = Lucene.Net.Index.TermEnum;
 using IndexReader = Lucene.Net.Index.IndexReader;
@@ -24,7 +24,6 @@
 
 namespace Lucene.Net.Search
 {
-	
 	/// <summary> A Query that matches documents within an exclusive range. A RangeQuery
 	/// is built by QueryParser for input like <code>[010 TO 120]</code> but only if the QueryParser has 
 	/// the useOldRangeQuery property set to true. The QueryParser default behaviour is to use
@@ -37,18 +36,14 @@
 	/// 
 	/// 
 	/// </summary>
-	/// <seealso cref="ConstantScoreRangeQuery">
-	/// 
-	/// 
-	/// </seealso>
-	/// <version>  $Id: RangeQuery.java 520891 2007-03-21 13:58:47Z yonik $
-	/// </version>
+	/// <seealso cref="ConstantScoreRangeQuery"/>
 	[Serializable]
 	public class RangeQuery : Query
 	{
 		private Term lowerTerm;
 		private Term upperTerm;
 		private bool inclusive;
+        private CompareInfo collator;
 		
 		/// <summary>Constructs a query selecting all terms greater than
 		/// <code>lowerTerm</code> but less than <code>upperTerm</code>.
@@ -56,6 +51,9 @@
 		/// in which case there is no bound on that side, but if there are
 		/// two terms, both terms <b>must</b> be for the same field.
 		/// </summary>
+        /// <param name="lowerTerm">term at the lower end of the range</param>
+        /// <param name="upperTerm">term at the upper end of the range</param>
+        /// <param name="inclusive">if true, both lowerTerm and upperTerm will be included in the range</param>
 		public RangeQuery(Term lowerTerm, Term upperTerm, bool inclusive)
 		{
 			if (lowerTerm == null && upperTerm == null)
@@ -74,66 +72,110 @@
 			}
 			else
 			{
-				this.lowerTerm = new Term(upperTerm.Field(), "");
+				this.lowerTerm = new Term(upperTerm.Field());
 			}
 			
 			this.upperTerm = upperTerm;
 			this.inclusive = inclusive;
 		}
-		
+
+        public RangeQuery(Term lowerTerm, Term upperTerm, bool inclusive, CompareInfo collator)
+            : this(lowerTerm, upperTerm, inclusive)
+        {
+            this.collator = collator;
+        }
+
 		public override Query Rewrite(IndexReader reader)
 		{
 			
 			BooleanQuery query = new BooleanQuery(true);
-			TermEnum enumerator = reader.Terms(lowerTerm);
-			
-			try
-			{
-				
-				bool checkLower = false;
-				if (!inclusive)
-				// make adjustments to set to exclusive
-					checkLower = true;
-				
-				System.String testField = GetField();
-				
-				do 
-				{
-					Term term = enumerator.Term();
-					if (term != null && term.Field() == testField)
-					{
-						// interned comparison
-						if (!checkLower || String.CompareOrdinal(term.Text(), lowerTerm.Text()) > 0)
-						{
-							checkLower = false;
-							if (upperTerm != null)
-							{
-								int compare = String.CompareOrdinal(upperTerm.Text(), term.Text());
-								/* if beyond the upper term, or is exclusive and
-								* this is equal to the upper term, break out */
-								if ((compare < 0) || (!inclusive && compare == 0))
-									break;
-							}
-							TermQuery tq = new TermQuery(term); // found a match
-							tq.SetBoost(GetBoost()); // set the boost
-							query.Add(tq, BooleanClause.Occur.SHOULD); // add to query
-						}
-					}
-					else
-					{
-						break;
-					}
-				}
-				while (enumerator.Next());
-			}
-			finally
-			{
-				enumerator.Close();
-			}
+            string testField = GetField();
+            if (collator != null)
+            {
+                TermEnum enumerator = reader.Terms(new Term(testField, ""));
+                string lowerTermText = lowerTerm != null ? lowerTerm.Text() : null;
+                string upperTermText = upperTerm != null ? upperTerm.Text() : null;
+
+                try
+                {
+                    do
+                    {
+                        Term term = enumerator.Term();
+                        if (term != null && term.Field() == testField) // interned comparison
+                        {
+                            if ((lowerTermText == null ||
+                                (inclusive ? collator.Compare(term.Text(), lowerTermText) >= 0 : collator.Compare(term.Text(), lowerTermText) > 0))
+                                &&
+                                (upperTermText == null ||
+                                (inclusive ? collator.Compare(term.Text(), upperTermText) <= 0 : collator.Compare(term.Text(), upperTermText) < 0))
+                                )
+                            {
+                                AddTermToQuery(term, query);
+                            }
+                        }
+                    }
+                    while (enumerator.Next());
+                }
+                finally
+                {
+                    enumerator.Close();
+                }
+            }
+            else
+            {
+                TermEnum enumerator = reader.Terms(lowerTerm);
+
+                try
+                {
+
+                    bool checkLower = false;
+                    if (!inclusive)
+                        // make adjustments to set to exclusive
+                        checkLower = true;
+
+                    do
+                    {
+                        Term term = enumerator.Term();
+                        if (term != null && term.Field() == testField)
+                        {
+                            // interned comparison
+                            if (!checkLower || String.CompareOrdinal(term.Text(), lowerTerm.Text()) > 0)
+                            {
+                                checkLower = false;
+                                if (upperTerm != null)
+                                {
+                                    int compare = String.CompareOrdinal(upperTerm.Text(), term.Text());
+                                    /* if beyond the upper term, or is exclusive and
+                                    * this is equal to the upper term, break out */
+                                    if ((compare < 0) || (!inclusive && compare == 0))
+                                        break;
+                                }
+                                AddTermToQuery(term, query); // Found a match
+                            }
+                        }
+                        else
+                        {
+                            break;
+                        }
+                    }
+                    while (enumerator.Next());
+                }
+                finally
+                {
+                    enumerator.Close();
+                }
+            }
 			return query;
 		}
-		
-		/// <summary>Returns the field name for this query </summary>
+
+        private void AddTermToQuery(Term term, BooleanQuery query)
+        {
+            TermQuery tq = new TermQuery(term); // found a match
+            tq.SetBoost(GetBoost()); // set the boost
+            query.Add(tq, BooleanClause.Occur.SHOULD); // add to query
+        }
+
+        /// <summary>Returns the field name for this query </summary>
 		public virtual System.String GetField()
 		{
 			return (lowerTerm != null ? lowerTerm.Field() : upperTerm.Field());
@@ -156,7 +198,15 @@
 		{
 			return inclusive;
 		}
-		
+
+        /// <summary>
+        /// Returns the collator used to determine range inclusion, if any.
+        /// </summary>
+        /// <returns></returns>
+        public CompareInfo GetCollator()
+        {
+            return collator;
+        }
 		
 		/// <summary>Prints a user-readable version of this query. </summary>
 		public override System.String ToString(System.String field)
@@ -177,7 +227,7 @@
 		}
 		
 		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			if (this == o)
 				return true;
@@ -189,6 +239,8 @@
 				return false;
 			if (this.inclusive != other.inclusive)
 				return false;
+            if (this.collator != null && !this.collator.Equals(other.collator))
+                return false;
 			// one of lowerTerm and upperTerm can be null
 			if (this.lowerTerm != null ? !this.lowerTerm.Equals(other.lowerTerm) : other.lowerTerm != null)
 				return false;
@@ -207,6 +259,7 @@
 			h ^= ((h << 25) | (h >> 8));
 			h ^= (upperTerm != null ? upperTerm.GetHashCode() : 0);
 			h ^= (this.inclusive ? 0x2742E74A : 0);
+            h ^= collator != null ? collator.GetHashCode() : 0;
 			return h;
 		}
 	}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteCachingWrapperFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/RemoteCachingWrapperFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteCachingWrapperFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteCachingWrapperFilter.cs Wed Jul 29 18:04:12 2009
@@ -36,8 +36,6 @@
 	/// RemoteCachingWrapperFilter f = new RemoteCachingWrapperFilter(new CachingWrapperFilter(myFilter));
 	/// <p/>
 	/// </summary>
-	/// <author>  Matt Ericson
-	/// </author>
 	[Serializable]
 	public class RemoteCachingWrapperFilter : Filter
 	{
@@ -55,10 +53,24 @@
 		/// </param>
 		/// <returns> the bitset
 		/// </returns>
-		public override System.Collections.BitArray Bits(IndexReader reader)
+        [System.Obsolete("Use GetDocIdSet(IndexReader) instead.")]
+        public override System.Collections.BitArray Bits(IndexReader reader)
 		{
 			Filter cachedFilter = FilterManager.GetInstance().GetFilter(filter);
 			return cachedFilter.Bits(reader);
 		}
-	}
+
+        /// <summary> Uses the {@link FilterManager} to keep the cache for a filter on the 
+        /// searcher side of a remote connection.
+        /// </summary>
+        /// <param name="reader">the index reader for the Filter
+        /// </param>
+        /// <returns> the DocIdSet
+        /// </returns>
+        public override DocIdSet GetDocIdSet(IndexReader reader)
+        {
+            Filter cachedFilter = FilterManager.GetInstance().GetFilter(filter);
+            return cachedFilter.GetDocIdSet(reader);
+        }
+    }
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDocComparator.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ScoreDocComparator.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDocComparator.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDocComparator.cs Wed Jul 29 18:04:12 2009
@@ -21,17 +21,11 @@
 {
 	
 	
-	/// <summary> Expert: Compares two ScoreDoc objects for sorting.
-	/// 
-	/// <p>Created: Feb 3, 2004 9:00:16 AM 
-	/// 
+	/// <summary>
+    /// Expert: Compares two ScoreDoc objects for sorting.
 	/// </summary>
-	/// <author>   Tim Jones (Nacimiento Software)
-	/// </author>
-	/// <since>   lucene 1.4
-	/// </since>
-	/// <version>  $Id: ScoreDocComparator.java 518518 2007-03-15 08:48:00Z buschmi $
-	/// </version>
+	/// <since>lucene 1.4</since>
+	/// <version>$Id:$</version>
 	public struct ScoreDocComparator_Fields
 	{
 		/// <summary>Special comparator for sorting hits according to computed relevance (document score). </summary>

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Scorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Scorer.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Scorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Scorer.cs Wed Jul 29 18:04:12 2009
@@ -18,8 +18,7 @@
 using System;
 
 namespace Lucene.Net.Search
-{
-	
+{	
 	/// <summary> Expert: Common scoring functionality for different types of queries.
 	/// 
 	/// <p>
@@ -34,7 +33,7 @@
 	/// </summary>
 	/// <seealso cref="BooleanQuery.setAllowDocsOutOfOrder">
 	/// </seealso>
-	public abstract class Scorer
+	public abstract class Scorer : DocIdSetIterator
 	{
 		private Similarity similarity;
 		
@@ -87,68 +86,12 @@
 			return true;
 		}
 		
-		/// <summary> Advances to the document matching this Scorer with the lowest doc Id
-		/// greater than the current value of {@link #Doc()} (or to the matching
-		/// document with the lowest doc Id if next has never been called on
-		/// this Scorer).
-		/// 
-		/// <p>
-		/// When this method is used the {@link #Explain(int)} method should not
-		/// be used.
-		/// </p>
-		/// 
-		/// </summary>
-		/// <returns> true iff there is another document matching the query.
-		/// </returns>
-		/// <seealso cref="BooleanQuery.setAllowDocsOutOfOrder">
-		/// </seealso>
-		public abstract bool Next();
-		
-		/// <summary>Returns the current document number matching the query.
-		/// Initially invalid, until {@link #Next()} is called the first time.
-		/// </summary>
-		public abstract int Doc();
-		
 		/// <summary>Returns the score of the current document matching the query.
 		/// Initially invalid, until {@link #Next()} or {@link #SkipTo(int)}
 		/// is called the first time.
 		/// </summary>
 		public abstract float Score();
-		
-		/// <summary> Skips to the document matching this Scorer with the lowest doc Id
-		/// greater than or equal to a given target.
-		/// 
-		/// <p>
-		/// The behavior of this method is undefined if the target specified is
-		/// less than or equal to the current value of {@link #Doc()}.
-		/// <p>
-		/// Behaves as if written:
-		/// <pre>
-		/// boolean skipTo(int target) {
-		/// do {
-		/// if (!next())
-		/// return false;
-		/// } while (target > doc());
-		/// return true;
-		/// }
-		/// </pre>
-		/// Most implementations are considerably more efficient than that.
-		/// </p>
-		/// 
-		/// <p>
-		/// When this method is used the {@link #Explain(int)} method should not
-		/// be used.
-		/// </p>
-		/// 
-		/// </summary>
-		/// <param name="target">The target document number.
-		/// </param>
-		/// <returns> true iff there is such a match.
-		/// </returns>
-		/// <seealso cref="BooleanQuery.setAllowDocsOutOfOrder">
-		/// </seealso>
-		public abstract bool SkipTo(int target);
-		
+
 		/// <summary>Returns an explanation of the score for a document.
 		/// <br>When this method is used, the {@link #Next()}, {@link #SkipTo(int)} and
 		/// {@link #Score(HitCollector)} methods should not be used.

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searchable.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Searchable.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searchable.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searchable.cs Wed Jul 29 18:04:12 2009
@@ -35,7 +35,7 @@
 	/// 
 	/// <p>Queries, filters and sort criteria are designed to be compact so that
 	/// they may be efficiently passed to a remote index, with only the top-scoring
-	/// hits being returned, rather than every non-zero scoring hit.
+	/// hits being returned, rather than every matching hit.
 	/// </summary>
 	
     public interface Searchable
@@ -54,7 +54,7 @@
         /// </summary>
         /// <param name="weight">to match documents
         /// </param>
-        /// <param name="filter">if non-null, a bitset used to eliminate some documents
+        /// <param name="filter">if non-null, used permit documents to be collected
         /// </param>
         /// <param name="results">to receive hits
         /// </param>

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searcher.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Searcher.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searcher.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Searcher.cs Wed Jul 29 18:04:12 2009
@@ -43,6 +43,8 @@
 		
 		/// <summary>Returns the documents matching <code>query</code>. </summary>
 		/// <throws>  BooleanQuery.TooManyClauses </throws>
+        /// 
+        [System.Obsolete("Hits will be removed in Lucene 3.0.  Use Search(Query, Filter, int) instead.")]
 		public Hits Search(Query query)
 		{
 			return Search(query, (Filter) null);
@@ -52,7 +54,8 @@
 		/// <code>filter</code>.
 		/// </summary>
 		/// <throws>  BooleanQuery.TooManyClauses </throws>
-		public virtual Hits Search(Query query, Filter filter)
+        [System.Obsolete("Hits will be removed in Lucene 3.0.  Use Search(Query, Filter, int) instead.")]
+        public virtual Hits Search(Query query, Filter filter)
 		{
 			return new Hits(this, query, filter);
 		}
@@ -61,7 +64,8 @@
 		/// <code>sort</code>.
 		/// </summary>
 		/// <throws>  BooleanQuery.TooManyClauses </throws>
-		public virtual Hits Search(Query query, Sort sort)
+        [System.Obsolete("Hits will be removed in Lucene 3.0.  Use Search(Query, Filter, int, Sort) instead.")]
+        public virtual Hits Search(Query query, Sort sort)
 		{
 			return new Hits(this, query, null, sort);
 		}
@@ -70,12 +74,13 @@
 		/// sorted by <code>sort</code>.
 		/// </summary>
 		/// <throws>  BooleanQuery.TooManyClauses </throws>
-		public virtual Hits Search(Query query, Filter filter, Sort sort)
+        [System.Obsolete("Hits will be removed in Lucene 3.0.  Use Search(Query, Filter, int, Sort) instead.")]
+        public virtual Hits Search(Query query, Filter filter, Sort sort)
 		{
 			return new Hits(this, query, filter, sort);
 		}
 		
-		/// <summary>Expert: Low-level search implementation with arbitrary sorting.  Finds
+		/// <summary>Search implementation with arbitrary sorting.  Finds
 		/// the top <code>n</code> hits for <code>query</code>, applying
 		/// <code>filter</code> if non-null, and sorting the hits by the criteria in
 		/// <code>sort</code>.
@@ -91,8 +96,7 @@
 		
 		/// <summary>Lower-level search API.
 		/// 
-		/// <p>{@link HitCollector#Collect(int,float)} is called for every non-zero
-		/// scoring document.
+		/// <p>{@link HitCollector#Collect(int,float)} is called for every matching document.
 		/// 
 		/// <p>Applications should only use this if they need <i>all</i> of the
 		/// matching documents.  The high-level search API ({@link
@@ -110,19 +114,18 @@
 		
 		/// <summary>Lower-level search API.
 		/// 
-		/// <p>{@link HitCollector#Collect(int,float)} is called for every non-zero
-		/// scoring document.
+		/// <p>{@link HitCollector#Collect(int,float)} is called for every matching document.
 		/// <br>HitCollector-based access to remote indexes is discouraged.
 		/// 
 		/// <p>Applications should only use this if they need <i>all</i> of the
 		/// matching documents.  The high-level search API ({@link
-		/// Searcher#Search(Query)}) is usually more efficient, as it skips
+		/// Searcher#Search(Query, Filter, int)}) is usually more efficient, as it skips
 		/// non-high-scoring hits.
 		/// 
 		/// </summary>
 		/// <param name="query">to match documents
 		/// </param>
-		/// <param name="filter">if non-null, a bitset used to eliminate some documents
+		/// <param name="filter">if non-null, used to permit documents to be collected
 		/// </param>
 		/// <param name="results">to receive hits
 		/// </param>
@@ -132,21 +135,25 @@
 			Search(CreateWeight(query), filter, results);
 		}
 		
-		/// <summary>Expert: Low-level search implementation.  Finds the top <code>n</code>
+		/// <summary>Finds the top <code>n</code>
 		/// hits for <code>query</code>, applying <code>filter</code> if non-null.
-		/// 
-		/// <p>Called by {@link Hits}.
-		/// 
-		/// <p>Applications should usually call {@link Searcher#Search(Query)} or
-		/// {@link Searcher#search(Query,Filter)} instead.
 		/// </summary>
 		/// <throws>  BooleanQuery.TooManyClauses </throws>
 		public virtual TopDocs Search(Query query, Filter filter, int n)
 		{
 			return Search(CreateWeight(query), filter, n);
 		}
-		
-		/// <summary>Returns an Explanation that describes how <code>doc</code> scored against
+
+        /// <summary>Finds the top <code>n</code>
+        /// hits for <code>query</code>, applying <code>filter</code> if non-null.
+        /// </summary>
+        /// <throws>  BooleanQuery.TooManyClauses </throws>
+        public virtual TopDocs Search(Query query, int n)
+        {
+            return Search(CreateWeight(query), null, n);
+        }
+
+        /// <summary>Returns an Explanation that describes how <code>doc</code> scored against
 		/// <code>query</code>.
 		/// 
 		/// <p>This is intended to be used in developing Similarity implementations,

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SimilarityDelegator.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SimilarityDelegator.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SimilarityDelegator.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SimilarityDelegator.cs Wed Jul 29 18:04:12 2009
@@ -69,5 +69,10 @@
 		{
 			return delegee.Coord(overlap, maxOverlap);
 		}
+
+        public override float ScorePayload(string fieldName, byte[] payload, int offset, int length)
+        {
+            return delegee.ScorePayload(fieldName, payload, offset, length);
+        }
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SloppyPhraseScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SloppyPhraseScorer.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SloppyPhraseScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SloppyPhraseScorer.cs Wed Jul 29 18:04:12 2009
@@ -43,13 +43,14 @@
 				}
 				
 			}
-			public int Compare(System.Object x, System.Object y)
+			public int Compare(object x, object y)
 			{
 				return ((PhrasePositions) y).offset - ((PhrasePositions) x).offset;
 			}
 		}
 		private int slop;
-		private PhrasePositions[] repeats;
+        private PhrasePositions[] repeats;
+        private PhrasePositions[] tmpPos;  // for flipping repeating pps.
 		private bool checkedRepeats;
 		
 		internal SloppyPhraseScorer(Weight weight, TermPositions[] tps, int[] offsets, Similarity similarity, int slop, byte[] norms) : base(weight, tps, offsets, similarity, norms)
@@ -96,7 +97,12 @@
 						done = true; // ran out of a term -- done
 						break;
 					}
-					tpsDiffer = !pp.repeats || TermPositionsDiffer(pp);
+                    PhrasePositions pp2 = null;
+					tpsDiffer = !pp.repeats || (pp2 = TermPositionsDiffer(pp)) == null;
+                    if (pp2 != null && pp2 != pp)
+                    {
+                        pp = Flip(pp, pp2); // flip pp to pp2
+                    }
 				}
 				
 				int matchLength = end - start;
@@ -111,22 +117,43 @@
 			return freq;
 		}
 		
-		
-		/// <summary> Init PhrasePositions in place.
-		/// There is a one time initializatin for this scorer:
-		/// <br>- Put in repeats[] each pp that has another pp with same position in the doc.
-		/// <br>- Also mark each such pp by pp.repeats = true.
-		/// <br>Later can consult with repeats[] in termPositionsDiffer(pp), making that check efficient.
-		/// In particular, this allows to score queries with no repetiotions with no overhead due to this computation.
-		/// <br>- Example 1 - query with no repetitions: "ho my"~2
-		/// <br>- Example 2 - query with repetitions: "ho my my"~2
-		/// <br>- Example 3 - query with repetitions: "my ho my"~2
-		/// <br>Init per doc w/repeats in query, includes propagating some repeating pp's to avoid false phrase detection.  
-		/// </summary>
-		/// <returns> end (max position), or -1 if any term ran out (i.e. done) 
-		/// </returns>
-		/// <throws>  IOException  </throws>
-		private int InitPhrasePositions()
+		// flip pp2 and pp in the queue: pop until finding pp2, insert back all but pp2, insert pp back
+        // assumes: pp!=pp2, pp2 in pq, pp not in pq
+        // called only when there are prepeating pps
+        private PhrasePositions Flip(PhrasePositions pp, PhrasePositions pp2)
+        {
+            int n = 0;
+            PhrasePositions pp3;
+
+            // pop until finding pp2
+            while ((pp3 = (PhrasePositions)pq.Pop()) != pp2)
+                tmpPos[n++] = pp3;
+
+            // insert back all but pp2
+            for (n--; n >= 0; n--)
+                pq.Insert(tmpPos[n]);
+
+            // insert pp back
+            pq.Put(pp);
+
+            return pp2;
+        }
+
+        /// <summary> Init PhrasePositions in place.
+        /// There is a one time initializatin for this scorer:
+        /// <br>- Put in repeats[] each pp that has another pp with same position in the doc.
+        /// <br>- Also mark each such pp by pp.repeats = true.
+        /// <br>Later can consult with repeats[] in termPositionsDiffer(pp), making that check efficient.
+        /// In particular, this allows to score queries with no repetiotions with no overhead due to this computation.
+        /// <br>- Example 1 - query with no repetitions: "ho my"~2
+        /// <br>- Example 2 - query with repetitions: "ho my my"~2
+        /// <br>- Example 3 - query with repetitions: "my ho my"~2
+        /// <br>Init per doc w/repeats in query, includes propagating some repeating pp's to avoid false phrase detection.  
+        /// </summary>
+        /// <returns> end (max position), or -1 if any term ran out (i.e. done) 
+        /// </returns>
+        /// <throws>  IOException  </throws>
+        private int InitPhrasePositions()
 		{
 			int end = 0;
 			
@@ -183,15 +210,13 @@
 			// with repeats must advance some repeating pp's so they all start with differing tp's       
 			if (repeats != null)
 			{
-				// must propagate higher offsets first (otherwise might miss matches).
-				System.Array.Sort(repeats, new AnonymousClassComparator(this));
-				// now advance them
 				for (int i = 0; i < repeats.Length; i++)
 				{
-					PhrasePositions pp = repeats[i];
-					while (!TermPositionsDiffer(pp))
+                    PhrasePositions pp = repeats[i];
+                    PhrasePositions pp2;
+					while ((pp2 = TermPositionsDiffer(pp)) != null)
 					{
-						if (!pp.NextPosition())
+						if (!pp2.NextPosition())  // out of pps that do not differ, advance the pp with higher offset
 							return - 1; // ran out of a term -- done  
 					}
 				}
@@ -206,14 +231,22 @@
 				pq.Put(pp); // build pq from list
 			}
 			
-			return end;
-		}
+            if (repeats != null)
+                tmpPos = new PhrasePositions[pq.Size()];
+
+            return end;
+        }
 		
-		// disalow two pp's to have the same tp position, so that same word twice 
-		// in query would go elswhere in the matched doc
-		private bool TermPositionsDiffer(PhrasePositions pp)
+        /// <summary>
+        /// We disallow two PPs having the same TermPosition, thereby verifying multiple occurrences
+        /// in the query of the same word would go elsewhere in the matched doc.
+        /// </summary>
+        /// <param name="pp"></param>
+        /// <returns>null if differ (i.e., valid) otherwise return the higher offset PhrasePositions
+        /// our of the first two PPs found to not differ</returns>
+        private PhrasePositions TermPositionsDiffer(PhrasePositions pp)
 		{
-			// efficiency note: a more efficient implemention could keep a map between repeating 
+			// efficiency note: a more efficient implementation could keep a map between repeating 
 			// pp's, so that if pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats 
 			// of term2, pp2a would only be checked against pp2b but not against pp1a, pp1b, pp1c. 
 			// However this would complicate code, for a rather rare case, so choice is to compromise here.
@@ -225,9 +258,9 @@
 					continue;
 				int tpPos2 = pp2.position + pp2.offset;
 				if (tpPos2 == tpPos)
-					return false;
+					return pp.offset > pp2.offset ? pp : pp2; // do not differ: return the one with higher offset
 			}
-			return true;
+			return null;
 		}
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Sort.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Sort.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Sort.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Sort.cs Wed Jul 29 18:04:12 2009
@@ -30,7 +30,7 @@
 	/// and does not need to be stored (unless you happen to want it back with the
 	/// rest of your document data).  In other words:
 	/// 
-	/// <p><code>document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.UN_TOKENIZED));</code></p>
+	/// <p><code>document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.NO_ANALYZED));</code></p>
 	/// 
 	/// 
 	/// <p><h3>Valid Types of Values</h3>
@@ -66,7 +66,7 @@
 	/// of term value has higher memory requirements than the other
 	/// two types.
 	/// 
-	/// <p><h3>Object Reuse</h3>
+	/// <p><h3>object Reuse</h3>
 	/// 
 	/// <p>One of these objects can be
 	/// used multiple times and the sort order changed between usages.
@@ -95,8 +95,6 @@
 	/// <p>Created: Feb 12, 2004 10:53:57 AM
 	/// 
 	/// </summary>
-	/// <author>   Tim Jones (Nacimiento Software)
-	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
 	/// <version>  $Id: Sort.java 598376 2007-11-26 18:45:39Z dnaber $

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SortField.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SortField.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SortField.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SortField.cs Wed Jul 29 18:04:12 2009
@@ -22,12 +22,7 @@
 	
 	/// <summary> Stores information about how to sort documents by terms in an individual
 	/// field.  Fields must be indexed in order to sort by them.
-	/// 
-	/// <p>Created: Feb 11, 2004 1:25:29 PM
-	/// 
 	/// </summary>
-	/// <author>   Tim Jones (Nacimiento Software)
-	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
 	/// <version>  $Id: SortField.java 598296 2007-11-26 14:52:01Z mikemccand $
@@ -79,13 +74,25 @@
 		/// lower values are at the front. 
 		/// </summary>
 		public const int DOUBLE = 7;
-		
-		/// <summary>Sort using a custom Comparator.  Sort values are any Comparable and
+
+        /// <summary>
+        /// Sort using term values as encoded shorts.
+        /// Sort values are shorts and lower values are at the front. 
+        /// </summary>
+        public const int SHORT = 8;
+
+        /// <summary>Sort using a custom Comparator.  Sort values are any Comparable and
 		/// sorting is done according to natural order. 
 		/// </summary>
 		public const int CUSTOM = 9;
-		
-		// IMPLEMENTATION NOTE: the FieldCache.STRING_INDEX is in the same "namespace"
+
+        /// <summary>
+        /// Sort using term values as encoded bytes.
+        /// Sort values are bytes and lower values are at the front. 
+        /// </summary>
+        public const int BYTE = 10;
+
+        // IMPLEMENTATION NOTE: the FieldCache.STRING_INDEX is in the same "namespace"
 		// as the above static int values.  Any new values must not have the same value
 		// as FieldCache.STRING_INDEX.
 		

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SpanFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilter.cs Wed Jul 29 18:04:12 2009
@@ -35,7 +35,7 @@
 		/// <summary>Returns a SpanFilterResult with true for documents which should be permitted in
 		/// search results, and false for those that should not and Spans for where the true docs match.
 		/// </summary>
-		/// <param name="reader">The {@link Lucene.Net.Index.IndexReader} to load position and bitset information from
+		/// <param name="reader">The {@link Lucene.Net.Index.IndexReader} to load position and DocIdSet information from
 		/// </param>
 		/// <returns> A {@link SpanFilterResult}
 		/// </returns>

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilterResult.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SpanFilterResult.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilterResult.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanFilterResult.cs Wed Jul 29 18:04:12 2009
@@ -30,7 +30,10 @@
 	/// </summary>
 	public class SpanFilterResult
 	{
+        [System.Obsolete()]
 		private System.Collections.BitArray bits;
+
+        private DocIdSet docIdSet;
 		private System.Collections.IList positions; //Spans spans;
 		
 		/// <summary> </summary>
@@ -38,13 +41,23 @@
 		/// </param>
 		/// <param name="positions">A List of {@link Lucene.Net.Search.SpanFilterResult.PositionInfo} objects
 		/// </param>
+        [System.Obsolete("Use SpanFilterResult(DocIdSet, List) instead.")]
 		public SpanFilterResult(System.Collections.BitArray bits, System.Collections.IList positions)
 		{
 			this.bits = bits;
 			this.positions = positions;
 		}
-		
-		/// <summary> The first entry in the array corresponds to the first "on" bit.
+
+        /// <summary></summary>
+        /// <param name="docIdSet">The DocIdSet for the Filter</param>
+        /// <param name="positions">A List of {@link Lucene.Net.Search.SpanFilterResult.PositionInfo} objects</param>
+        public SpanFilterResult(DocIdSet docIdSet, System.Collections.IList positions)
+        {
+            this.docIdSet = docIdSet;
+            this.positions = positions;
+        }
+
+        /// <summary> The first entry in the array corresponds to the first "on" bit.
 		/// Entries are increasing by document order
 		/// </summary>
 		/// <returns> A List of PositionInfo objects
@@ -54,12 +67,20 @@
 			return positions;
 		}
 		
+        [System.Obsolete("Use GetDocIdSet() instead.")]
 		public virtual System.Collections.BitArray GetBits()
 		{
 			return bits;
 		}
-		
-		
+
+        /// <summary>
+        /// Returns the DocIdSet.
+        /// </summary>
+        /// <returns></returns>
+        public virtual DocIdSet GetDocIdSet()
+        {
+            return docIdSet;
+        }
 		
 		public class PositionInfo
 		{

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanQueryFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/SpanQueryFilter.cs?rev=798995&r1=798994&r2=798995&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanQueryFilter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/SpanQueryFilter.cs Wed Jul 29 18:04:12 2009
@@ -17,8 +17,10 @@
 
 using System;
 
+using OpenBitSet = Lucene.Net.Util.OpenBitSet;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using SpanQuery = Lucene.Net.Search.Spans.SpanQuery;
+using _Spans = Lucene.Net.Search.Spans.Spans;
 
 namespace Lucene.Net.Search
 {
@@ -54,26 +56,31 @@
 		{
 			this.query = query;
 		}
-		
-		public override System.Collections.BitArray Bits(IndexReader reader)
+
+        [System.Obsolete()]
+        public override System.Collections.BitArray Bits(IndexReader reader)
+        {
+            throw new Exception("The method or operation is not implemented.");
+        }	
+	
+		public override DocIdSet GetDocIdSet(IndexReader reader)
 		{
 			SpanFilterResult result = BitSpans(reader);
-			return result.GetBits();
+			return result.GetDocIdSet();
 		}
 		
-		
 		public override SpanFilterResult BitSpans(IndexReader reader)
 		{
 			
-			System.Collections.BitArray bits = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
-			Lucene.Net.Search.Spans.Spans spans = query.GetSpans(reader);
+			OpenBitSet bits = new OpenBitSet((reader.MaxDoc() % 64 == 0 ? reader.MaxDoc() / 64 : reader.MaxDoc() / 64 + 1) * 64);
+            _Spans spans = query.GetSpans(reader);
 			System.Collections.IList tmp = new System.Collections.ArrayList(20);
 			int currentDoc = - 1;
 			SpanFilterResult.PositionInfo currentInfo = null;
 			while (spans.Next())
 			{
 				int doc = spans.Doc();
-				bits.Set(doc, true);
+				bits.Set(doc);
 				if (currentDoc != doc)
 				{
 					currentInfo = new SpanFilterResult.PositionInfo(doc);
@@ -85,7 +92,6 @@
 			return new SpanFilterResult(bits, tmp);
 		}
 		
-		
 		public virtual SpanQuery GetQuery()
 		{
 			return query;
@@ -96,7 +102,7 @@
 			return "QueryWrapperFilter(" + query + ")";
 		}
 		
-		public  override bool Equals(System.Object o)
+		public  override bool Equals(object o)
 		{
 			return o is SpanQueryFilter && this.query.Equals(((SpanQueryFilter) o).query);
 		}