You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2006/06/04 04:41:25 UTC

svn commit: r411501 [20/30] - in /incubator/lucene.net/trunk/C#/src: ./ Demo/DeleteFiles/ Demo/DemoLib/ Demo/DemoLib/HTML/ Demo/IndexFiles/ Demo/IndexHtml/ Demo/SearchFiles/ Lucene.Net/ Lucene.Net/Analysis/ Lucene.Net/Analysis/Standard/ Lucene.Net/Docu...

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhrasePrefixQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PhrasePrefixQuery.cs?rev=411501&r1=411500&r2=411501&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhrasePrefixQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhrasePrefixQuery.cs Sat Jun  3 19:41:13 2006
@@ -13,11 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using MultipleTermPositions = Lucene.Net.Index.MultipleTermPositions;
 using Term = Lucene.Net.Index.Term;
 using TermPositions = Lucene.Net.Index.TermPositions;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+
 namespace Lucene.Net.Search
 {
 	
@@ -29,12 +32,14 @@
 	/// terms) to add them to the query.
 	/// 
 	/// </summary>
+	/// <deprecated> use {@link Lucene.Net.search.MultiPhraseQuery} instead
+	/// </deprecated>
 	/// <author>  Anders Nielsen
 	/// </author>
 	/// <version>  1.0
 	/// </version>
 	[Serializable]
-	public class PhrasePrefixQuery:Query
+	public class PhrasePrefixQuery : Query
 	{
 		private System.String field;
 		private System.Collections.ArrayList termArrays = new System.Collections.ArrayList();
@@ -42,36 +47,36 @@
 		
 		private int slop = 0;
 		
-        /// <summary>Sets the phrase slop for this query.</summary>
-        /// <seealso cref="PhraseQuery#SetSlop(int)">
-        /// </seealso>
-        public virtual void  SetSlop(int s)
+		/// <summary>Sets the phrase slop for this query.</summary>
+		/// <seealso cref="PhraseQuery.SetSlop(int)">
+		/// </seealso>
+		public virtual void  SetSlop(int s)
 		{
 			slop = s;
 		}
 		
-        /// <summary>Sets the phrase slop for this query.</summary>
-        /// <seealso cref="PhraseQuery#GetSlop()">
-        /// </seealso>
-        public virtual int GetSlop()
+		/// <summary>Sets the phrase slop for this query.</summary>
+		/// <seealso cref="PhraseQuery.GetSlop()">
+		/// </seealso>
+		public virtual int GetSlop()
 		{
 			return slop;
 		}
 		
-        /// <summary>Add a single term at the next position in the phrase.</summary>
-        /// <seealso cref="PhraseQuery#Add(Term)">
-        /// </seealso>
-        public virtual void  Add(Term term)
+		/// <summary>Add a single term at the next position in the phrase.</summary>
+		/// <seealso cref="PhraseQuery.Add(Term)">
+		/// </seealso>
+		public virtual void  Add(Term term)
 		{
 			Add(new Term[]{term});
 		}
 		
-        /// <summary>Add multiple terms at the next position in the phrase.  Any of the terms
-        /// may match.
-        /// 
-        /// </summary>
-        /// <seealso cref="PhraseQuery#Add(Term)">
-        /// </seealso>
+		/// <summary>Add multiple terms at the next position in the phrase.  Any of the terms
+		/// may match.
+		/// 
+		/// </summary>
+		/// <seealso cref="PhraseQuery.Add(Term)">
+		/// </seealso>
 		public virtual void  Add(Term[] terms)
 		{
 			int position = 0;
@@ -81,42 +86,42 @@
 			Add(terms, position);
 		}
 		
-        /// <summary> Allows to specify the relative position of terms within the phrase.
-        /// 
-        /// </summary>
-        /// <seealso cref="int)">
-        /// </seealso>
-        /// <param name="">terms
-        /// </param>
-        /// <param name="">position
-        /// </param>
-        public virtual void  Add(Term[] terms, int position)
-        {
-            if (termArrays.Count == 0)
-                field = terms[0].Field();
-			
-            for (int i = 0; i < terms.Length; i++)
-            {
-                if (terms[i].Field() != field)
-                {
-                    throw new System.ArgumentException("All phrase terms must be in the same field (" + field + "): " + terms[i]);
-                }
-            }
-			
-            termArrays.Add(terms);
-            positions.Add((System.Int32) position);
-        }
+		/// <summary> Allows to specify the relative position of terms within the phrase.
+		/// 
+		/// </summary>
+		/// <seealso cref="PhraseQuery.Add(Term, int)">
+		/// </seealso>
+		/// <param name="terms">
+		/// </param>
+		/// <param name="position">
+		/// </param>
+		public virtual void  Add(Term[] terms, int position)
+		{
+			if (termArrays.Count == 0)
+				field = terms[0].Field();
+			
+			for (int i = 0; i < terms.Length; i++)
+			{
+				if (terms[i].Field() != field)
+				{
+					throw new System.ArgumentException("All phrase terms must be in the same field (" + field + "): " + terms[i]);
+				}
+			}
+			
+			termArrays.Add(terms);
+			positions.Add((System.Int32) position);
+		}
 		
-        /// <summary> Returns the relative positions of terms in this phrase.</summary>
-        public virtual int[] GetPositions()
-        {
-            int[] result = new int[positions.Count];
-            for (int i = 0; i < positions.Count; i++)
-                result[i] = ((System.Int32) positions[i]);
-            return result;
-        }
+		/// <summary> Returns the relative positions of terms in this phrase.</summary>
+		public virtual int[] GetPositions()
+		{
+			int[] result = new int[positions.Count];
+			for (int i = 0; i < positions.Count; i++)
+				result[i] = ((System.Int32) positions[i]);
+			return result;
+		}
 		
-        [Serializable]
+		[Serializable]
 		private class PhrasePrefixWeight : Weight
 		{
 			private void  InitBlock(PhrasePrefixQuery enclosingInstance)
@@ -124,31 +129,15 @@
 				this.enclosingInstance = enclosingInstance;
 			}
 			private PhrasePrefixQuery enclosingInstance;
-			virtual public Query Query
+			public PhrasePrefixQuery Enclosing_Instance
 			{
 				get
 				{
-					return Enclosing_Instance;
+					return enclosingInstance;
 				}
 				
 			}
-            virtual public float Value
-            {
-                get
-                {
-                    return value_Renamed;
-                }
-				
-            }
-            public PhrasePrefixQuery Enclosing_Instance
-            {
-                get
-                {
-                    return enclosingInstance;
-                }
-				
-            }
-            private Searcher searcher;
+			private Similarity similarity;
 			private float value_Renamed;
 			private float idf;
 			private float queryNorm;
@@ -157,19 +146,31 @@
 			public PhrasePrefixWeight(PhrasePrefixQuery enclosingInstance, Searcher searcher)
 			{
 				InitBlock(enclosingInstance);
-				this.searcher = searcher;
-			}
-			
-			public virtual float SumOfSquaredWeights()
-			{
+				this.similarity = Enclosing_Instance.GetSimilarity(searcher);
+				
+				// compute idf
 				System.Collections.IEnumerator i = Enclosing_Instance.termArrays.GetEnumerator();
 				while (i.MoveNext())
 				{
 					Term[] terms = (Term[]) i.Current;
 					for (int j = 0; j < terms.Length; j++)
+					{
 						idf += Enclosing_Instance.GetSimilarity(searcher).Idf(terms[j], searcher);
+					}
 				}
-				
+			}
+			
+			public virtual Query GetQuery()
+			{
+				return Enclosing_Instance;
+			}
+			public virtual float GetValue()
+			{
+				return value_Renamed;
+			}
+			
+			public virtual float SumOfSquaredWeights()
+			{
 				queryWeight = idf * Enclosing_Instance.GetBoost(); // compute query weight
 				return queryWeight * queryWeight; // square it
 			}
@@ -205,21 +206,21 @@
 				}
 				
 				if (Enclosing_Instance.slop == 0)
-					return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), Enclosing_Instance.GetSimilarity(searcher), reader.Norms(Enclosing_Instance.field));
+					return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, reader.Norms(Enclosing_Instance.field));
 				else
-					return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), Enclosing_Instance.GetSimilarity(searcher), Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
+					return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
 			}
 			
 			public virtual Explanation Explain(IndexReader reader, int doc)
 			{
 				Explanation result = new Explanation();
-				result.SetDescription("weight(" + Query + " in " + doc + "), product of:");
+				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
 				
-				Explanation idfExpl = new Explanation(idf, "idf(" + Query + ")");
+				Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
 				
 				// explain query weight
 				Explanation queryExpl = new Explanation();
-				queryExpl.SetDescription("queryWeight(" + Query + "), product of:");
+				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
 				
 				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
 				if (Enclosing_Instance.GetBoost() != 1.0f)
@@ -234,9 +235,9 @@
 				
 				result.AddDetail(queryExpl);
 				
-				// explain Field weight
+				// explain field weight
 				Explanation fieldExpl = new Explanation();
-				fieldExpl.SetDescription("fieldWeight(" + Query + " in " + doc + "), product of:");
+				fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
 				
 				Explanation tfExpl = Scorer(reader).Explain(doc);
 				fieldExpl.AddDetail(tfExpl);
@@ -246,7 +247,7 @@
 				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
 				float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f;
 				fieldNormExpl.SetValue(fieldNorm);
-				fieldNormExpl.SetDescription("fieldNorm(Field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
+				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
 				fieldExpl.AddDetail(fieldNormExpl);
 				
 				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
@@ -269,10 +270,10 @@
 			{
 				// optimize one-term case
 				Term[] terms = (Term[]) termArrays[0];
-				BooleanQuery boq = new BooleanQuery();
+				BooleanQuery boq = new BooleanQuery(true);
 				for (int i = 0; i < terms.Length; i++)
 				{
-					boq.Add(new TermQuery(terms[i]), false, false);
+					boq.Add(new TermQuery(terms[i]), BooleanClause.Occur.SHOULD);
 				}
 				boq.SetBoost(GetBoost());
 				return boq.CreateWeight(searcher);
@@ -295,10 +296,10 @@
 			while (i.MoveNext())
 			{
 				Term[] terms = (Term[]) i.Current;
-				buffer.Append(terms[0].Text() + (terms.Length > 0 ? "*" : ""));
-                if (i.MoveNext())
-                    buffer.Append(" ");
-            }
+				buffer.Append(terms[0].Text() + (terms.Length > 1?"*":""));
+				if (i.MoveNext())
+					buffer.Append(" ");
+			}
 			buffer.Append("\"");
 			
 			if (slop != 0)
@@ -307,14 +308,11 @@
 				buffer.Append(slop);
 			}
 			
-			if (GetBoost() != 1.0f)
-			{
-				buffer.Append("^");
-				buffer.Append(GetBoost().ToString());
-			}
+			buffer.Append(ToStringUtils.Boost(GetBoost()));
 			
 			return buffer.ToString();
 		}
+        // {{Aroush-1.9}} Do we need this?!
 		override public System.Object Clone()
 		{
 			return null;

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,23 +13,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using TermPositions = Lucene.Net.Index.TermPositions;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+
 namespace Lucene.Net.Search
 {
 	
 	/// <summary>A Query that matches documents containing a particular sequence of terms.
-	/// This may be combined with other terms with a {@link BooleanQuery}.
+	/// A PhraseQuery is built by QueryParser for input like <code>"new york"</code>.
+	/// 
+	/// <p>This query may be combined with other terms or queries with a {@link BooleanQuery}.
 	/// </summary>
 	[Serializable]
-	public class PhraseQuery:Query
+	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 int slop = 0;
+		private System.Collections.ArrayList positions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
+		private int slop = 0;
 		
 		/// <summary>Constructs an empty phrase query. </summary>
 		public PhraseQuery()
@@ -58,57 +63,57 @@
 			return slop;
 		}
 		
-        /// <summary> Adds a term to the end of the query phrase.
-        /// The relative position of the term is the one immediately after the last term added.
-        /// </summary>
-        public virtual void  Add(Term term)
-        {
-            int position = 0;
-            if (positions.Count > 0)
-                position = ((System.Int32) positions[positions.Count - 1]) + 1;
-			
-            Add(term, position);
-        }
-		
-        /// <summary> Adds a term to the end of the query phrase.
-        /// The relative position of the term within the phrase is specified explicitly.
-        /// This allows e.g. phrases with more than one term at the same position
-        /// or phrases with gaps (e.g. in connection with stopwords).
-        /// 
-        /// </summary>
-        /// <param name="">term
-        /// </param>
-        /// <param name="">position
-        /// </param>
-        public virtual void  Add(Term term, int position)
-        {
-            if (terms.Count == 0)
-                field = term.Field();
-            else if (term.Field() != field)
-            {
-                throw new System.ArgumentException("All phrase terms must be in the same field: " + term);
-            }
-			
-            terms.Add(term);
-            positions.Add((System.Int32) position);
-        }
+		/// <summary> Adds a term to the end of the query phrase.
+		/// The relative position of the term is the one immediately after the last term added.
+		/// </summary>
+		public virtual void  Add(Term term)
+		{
+			int position = 0;
+			if (positions.Count > 0)
+				position = ((System.Int32) positions[positions.Count - 1]) + 1;
+			
+			Add(term, position);
+		}
 		
-        /// <summary>Returns the set of terms in this phrase. </summary>
+		/// <summary> Adds a term to the end of the query phrase.
+		/// The relative position of the term within the phrase is specified explicitly.
+		/// This allows e.g. phrases with more than one term at the same position
+		/// or phrases with gaps (e.g. in connection with stopwords).
+		/// 
+		/// </summary>
+		/// <param name="term">
+		/// </param>
+		/// <param name="position">
+		/// </param>
+		public virtual void  Add(Term term, int position)
+		{
+			if (terms.Count == 0)
+				field = term.Field();
+			else if (term.Field() != field)
+			{
+				throw new System.ArgumentException("All phrase terms must be in the same field: " + term);
+			}
+			
+			terms.Add(term);
+			positions.Add((System.Int32) position);
+		}
+		
+		/// <summary>Returns the set of terms in this phrase. </summary>
 		public virtual Term[] GetTerms()
 		{
 			return (Term[]) terms.ToArray(typeof(Term));
 		}
 		
-        /// <summary> Returns the relative positions of terms in this phrase.</summary>
-        public virtual int[] GetPositions()
-        {
-            int[] result = new int[positions.Count];
-            for (int i = 0; i < positions.Count; i++)
-                result[i] = ((System.Int32) positions[i]);
-            return result;
-        }
+		/// <summary> Returns the relative positions of terms in this phrase.</summary>
+		public virtual int[] GetPositions()
+		{
+			int[] result = new int[positions.Count];
+			for (int i = 0; i < positions.Count; i++)
+				result[i] = ((System.Int32) positions[i]);
+			return result;
+		}
 		
-        [Serializable]
+		[Serializable]
 		private class PhraseWeight : Weight
 		{
 			private void  InitBlock(PhraseQuery enclosingInstance)
@@ -116,31 +121,15 @@
 				this.enclosingInstance = enclosingInstance;
 			}
 			private PhraseQuery enclosingInstance;
-			virtual public Query Query
+			public PhraseQuery Enclosing_Instance
 			{
 				get
 				{
-					return Enclosing_Instance;
+					return enclosingInstance;
 				}
 				
 			}
-            virtual public float Value
-            {
-                get
-                {
-                    return value_Renamed;
-                }
-				
-            }
-            public PhraseQuery Enclosing_Instance
-            {
-                get
-                {
-                    return enclosingInstance;
-                }
-				
-            }
-            private Searcher searcher;
+			private Similarity similarity;
 			private float value_Renamed;
 			private float idf;
 			private float queryNorm;
@@ -149,7 +138,9 @@
 			public PhraseWeight(PhraseQuery enclosingInstance, Searcher searcher)
 			{
 				InitBlock(enclosingInstance);
-				this.searcher = searcher;
+				this.similarity = Enclosing_Instance.GetSimilarity(searcher);
+				
+				idf = similarity.Idf(Enclosing_Instance.terms, searcher);
 			}
 			
 			public override System.String ToString()
@@ -157,9 +148,17 @@
 				return "weight(" + Enclosing_Instance + ")";
 			}
 			
+			public virtual Query GetQuery()
+			{
+				return Enclosing_Instance;
+			}
+			public virtual float GetValue()
+			{
+				return value_Renamed;
+			}
+			
 			public virtual float SumOfSquaredWeights()
 			{
-				idf = Enclosing_Instance.GetSimilarity(searcher).Idf(Enclosing_Instance.terms, searcher);
 				queryWeight = idf * Enclosing_Instance.GetBoost(); // compute query weight
 				return queryWeight * queryWeight; // square it
 			}
@@ -188,16 +187,16 @@
 				
 				if (Enclosing_Instance.slop == 0)
 				// optimize exact case
-					return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), Enclosing_Instance.GetSimilarity(searcher), reader.Norms(Enclosing_Instance.field));
+					return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, reader.Norms(Enclosing_Instance.field));
 				else
-					return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), Enclosing_Instance.GetSimilarity(searcher), Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
+					return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
 			}
 			
 			public virtual Explanation Explain(IndexReader reader, int doc)
 			{
 				
 				Explanation result = new Explanation();
-				result.SetDescription("weight(" + Query + " in " + doc + "), product of:");
+				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
 				
 				System.Text.StringBuilder docFreqs = new System.Text.StringBuilder();
 				System.Text.StringBuilder query = new System.Text.StringBuilder();
@@ -214,7 +213,7 @@
 					
 					docFreqs.Append(term.Text());
 					docFreqs.Append("=");
-					docFreqs.Append(searcher.DocFreq(term));
+					docFreqs.Append(reader.DocFreq(term));
 					
 					query.Append(term.Text());
 				}
@@ -224,7 +223,7 @@
 				
 				// explain query weight
 				Explanation queryExpl = new Explanation();
-				queryExpl.SetDescription("queryWeight(" + Query + "), product of:");
+				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
 				
 				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
 				if (Enclosing_Instance.GetBoost() != 1.0f)
@@ -238,7 +237,7 @@
 				
 				result.AddDetail(queryExpl);
 				
-				// explain Field weight
+				// explain field weight
 				Explanation fieldExpl = new Explanation();
 				fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:");
 				
@@ -250,7 +249,7 @@
 				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
 				float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f;
 				fieldNormExpl.SetValue(fieldNorm);
-				fieldNormExpl.SetDescription("fieldNorm(Field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
+				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
 				fieldExpl.AddDetail(fieldNormExpl);
 				
 				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
@@ -280,6 +279,15 @@
 			return new PhraseWeight(this, searcher);
 		}
 		
+		/// <seealso cref="Lucene.Net.search.Query.ExtractTerms(java.util.Set)">
+		/// </seealso>
+		public override void  ExtractTerms(System.Collections.Hashtable queryTerms)
+		{
+			foreach (Term term in terms)
+			{
+				queryTerms.Add(term, term);
+			}
+		}
 		
 		/// <summary>Prints a user-readable version of this query. </summary>
 		public override System.String ToString(System.String f)
@@ -306,14 +314,7 @@
 				buffer.Append(slop);
 			}
 			
-			if (GetBoost() != 1.0f)
-			{
-                System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
-                nfi.NumberDecimalDigits = 1;
-
-                buffer.Append("^");
-                buffer.Append(GetBoost().ToString("N", nfi));
-			}
+			buffer.Append(ToStringUtils.Boost(GetBoost()));
 			
 			return buffer.ToString();
 		}
@@ -324,7 +325,7 @@
 			if (!(o is PhraseQuery))
 				return false;
 			PhraseQuery other = (PhraseQuery) o;
-			return (this.GetBoost() == other.GetBoost()) && 
+            return (this.GetBoost() == other.GetBoost()) && 
                 (this.slop == other.slop) && 
                 this.terms.Equals(other.terms) && 
                 this.positions.Equals(other.positions);
@@ -333,11 +334,9 @@
 		/// <summary>Returns a hash code value for this object.</summary>
 		public override int GetHashCode()
 		{
-            return System.BitConverter.ToInt32(System.BitConverter.GetBytes(GetBoost()), 0) ^ 
-                System.BitConverter.ToInt32(System.BitConverter.GetBytes(slop), 0) ^ 
-                terms.GetHashCode() ^ 
-                positions.GetHashCode();
+			return BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0) ^ slop ^ terms.GetHashCode() ^ positions.GetHashCode();
 		}
+		// {{Aroush-1.9}} Do we need this?!
 		override public System.Object Clone()
 		{
 			return null;

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
+
 namespace Lucene.Net.Search
 {
 	

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/PhraseScorer.cs?rev=411501&r1=411500&r2=411501&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/PhraseScorer.cs Sat Jun  3 19:41:13 2006
@@ -13,12 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using Lucene.Net.Index;
+
 namespace Lucene.Net.Search
 {
 	
-	abstract class PhraseScorer:Scorer
+	abstract class PhraseScorer : Scorer
 	{
 		private Weight weight;
 		protected internal byte[] norms;
@@ -36,7 +38,7 @@
 		{
 			this.norms = norms;
 			this.weight = weight;
-			this.value_Renamed = weight.Value;
+			this.value_Renamed = weight.GetValue();
 			
 			// convert tps to a list
 			for (int i = 0; i < tps.Length; i++)

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,16 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using TermEnum = Lucene.Net.Index.TermEnum;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+
 namespace Lucene.Net.Search
 {
 	
-	/// <summary>A Query that matches documents containing terms with a specified prefix. </summary>
+	/// <summary>A Query that matches documents containing terms with a specified prefix. A PrefixQuery
+	/// is built by QueryParser for input like <code>app*</code>. 
+	/// </summary>
 	[Serializable]
-	public class PrefixQuery:Query
+	public class PrefixQuery : Query
 	{
 		private Term prefix;
 		
@@ -40,7 +45,7 @@
 		
 		public override Query Rewrite(IndexReader reader)
 		{
-			BooleanQuery query = new BooleanQuery();
+			BooleanQuery query = new BooleanQuery(true);
 			TermEnum enumerator = reader.Terms(prefix);
 			try
 			{
@@ -53,7 +58,7 @@
 					{
 						TermQuery tq = new TermQuery(term); // found a match
 						tq.SetBoost(GetBoost()); // set the boost
-						query.Add(tq, false, false); // add to query
+						query.Add(tq, BooleanClause.Occur.SHOULD); // add to query
 						//System.out.println("added " + term);
 					}
 					else
@@ -70,11 +75,6 @@
 			return query;
 		}
 		
-		public override Query Combine(Query[] queries)
-		{
-			return Query.MergeBooleanQueries(queries);
-		}
-		
 		/// <summary>Prints a user-readable version of this query. </summary>
 		public override System.String ToString(System.String field)
 		{
@@ -86,17 +86,26 @@
 			}
 			buffer.Append(prefix.Text());
 			buffer.Append('*');
-			if (GetBoost() != 1.0f)
-			{
-                System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
-                nfi.NumberDecimalDigits = 1;
-
-				buffer.Append("^");
-				buffer.Append(GetBoost().ToString("N", nfi));
-			}
+			buffer.Append(ToStringUtils.Boost(GetBoost()));
 			return buffer.ToString();
 		}
-		override public System.Object Clone()
+		
+		/// <summary>Returns true iff <code>o</code> is equal to this. </summary>
+		public  override bool Equals(System.Object o)
+		{
+			if (!(o is PrefixQuery))
+				return false;
+			PrefixQuery other = (PrefixQuery) o;
+			return (this.GetBoost() == other.GetBoost()) && this.prefix.Equals(other.prefix);
+		}
+		
+		/// <summary>Returns a hash code value for this object.</summary>
+		public override int GetHashCode()
+		{
+			return BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0) ^ prefix.GetHashCode();
+		}
+        // {{Aroush-1.9}} Do we need this?!
+        override public System.Object Clone()
 		{
 			return null;
 		}

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2002-2004 The Apache Software Foundation
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using IndexReader = Lucene.Net.Index.IndexReader;
+
 namespace Lucene.Net.Search
 {
 	
@@ -27,14 +29,14 @@
 	/// <li> {@link WildcardQuery}
 	/// <li> {@link PhraseQuery}
 	/// <li> {@link PrefixQuery}
-	/// <li> {@link PhrasePrefixQuery}
+	/// <li> {@link MultiPhraseQuery}
 	/// <li> {@link FuzzyQuery}
 	/// <li> {@link RangeQuery}
-	/// <li> {@link Lucene.Net.Search.Spans.SpanQuery}
+	/// <li> {@link Lucene.Net.search.spans.SpanQuery}
 	/// </ul>
 	/// <p>A parser for queries is contained in:
 	/// <ul>
-	/// <li>{@link Lucene.Net.QueryParser.QueryParser QueryParser}
+	/// <li>{@link Lucene.Net.queryParser.QueryParser QueryParser}
 	/// </ul>
 	/// </summary>
 	[Serializable]
@@ -60,11 +62,18 @@
 			return boost;
 		}
 		
-		/// <summary>Prints a query to a string, with <code>Field</code> as the default Field
-		/// for terms.  <p>The representation used is one that is readable by
-		/// {@link Lucene.Net.QueryParser.QueryParser QueryParser}
-		/// (although, if the query was created by the parser, the printed
-		/// representation may not be exactly what was parsed).
+		/// <summary>Prints a query to a string, with <code>field</code> as the default field
+		/// for terms.  <p>The representation used is one that is supposed to be readable
+		/// by {@link Lucene.Net.queryParser.QueryParser QueryParser}. However,
+		/// there are the following limitations:
+		/// <ul>
+		/// <li>If the query was created by the parser, the printed
+		/// representation may not be exactly what was parsed. For example,
+		/// characters that need to be escaped will be represented without
+		/// the required backslash.</li>
+		/// <li>Some of the more complicated queries (e.g. span queries)
+		/// don't have a representation that can be parsed by QueryParser.</li>
+		/// </ul>
 		/// </summary>
 		public abstract System.String ToString(System.String field);
 		
@@ -83,7 +92,7 @@
 			throw new System.NotSupportedException();
 		}
 		
-		/// <summary>Expert: Constructs an initializes a Weight for a top-level query. </summary>
+		/// <summary>Expert: Constructs and initializes a Weight for a top-level query. </summary>
 		public virtual Weight Weight(Searcher searcher)
 		{
 			Query query = searcher.Rewrite(this);
@@ -94,7 +103,10 @@
 			return weight;
 		}
 		
-		/// <summary>Expert: called to re-write queries into primitive queries. </summary>
+		/// <summary>Expert: called to re-write queries into primitive queries. For example,
+		/// a PrefixQuery will be rewritten into a BooleanQuery that consists
+		/// of TermQuerys.
+		/// </summary>
 		public virtual Query Rewrite(IndexReader reader)
 		{
 			return this;
@@ -102,11 +114,74 @@
 		
 		/// <summary>Expert: called when re-writing queries under MultiSearcher.
 		/// 
-		/// <p>Only implemented by derived queries, with no
-		/// {@link #CreateWeight(Searcher)} implementatation.
+		/// Create a single query suitable for use by all subsearchers (in 1-1
+		/// correspondence with queries). This is an optimization of the OR of
+		/// all queries. We handle the common optimization cases of equal
+		/// queries and overlapping clauses of boolean OR queries (as generated
+		/// by MultiTermQuery.rewrite() and RangeQuery.rewrite()).
+		/// Be careful overriding this method as queries[0] determines which
+		/// method will be called and is not necessarily of the same type as
+		/// the other queries.
 		/// </summary>
 		public virtual Query Combine(Query[] queries)
 		{
+			System.Collections.Hashtable uniques = new System.Collections.Hashtable();
+			for (int i = 0; i < queries.Length; i++)
+			{
+				Query query = queries[i];
+				BooleanClause[] clauses = null;
+				// check if we can split the query into clauses
+				bool splittable = (query is BooleanQuery);
+				if (splittable)
+				{
+					BooleanQuery bq = (BooleanQuery) query;
+					splittable = bq.IsCoordDisabled();
+					clauses = bq.GetClauses();
+					for (int j = 0; splittable && j < clauses.Length; j++)
+					{
+						splittable = (clauses[j].GetOccur() == BooleanClause.Occur.SHOULD);
+					}
+				}
+				if (splittable)
+				{
+					for (int j = 0; j < clauses.Length; j++)
+					{
+                        Query tmp = clauses[j].GetQuery();
+						uniques.Add(tmp, tmp);
+					}
+				}
+				else
+				{
+                    if (uniques.Contains(query) == false)
+                    {
+                        uniques.Add(query, query);
+                    }
+				}
+			}
+			// optimization: if we have just one query, just return it
+			if (uniques.Count == 1)
+			{
+                System.Collections.IDictionaryEnumerator iter = uniques.GetEnumerator();
+                iter.MoveNext();
+                return iter.Value as Query;
+			}
+			System.Collections.IDictionaryEnumerator it = uniques.GetEnumerator();
+			BooleanQuery result = new BooleanQuery(true);
+			while (it.MoveNext())
+			{
+				result.Add((Query) it.Value, BooleanClause.Occur.SHOULD);
+			}
+			return result;
+		}
+		
+		/// <summary> Expert: adds all terms occuring in this query to the terms set. Only
+		/// works if this query is in its {@link #rewrite rewritten} form.
+		/// 
+		/// </summary>
+		/// <throws>  UnsupportedOperationException if this query is not yet rewritten </throws>
+		public virtual void  ExtractTerms(System.Collections.Hashtable terms)
+		{
+			// needs to be implemented by query subclasses
 			throw new System.NotSupportedException();
 		}
 		
@@ -128,12 +203,13 @@
 				}
 			}
 			
-            BooleanQuery result = new BooleanQuery();
+			bool coordDisabled = queries.Length == 0 ? false : ((BooleanQuery) queries[0]).IsCoordDisabled();
+			BooleanQuery result = new BooleanQuery(coordDisabled);
             foreach (BooleanClause booleanClause in allClauses.Keys)
             {
                 result.Add(booleanClause);
             }
-            return result;
+			return result;
 		}
 		
 		/// <summary>Expert: Returns the Similarity implementation to be used for this query.
@@ -151,7 +227,7 @@
 		{
 			try
 			{
-				return (Query) this.MemberwiseClone();
+				return (Query) base.MemberwiseClone();
 			}
 			catch (System.Exception e)
 			{

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,9 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using System.Runtime.InteropServices;
 using IndexReader = Lucene.Net.Index.IndexReader;
+
 namespace Lucene.Net.Search
 {
 	
@@ -24,18 +26,18 @@
 	/// index using this filter are much faster.
 	/// 
 	/// <p> This could be used, for example, with a {@link RangeQuery} on a suitably
-	/// formatted date Field to implement date filtering.  One could re-use a single
+	/// formatted date field to implement date filtering.  One could re-use a single
 	/// QueryFilter that matches, e.g., only documents modified within the last
 	/// week.  The QueryFilter and RangeQuery would only need to be reconstructed
 	/// once per day.
 	/// 
 	/// </summary>
-	/// <version>  $Id: QueryFilter.java,v 1.6 2004/05/08 19:54:12 ehatcher Exp $
+	/// <version>  $Id: QueryFilter.java 328729 2005-10-26 21:05:35Z yonik $
 	/// </version>
 	[Serializable]
-	public class QueryFilter:Filter
+	public class QueryFilter : Filter
 	{
-		private class AnonymousClassHitCollector:HitCollector
+		private class AnonymousClassHitCollector : HitCollector
 		{
 			public AnonymousClassHitCollector(System.Collections.BitArray bits, QueryFilter enclosingInstance)
 			{
@@ -107,6 +109,18 @@
 		public override System.String ToString()
 		{
 			return "QueryFilter(" + query + ")";
+		}
+		
+		public  override bool Equals(System.Object o)
+		{
+			if (!(o is QueryFilter))
+				return false;
+			return this.query.Equals(((QueryFilter) o).query);
+		}
+		
+		public override int GetHashCode()
+		{
+			return query.GetHashCode() ^ (unchecked((int) 0x923F64B9L));     // {{Aroush-1.9}} Is this OK?!
 		}
 	}
 }

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,11 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using Analyzer = Lucene.Net.Analysis.Analyzer;
 using Token = Lucene.Net.Analysis.Token;
 using TokenStream = Lucene.Net.Analysis.TokenStream;
 using TermFreqVector = Lucene.Net.Index.TermFreqVector;
+
 namespace Lucene.Net.Search
 {
 	
@@ -81,7 +83,7 @@
 				for (int i = 0; i < queryTerms.Length; i++)
 				{
 					System.String term = queryTerms[i];
-                    System.Object tmpPosition = tmpSet[term];
+					System.Object tmpPosition = tmpSet[term];
 					if (tmpPosition == null)
 					{
 						tmpSet[term] = (System.Int32) j++;
@@ -95,7 +97,7 @@
 						tmpFreqs[position] = (System.Int32) (integer + 1);
 					}
 				}
-                terms = (System.String[]) tmpList.ToArray(typeof(System.String));
+				terms = (System.String[]) tmpList.ToArray(typeof(System.String));
 				//termFreqs = (int[])tmpFreqs.toArray(termFreqs);
 				termFreqs = new int[tmpFreqs.Count];
 				int i2 = 0;

Added: 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=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeFilter.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RangeFilter.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+using IndexReader = Lucene.Net.Index.IndexReader;
+using Term = Lucene.Net.Index.Term;
+using TermDocs = Lucene.Net.Index.TermDocs;
+using TermEnum = Lucene.Net.Index.TermEnum;
+
+namespace Lucene.Net.Search
+{
+	
+	/// <summary> A Filter that restricts search results to a range of values in a given
+	/// field.
+	/// 
+	/// <p>
+	/// This code borrows heavily from {@link RangeQuery}, but is implemented as a Filter
+	/// (much like {@link DateFilter}).
+	/// </p>
+	/// </summary>
+	[Serializable]
+	public class RangeFilter : Filter
+	{
+		
+		private System.String fieldName;
+		private System.String lowerTerm;
+		private System.String upperTerm;
+		private bool includeLower;
+		private bool includeUpper;
+		
+		/// <param name="fieldName">The field this range applies to
+		/// </param>
+		/// <param name="lowerTerm">The lower bound on this range
+		/// </param>
+		/// <param name="upperTerm">The upper bound on this range
+		/// </param>
+		/// <param name="includeLower">Does this range include the lower bound?
+		/// </param>
+		/// <param name="includeUpper">Does this range include the upper bound?
+		/// </param>
+		/// <throws>  IllegalArgumentException if both terms are null or if </throws>
+		/// <summary>  lowerTerm is null and includeLower is true (similar for upperTerm
+		/// and includeUpper)
+		/// </summary>
+		public RangeFilter(System.String fieldName, System.String lowerTerm, System.String upperTerm, bool includeLower, bool includeUpper)
+		{
+			this.fieldName = fieldName;
+			this.lowerTerm = lowerTerm;
+			this.upperTerm = upperTerm;
+			this.includeLower = includeLower;
+			this.includeUpper = includeUpper;
+			
+			if (null == lowerTerm && null == upperTerm)
+			{
+				throw new System.ArgumentException("At least one value must be non-null");
+			}
+			if (includeLower && null == lowerTerm)
+			{
+				throw new System.ArgumentException("The lower bound must be non-null to be inclusive");
+			}
+			if (includeUpper && null == upperTerm)
+			{
+				throw new System.ArgumentException("The upper bound must be non-null to be inclusive");
+			}
+		}
+		
+		/// <summary> Constructs a filter for field <code>fieldName</code> matching
+		/// less than or equal to <code>upperTerm</code>.
+		/// </summary>
+		public static RangeFilter Less(System.String fieldName, System.String upperTerm)
+		{
+			return new RangeFilter(fieldName, null, upperTerm, false, true);
+		}
+		
+		/// <summary> Constructs a filter for field <code>fieldName</code> matching
+		/// greater than or equal to <code>lowerTerm</code>.
+		/// </summary>
+		public static RangeFilter More(System.String fieldName, System.String lowerTerm)
+		{
+			return new RangeFilter(fieldName, lowerTerm, null, true, false);
+		}
+		
+		/// <summary> Returns a BitSet with true for documents which should be
+		/// permitted in search results, and false for those that should
+		/// not.
+		/// </summary>
+		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, "")));
+			
+			try
+			{
+				
+				if (enumerator.Term() == null)
+				{
+					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());
+				}
+				finally
+				{
+					termDocs.Close();
+				}
+			}
+			finally
+			{
+				enumerator.Close();
+			}
+			
+			return bits;
+		}
+		
+		public override System.String ToString()
+		{
+			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
+			buffer.Append(fieldName);
+			buffer.Append(":");
+			buffer.Append(includeLower?"[":"{");
+			if (null != lowerTerm)
+			{
+				buffer.Append(lowerTerm);
+			}
+			buffer.Append("-");
+			if (null != upperTerm)
+			{
+				buffer.Append(upperTerm);
+			}
+			buffer.Append(includeUpper ? "]" : "}");
+			return buffer.ToString();
+		}
+		
+		/// <summary>Returns true if <code>o</code> is equal to this. </summary>
+		public  override bool Equals(System.Object o)
+		{
+			if (this == o)
+				return true;
+			if (!(o is RangeFilter))
+				return false;
+			RangeFilter other = (RangeFilter) o;
+			
+			if (!this.fieldName.Equals(other.fieldName) || this.includeLower != other.includeLower || this.includeUpper != other.includeUpper)
+			{
+				return false;
+			}
+			if (this.lowerTerm != null ? !this.lowerTerm.Equals(other.lowerTerm) : other.lowerTerm != null)
+				return false;
+			if (this.upperTerm != null ? !this.upperTerm.Equals(other.upperTerm) : other.upperTerm != null)
+				return false;
+			return true;
+		}
+		
+		/// <summary>Returns a hash code value for this object.</summary>
+		public override int GetHashCode()
+		{
+			int h = fieldName.GetHashCode();
+			h ^= (lowerTerm != null ? lowerTerm.GetHashCode() : unchecked((int) 0xB6ECE882));           // {{Aroush-1.9}} is this OK?!
+			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?!
+			return h;
+		}
+	}
+}
\ No newline at end of file

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,17 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using TermEnum = Lucene.Net.Index.TermEnum;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+
 namespace Lucene.Net.Search
 {
 	
-	/// <summary> A Query that matches documents within an exclusive range.
+	/// <summary> A Query that matches documents within an exclusive range. A RangeQuery
+	/// is built by QueryParser for input like <code>[010 TO 120]</code>.
 	/// 
 	/// </summary>
-	/// <version>  $Id: RangeQuery.java,v 1.12 2004/03/29 22:48:03 cutting Exp $
+	/// <version>  $Id: RangeQuery.java 329381 2005-10-29 09:26:21Z ehatcher $
 	/// </version>
 	[Serializable]
 	public class RangeQuery : Query
@@ -36,7 +40,7 @@
 		/// <code>lowerTerm</code> but less than <code>upperTerm</code>.
 		/// There must be at least one term and either term may be null,
 		/// 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.
+		/// two terms, both terms <b>must</b> be for the same field.
 		/// </summary>
 		public RangeQuery(Term lowerTerm, Term upperTerm, bool inclusive)
 		{
@@ -46,7 +50,7 @@
 			}
 			if (lowerTerm != null && upperTerm != null && lowerTerm.Field() != upperTerm.Field())
 			{
-				throw new System.ArgumentException("Both terms must be for the same Field");
+				throw new System.ArgumentException("Both terms must be for the same field");
 			}
 			
 			// if we have a lowerTerm, start there. otherwise, start at beginning
@@ -63,19 +67,10 @@
 			this.inclusive = inclusive;
 		}
 		
-		/// <summary> FIXME: Describe <code>rewrite</code> method here.
-		/// 
-		/// </summary>
-		/// <param name="reader">an <code>IndexReader</code> value
-		/// </param>
-		/// <returns> a <code>Query</code> value
-		/// </returns>
-		/// <exception cref=""> IOException if an error occurs
-		/// </exception>
 		public override Query Rewrite(IndexReader reader)
 		{
 			
-			BooleanQuery query = new BooleanQuery();
+			BooleanQuery query = new BooleanQuery(true);
 			TermEnum enumerator = reader.Terms(lowerTerm);
 			
 			try
@@ -106,7 +101,7 @@
 							}
 							TermQuery tq = new TermQuery(term); // found a match
 							tq.SetBoost(GetBoost()); // set the boost
-							query.Add(tq, false, false); // add to query
+							query.Add(tq, BooleanClause.Occur.SHOULD); // add to query
 						}
 					}
 					else
@@ -123,12 +118,7 @@
 			return query;
 		}
 		
-		public override Query Combine(Query[] queries)
-		{
-			return Query.MergeBooleanQueries(queries);
-		}
-		
-		/// <summary>Returns the Field name for this query </summary>
+		/// <summary>Returns the field name for this query </summary>
 		public virtual System.String GetField()
 		{
 			return (lowerTerm != null?lowerTerm.Field():upperTerm.Field());
@@ -163,20 +153,41 @@
 				buffer.Append(":");
 			}
 			buffer.Append(inclusive?"[":"{");
-			buffer.Append(lowerTerm != null?lowerTerm.Text():"null");
+			buffer.Append(lowerTerm != null ? lowerTerm.Text() : "null");
 			buffer.Append(" TO ");
-			buffer.Append(upperTerm != null?upperTerm.Text():"null");
-			buffer.Append(inclusive?"]":"}");
-			if (GetBoost() != 1.0f)
-			{
-                System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
-                nfi.NumberDecimalDigits = 1;
-
-				buffer.Append("^");
-				buffer.Append(GetBoost().ToString("N", nfi));
-			}
+			buffer.Append(upperTerm != null ? upperTerm.Text() : "null");
+			buffer.Append(inclusive ? "]" : "}");
+			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)
+		{
+			if (this == o)
+				return true;
+			if (!(o is RangeQuery))
+				return false;
+			
+			RangeQuery other = (RangeQuery) o;
+			if (this.GetBoost() != other.GetBoost())
+				return false;
+			if (this.inclusive != other.inclusive)
+				return false;
+			// one of lowerTerm and upperTerm can be null
+			if (this.lowerTerm != null?!this.lowerTerm.Equals(other.lowerTerm):other.lowerTerm != null)
+				return false;
+			if (this.upperTerm != null?!this.upperTerm.Equals(other.upperTerm):other.upperTerm != null)
+				return false;
+			return true;
+		}
+		
+		/// <summary>Returns a hash code value for this object.</summary>
+		public override int GetHashCode()
+		{
+			return BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0) ^ (lowerTerm != null ? lowerTerm.GetHashCode():0) ^ (upperTerm != null?upperTerm.GetHashCode() : 0) ^ (this.inclusive ? 1 : 0);
+		}
+		// {{Aroush-1.9}} Do we need this?!
 		override public System.Object Clone()
 		{
 			return null;

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Regex/RegexQuery.cs?rev=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexQuery.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexQuery.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+using IndexReader = Lucene.Net.Index.IndexReader;
+using Term = Lucene.Net.Index.Term;
+using FilteredTermEnum = Lucene.Net.Search.FilteredTermEnum;
+using MultiTermQuery = Lucene.Net.Search.MultiTermQuery;
+
+namespace Lucene.Net.Search.Regex
+{
+	
+	[Serializable]
+	public class RegexQuery : MultiTermQuery
+	{
+		public RegexQuery(Term term) : base(term)
+		{
+		}
+		
+		protected internal override FilteredTermEnum GetEnum(IndexReader reader)
+		{
+			Term term = new Term(GetTerm().Field(), GetTerm().Text());
+			return new RegexTermEnum(reader, term);
+		}
+		
+		public  override bool Equals(System.Object o)
+		{
+			if (o is RegexQuery)
+				return base.Equals(o);
+			
+			return false;
+		}
+		
+        public override int GetHashCode()
+		{
+			return base.GetHashCode();
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexTermEnum.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Regex/RegexTermEnum.cs?rev=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexTermEnum.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/RegexTermEnum.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+using IndexReader = Lucene.Net.Index.IndexReader;
+using Term = Lucene.Net.Index.Term;
+using FilteredTermEnum = Lucene.Net.Search.FilteredTermEnum;
+using Pattern = System.Text.RegularExpressions.Regex;
+
+namespace Lucene.Net.Search.Regex
+{
+	
+	public class RegexTermEnum : FilteredTermEnum
+	{
+		private System.String field = "";
+		private System.String pre = "";
+		internal bool endEnum = false;
+		private Pattern pattern;
+		
+		public RegexTermEnum(IndexReader reader, Term term) : base()
+		{
+			field = term.Field();
+			System.String text = term.Text();
+			
+			pattern = new Pattern(text);
+			
+			// Find the first regex character position, to find the
+			// maximum prefix to use for term enumeration
+			int index = 0;
+			while (index < text.Length)
+			{
+				char c = text[index];
+				
+				if (!System.Char.IsLetterOrDigit(c))
+					break;
+				
+				index++;
+			}
+			
+			pre = text.Substring(0, (index) - (0));
+			
+			SetEnum(reader.Terms(new Term(term.Field(), pre)));
+		}
+		
+		protected internal override bool TermCompare(Term term)
+		{
+			if ((System.Object) field == (System.Object) term.Field())
+			{
+				System.String searchText = term.Text();
+				if (searchText.StartsWith(pre))
+				{
+                    return pattern.Match(searchText).Success;
+				}
+			}
+			endEnum = true;
+			return false;
+		}
+		
+		public override float Difference()
+		{
+			// TODO: adjust difference based on distance of searchTerm.text() and term().text()
+			return 1.0f;
+		}
+		
+		public override bool EndEnum()
+		{
+			return endEnum;
+		}
+		
+		public override void  Close()
+		{
+			base.Close();
+			field = null;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/SpanRegexQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Regex/SpanRegexQuery.cs?rev=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/SpanRegexQuery.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Regex/SpanRegexQuery.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+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 Query = Lucene.Net.Search.Query;
+using TermQuery = Lucene.Net.Search.TermQuery;
+using SpanOrQuery = Lucene.Net.Search.Spans.SpanOrQuery;
+using SpanQuery = Lucene.Net.Search.Spans.SpanQuery;
+using SpanTermQuery = Lucene.Net.Search.Spans.SpanTermQuery;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+
+namespace Lucene.Net.Search.Regex
+{
+	
+	[Serializable]
+	public class SpanRegexQuery:SpanQuery
+	{
+		virtual public Term Term
+		{
+			get
+			{
+				return term;
+			}
+			
+		}
+		private Term term;
+		
+		public SpanRegexQuery(Term term)
+		{
+			this.term = term;
+		}
+		
+		public override Query Rewrite(IndexReader reader)
+		{
+			Query orig = new RegexQuery(term).Rewrite(reader);
+			
+			// RegexQuery (via MultiTermQuery).rewrite always returns a BooleanQuery
+			BooleanQuery bq = (BooleanQuery) orig;
+			
+			BooleanClause[] clauses = bq.GetClauses();
+			SpanQuery[] sqs = new SpanQuery[clauses.Length];
+			for (int i = 0; i < clauses.Length; i++)
+			{
+				BooleanClause clause = clauses[i];
+				
+				// Clauses from RegexQuery.rewrite are always TermQuery's
+				TermQuery tq = (TermQuery) clause.GetQuery();
+				
+				sqs[i] = new SpanTermQuery(tq.GetTerm());
+				sqs[i].SetBoost(tq.GetBoost());
+			}
+			
+			SpanOrQuery query = new SpanOrQuery(sqs);
+			query.SetBoost(orig.GetBoost());
+			
+			return query;
+		}
+		
+		public override Lucene.Net.Search.Spans.Spans GetSpans(IndexReader reader)
+		{
+			throw new System.NotSupportedException("Query should have been rewritten");
+		}
+		
+		public override System.String GetField()
+		{
+			return term.Field();
+		}
+		
+		public override System.Collections.ICollection GetTerms()
+		{
+			System.Collections.ArrayList terms = new System.Collections.ArrayList();
+            terms.Add(term);
+			return terms;
+		}
+		
+		public  override bool Equals(System.Object o)
+		{
+			if (this == o)
+				return true;
+			if (o == null || GetType() != o.GetType())
+				return false;
+			
+			SpanRegexQuery that = (SpanRegexQuery) o;
+			
+			return term.Equals(that.term) && GetBoost() == that.GetBoost();
+		}
+		
+		public override int GetHashCode()
+		{
+			return term.GetHashCode();
+		}
+		
+		public override System.String ToString(System.String field)
+		{
+			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
+			buffer.Append("spanRegexQuery(");
+			buffer.Append(term);
+			buffer.Append(")");
+			buffer.Append(ToStringUtils.Boost(GetBoost()));
+			return buffer.ToString();
+		}
+	}
+}
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteSearchable.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/RemoteSearchable.cs?rev=411501&r1=411500&r2=411501&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteSearchable.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/RemoteSearchable.cs Sat Jun  3 19:41:13 2006
@@ -13,13 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
 using Document = Lucene.Net.Documents.Document;
 using Term = Lucene.Net.Index.Term;
+
 namespace Lucene.Net.Search
 {
 	
-	/// <summary>A remote searchable implementation. </summary>
+	/// <summary> A remote searchable implementation.
+	/// 
+	/// </summary>
+	/// <version>  $Id: RemoteSearchable.java 351472 2005-12-01 21:15:53Z bmesser $
+	/// </version>
 	[Serializable]
 	public class RemoteSearchable : System.MarshalByRefObject, Lucene.Net.Search.Searchable
 	{
@@ -27,16 +33,23 @@
 		private Lucene.Net.Search.Searchable local;
 		
 		/// <summary>Constructs and exports a remote searcher. </summary>
-		public RemoteSearchable(Lucene.Net.Search.Searchable local):base()
+		public RemoteSearchable(Lucene.Net.Search.Searchable local) : base()
 		{
 			this.local = local;
 		}
 		
+		// this implementation should be removed when the deprecated
+		// Searchable#search(Query,Filter,HitCollector) is removed
 		public virtual void  Search(Query query, Filter filter, HitCollector results)
 		{
 			local.Search(query, filter, results);
 		}
 		
+		public virtual void  Search(Weight weight, Filter filter, HitCollector results)
+		{
+			local.Search(weight, filter, results);
+		}
+		
 		public virtual void  Close()
 		{
 			local.Close();
@@ -47,21 +60,41 @@
 			return local.DocFreq(term);
 		}
 		
+		
+		public virtual int[] DocFreqs(Term[] terms)
+		{
+			return local.DocFreqs(terms);
+		}
+		
 		public virtual int MaxDoc()
 		{
 			return local.MaxDoc();
 		}
 		
+		// this implementation should be removed when the deprecated
+		// Searchable#search(Query,Filter,int) is removed
 		public virtual TopDocs Search(Query query, Filter filter, int n)
 		{
 			return local.Search(query, filter, n);
 		}
 		
+		public virtual TopDocs Search(Weight weight, Filter filter, int n)
+		{
+			return local.Search(weight, filter, n);
+		}
+		
+		// this implementation should be removed when the deprecated
+		// Searchable#search(Query,Filter,int,Sort) is removed
 		public virtual TopFieldDocs Search(Query query, Filter filter, int n, Sort sort)
 		{
 			return local.Search(query, filter, n, sort);
 		}
 		
+		public virtual TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort)
+		{
+			return local.Search(weight, filter, n, sort);
+		}
+		
 		public virtual Document Doc(int i)
 		{
 			return local.Doc(i);
@@ -72,11 +105,18 @@
 			return local.Rewrite(original);
 		}
 		
+		// this implementation should be removed when the deprecated
+		// Searchable#explain(Query,int) is removed
 		public virtual Explanation Explain(Query query, int doc)
 		{
 			return local.Explain(query, doc);
 		}
-
+		
+		public virtual Explanation Explain(Weight weight, int doc)
+		{
+			return local.Explain(weight, doc);
+		}
+		
         public override System.Object InitializeLifetimeService()
         {
             long initialLeaseTime, sponsorshipTimeout, renewOnCallTime;
@@ -111,13 +151,24 @@
 		{
 			System.Runtime.Remoting.RemotingConfiguration.Configure("Lucene.Net.Search.RemoteSearchable.config");
 			System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Http.HttpChannel(1099));
+			System.String indexName = null;
+			
+			if (args != null && args.Length == 1)
+				indexName = args[0];
+			
+			if (indexName == null)
+			{
+				System.Console.Out.WriteLine("Usage: Lucene.Net.search.RemoteSearchable <index>");
+				return ;
+			}
+			
 			// create and install a security manager
-			if (false) //{{}}// if (System.getSecurityManager() == null)    // {{Aroush-1.4.3}} >> 'java.lang.System.getSecurityManager()'
+			if (true)  // if (System_Renamed.getSecurityManager() == null) // {{Aroush-1.4.3}} Do we need this line?!
 			{
-				//{{}}// System.setSecurityManager(new RMISecurityManager());   // {{Aroush-1.4.3}} >> 'java.lang.System.setSecurityManager()' and 'java.rmi.RMISecurityManager.RMISecurityManager()'
+				// System_Renamed.setSecurityManager(new RMISecurityManager());     // {{Aroush-1.4.3}} Do we need this line?!
 			}
 			
-			Lucene.Net.Search.Searchable local = new IndexSearcher(args[0]);
+			Lucene.Net.Search.Searchable local = new IndexSearcher(indexName);
 			RemoteSearchable impl = new RemoteSearchable(local);
 			
 			// bind the implementation to "Searchable"

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqExclScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ReqExclScorer.cs?rev=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqExclScorer.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqExclScorer.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+
+namespace Lucene.Net.Search
+{
+	
+	
+	/// <summary>A Scorer for queries with a required subscorer and an excluding (prohibited) subscorer.
+	/// <br>
+	/// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)},
+	/// and it uses the skipTo() on the given scorers.
+	/// </summary>
+	public class ReqExclScorer : Scorer
+	{
+		private Scorer reqScorer, exclScorer;
+		
+		/// <summary>Construct a <code>ReqExclScorer</code>.</summary>
+		/// <param name="reqScorer">The scorer that must match, except where
+		/// </param>
+		/// <param name="exclScorer">indicates exclusion.
+		/// </param>
+		public ReqExclScorer(Scorer reqScorer, Scorer exclScorer) : base(null)
+		{ // No similarity used.
+			this.reqScorer = reqScorer;
+			this.exclScorer = exclScorer;
+		}
+		
+		private bool firstTime = true;
+		
+		public override bool Next()
+		{
+			if (firstTime)
+			{
+				if (!exclScorer.Next())
+				{
+					exclScorer = null; // exhausted at start
+				}
+				firstTime = false;
+			}
+			if (reqScorer == null)
+			{
+				return false;
+			}
+			if (!reqScorer.Next())
+			{
+				reqScorer = null; // exhausted, nothing left
+				return false;
+			}
+			if (exclScorer == null)
+			{
+				return true; // reqScorer.next() already returned true
+			}
+			return ToNonExcluded();
+		}
+		
+		/// <summary>Advance to non excluded doc.
+		/// <br>On entry:
+		/// <ul>
+		/// <li>reqScorer != null,
+		/// <li>exclScorer != null,
+		/// <li>reqScorer was advanced once via next() or skipTo()
+		/// and reqScorer.doc() may still be excluded.
+		/// </ul>
+		/// Advances reqScorer a non excluded required doc, if any.
+		/// </summary>
+		/// <returns> true iff there is a non excluded required doc.
+		/// </returns>
+		private bool ToNonExcluded()
+		{
+			int exclDoc = exclScorer.Doc();
+			do 
+			{
+				int reqDoc = reqScorer.Doc(); // may be excluded
+				if (reqDoc < exclDoc)
+				{
+					return true; // reqScorer advanced to before exclScorer, ie. not excluded
+				}
+				else if (reqDoc > exclDoc)
+				{
+					if (!exclScorer.SkipTo(reqDoc))
+					{
+						exclScorer = null; // exhausted, no more exclusions
+						return true;
+					}
+					exclDoc = exclScorer.Doc();
+					if (exclDoc > reqDoc)
+					{
+						return true; // not excluded
+					}
+				}
+			}
+			while (reqScorer.Next());
+			reqScorer = null; // exhausted, nothing left
+			return false;
+		}
+		
+		public override int Doc()
+		{
+			return reqScorer.Doc(); // reqScorer may be null when next() or skipTo() already return false
+		}
+		
+		/// <summary>Returns the score of the current document matching the query.
+		/// Initially invalid, until {@link #Next()} is called the first time.
+		/// </summary>
+		/// <returns> The score of the required scorer.
+		/// </returns>
+		public override float Score()
+		{
+			return reqScorer.Score(); // reqScorer may be null when next() or skipTo() already return false
+		}
+		
+		/// <summary>Skips to the first match beyond the current whose document number is
+		/// greater than or equal to a given target.
+		/// <br>When this method is used the {@link #Explain(int)} method should not be used.
+		/// </summary>
+		/// <param name="target">The target document number.
+		/// </param>
+		/// <returns> true iff there is such a match.
+		/// </returns>
+		public override bool SkipTo(int target)
+		{
+			if (firstTime)
+			{
+				firstTime = false;
+				if (!exclScorer.SkipTo(target))
+				{
+					exclScorer = null; // exhausted
+				}
+			}
+			if (reqScorer == null)
+			{
+				return false;
+			}
+			if (exclScorer == null)
+			{
+				return reqScorer.SkipTo(target);
+			}
+			if (!reqScorer.SkipTo(target))
+			{
+				reqScorer = null;
+				return false;
+			}
+			return ToNonExcluded();
+		}
+		
+		public override Explanation Explain(int doc)
+		{
+			Explanation res = new Explanation();
+			if (exclScorer.SkipTo(doc) && (exclScorer.Doc() == doc))
+			{
+				res.SetDescription("excluded");
+			}
+			else
+			{
+				res.SetDescription("not excluded");
+				res.AddDetail(reqScorer.Explain(doc));
+			}
+			return res;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqOptSumScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ReqOptSumScorer.cs?rev=411501&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqOptSumScorer.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ReqOptSumScorer.cs Sat Jun  3 19:41:13 2006
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * 
+ * Licensed 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 System;
+
+namespace Lucene.Net.Search
+{
+	
+	/// <summary>A Scorer for queries with a required part and an optional part.
+	/// Delays skipTo() on the optional part until a score() is needed.
+	/// <br>
+	/// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)}.
+	/// </summary>
+	public class ReqOptSumScorer : Scorer
+	{
+		/// <summary>The scorers passed from the constructor.
+		/// These are set to null as soon as their next() or skipTo() returns false.
+		/// </summary>
+		private Scorer reqScorer;
+		private Scorer optScorer;
+		
+		/// <summary>Construct a <code>ReqOptScorer</code>.</summary>
+		/// <param name="reqScorer">The required scorer. This must match.
+		/// </param>
+		/// <param name="optScorer">The optional scorer. This is used for scoring only.
+		/// </param>
+		public ReqOptSumScorer(Scorer reqScorer, Scorer optScorer) : base(null)
+		{ // No similarity used.
+			this.reqScorer = reqScorer;
+			this.optScorer = optScorer;
+		}
+		
+		private bool firstTimeOptScorer = true;
+		
+		public override bool Next()
+		{
+			return reqScorer.Next();
+		}
+		
+		public override bool SkipTo(int target)
+		{
+			return reqScorer.SkipTo(target);
+		}
+		
+		public override int Doc()
+		{
+			return reqScorer.Doc();
+		}
+		
+		/// <summary>Returns the score of the current document matching the query.
+		/// Initially invalid, until {@link #Next()} is called the first time.
+		/// </summary>
+		/// <returns> The score of the required scorer, eventually increased by the score
+		/// of the optional scorer when it also matches the current document.
+		/// </returns>
+		public override float Score()
+		{
+			int curDoc = reqScorer.Doc();
+			float reqScore = reqScorer.Score();
+			if (firstTimeOptScorer)
+			{
+				firstTimeOptScorer = false;
+				if (!optScorer.SkipTo(curDoc))
+				{
+					optScorer = null;
+					return reqScore;
+				}
+			}
+			else if (optScorer == null)
+			{
+				return reqScore;
+			}
+			else if ((optScorer.Doc() < curDoc) && (!optScorer.SkipTo(curDoc)))
+			{
+				optScorer = null;
+				return reqScore;
+			}
+			// assert (optScorer != null) && (optScorer.doc() >= curDoc);
+			return (optScorer.Doc() == curDoc)?reqScore + optScorer.Score():reqScore;
+		}
+		
+		/// <summary>Explain the score of a document.</summary>
+		/// <todo>  Also show the total score. </todo>
+		/// <summary> See BooleanScorer.explain() on how to do this.
+		/// </summary>
+		public override Explanation Explain(int doc)
+		{
+			Explanation res = new Explanation();
+			res.SetDescription("required, optional");
+			res.AddDetail(reqScorer.Explain(doc));
+			res.AddDetail(optScorer.Explain(doc));
+			return res;
+		}
+	}
+}
\ No newline at end of file

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDoc.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ScoreDoc.cs?rev=411501&r1=411500&r2=411501&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDoc.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ScoreDoc.cs Sat Jun  3 19:41:13 2006
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
+
 namespace Lucene.Net.Search
 {
 	
@@ -27,7 +29,7 @@
 		public float score;
 		
 		/// <summary>Expert: A hit document's number.</summary>
-		/// <seealso cref="Searcher#Doc(int)">
+		/// <seealso cref="Searcher.Doc(int)">
 		/// </seealso>
 		public int doc;
 		

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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
+
 namespace Lucene.Net.Search
 {
 	
@@ -27,10 +29,10 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: ScoreDocComparator.java,v 1.5 2004/05/19 23:05:27 tjones Exp $
+	/// <version>  $Id: ScoreDocComparator.java 150348 2004-05-19 23:05:27Z tjones $
 	/// </version>
 	public struct ScoreDocComparator_Fields
-    {
+	{
 		/// <summary>Special comparator for sorting hits according to computed relevance (document score). </summary>
 		public readonly static ScoreDocComparator RELEVANCE;
 		/// <summary>Special comparator for sorting hits according to index order (document number). </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=411501&r1=411500&r2=411501&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 Sat Jun  3 19:41:13 2006
@@ -13,16 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 using System;
+
 namespace Lucene.Net.Search
 {
 	
-	/// <summary>Expert: Implements scoring for a class of queries. </summary>
+	/// <summary>Expert: Common scoring functionality for different types of queries.
+	/// <br>A <code>Scorer</code> either iterates over documents matching a query,
+	/// or provides an explanation of the score for a query for a given document.
+	/// <br>Document scores are computed using a given <code>Similarity</code> implementation.
+	/// </summary>
 	public abstract class Scorer
 	{
 		private Similarity similarity;
 		
-		/// <summary>Constructs a Scorer. </summary>
+		/// <summary>Constructs a Scorer.</summary>
+		/// <param name="similarity">The <code>Similarity</code> implementation used by this scorer.
+		/// </param>
 		protected internal Scorer(Similarity similarity)
 		{
 			this.similarity = similarity;
@@ -34,7 +42,11 @@
 			return this.similarity;
 		}
 		
-		/// <summary>Scores all documents and passes them to a collector. </summary>
+		/// <summary>Scores and collects all matching documents.</summary>
+		/// <param name="hc">The collector to which all matching documents are passed through
+		/// {@link HitCollector#Collect(int, float)}.
+		/// <br>When this method is used the {@link #Explain(int)} method should not be used.
+		/// </param>
 		public virtual void  Score(HitCollector hc)
 		{
 			while (Next())
@@ -43,37 +55,70 @@
 			}
 		}
 		
-		/// <summary>Advance to the next document matching the query.  Returns true iff there
-		/// is another match. 
+		/// <summary>Expert: Collects matching documents in a range.  Hook for optimization.
+		/// Note that {@link #Next()} must be called once before this method is called
+		/// for the first time.
 		/// </summary>
+		/// <param name="hc">The collector to which all matching documents are passed through
+		/// {@link HitCollector#Collect(int, float)}.
+		/// </param>
+		/// <param name="max">Do not score documents past this.
+		/// </param>
+		/// <returns> true if more matching documents may remain.
+		/// </returns>
+		protected internal virtual bool Score(HitCollector hc, int max)
+		{
+			while (Doc() < max)
+			{
+				hc.Collect(Doc(), Score());
+				if (!Next())
+					return false;
+			}
+			return true;
+		}
+		
+		/// <summary>Advances to the next document matching the query.</summary>
+		/// <returns> true iff there is another document matching the query.
+		/// <br>When this method is used the {@link #Explain(int)} method should not be used.
+		/// </returns>
 		public abstract bool Next();
 		
-		/// <summary>Returns the current document number.  Initially invalid, until {@link
-		/// #Next()} is called the first time. 
+		/// <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.  Initially invalid, until
-		/// {@link #Next()} is called the first time. 
+		/// <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 first match beyond the current whose document number is
-		/// greater than or equal to <i>target</i>. <p>Returns true iff there is such
-		/// a match.  <p>Behaves as if written: <pre>
-		/// boolean SkipTo(int target) {
+		/// greater than or equal to a given target.
+		/// <br>When this method is used the {@link #Explain(int)} method should not be used.
+		/// </summary>
+		/// <param name="target">The target document number.
+		/// </param>
+		/// <returns> true iff there is such a match.
+		/// <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.
-		/// </summary>
+		/// </pre>Most implementations are considerably more efficient than that.
+		/// </returns>
 		public abstract bool SkipTo(int target);
 		
-		/// <summary>Returns an explanation of the score for <code>doc</code>. </summary>
+		/// <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.
+		/// </summary>
+		/// <param name="doc">The document number for the explanation.
+		/// </param>
 		public abstract Explanation Explain(int doc);
 	}
 }