You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2014/09/22 01:56:46 UTC

[4/4] git commit: More work on Lucene.Net.Queries

More work on Lucene.Net.Queries


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/5506faf0
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/5506faf0
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/5506faf0

Branch: refs/heads/master
Commit: 5506faf0c1397018c8f7e24ffcfe4d99823d86b7
Parents: cf1df6b
Author: Itamar Syn-Hershko <it...@code972.com>
Authored: Mon Sep 22 02:55:29 2014 +0300
Committer: Itamar Syn-Hershko <it...@code972.com>
Committed: Mon Sep 22 02:55:29 2014 +0300

----------------------------------------------------------------------
 src/Lucene.Net.Core/Search/Query.cs             |   4 +-
 src/Lucene.Net.Queries/BooleanFilter.cs         |   2 +-
 src/Lucene.Net.Queries/BoostingQuery.cs         | 344 ++++----
 src/Lucene.Net.Queries/CommonTermsQuery.cs      |  21 +-
 src/Lucene.Net.Queries/CustomScoreQuery.cs      | 821 ++++++++++---------
 src/Lucene.Net.Queries/Function/BoostedQuery.cs |  41 +-
 .../Function/FunctionQuery.cs                   |  51 +-
 .../Function/FunctionValues.cs                  |  18 +-
 src/Lucene.Net.Queries/Function/ValueSource.cs  |   7 +-
 .../Function/ValueSources/ByteFieldSource.cs    |   6 +-
 .../ValueSources/BytesRefFieldSource.cs         |   2 +-
 .../ValueSources/DoubleConstValueSource.cs      | 257 +++---
 .../Function/ValueSources/EnumFieldSource.cs    |   8 +-
 .../Function/ValueSources/FloatFieldSource.cs   | 213 +++--
 .../Function/ValueSources/IDFValueSource.cs     |  97 ++-
 .../Function/ValueSources/IfFunction.cs         | 299 ++++---
 .../Function/ValueSources/IntFieldSource.cs     | 294 ++++---
 .../ValueSources/JoinDocFreqValueSource.cs      | 166 ++--
 .../ValueSources/LinearFloatFunction.cs         | 145 ++--
 .../Function/ValueSources/LiteralValueSource.cs | 205 +++--
 .../Function/ValueSources/LongFieldSource.cs    | 301 ++++---
 .../Function/ValueSources/MaxDocValueSource.cs  |  85 +-
 .../Function/ValueSources/MaxFloatFunction.cs   |  57 +-
 .../Function/ValueSources/MinFloatFunction.cs   |  57 +-
 .../Function/ValueSources/MultiBoolFunction.cs  | 236 +++---
 .../Function/ValueSources/MultiFloatFunction.cs | 241 +++---
 .../Function/ValueSources/MultiFunction.cs      |   6 +-
 .../Function/ValueSources/MultiValueSource.cs   |   4 +-
 .../Function/ValueSources/NormValueSource.cs    | 183 ++---
 .../Function/ValueSources/NumDocsValueSource.cs |  60 +-
 .../Function/ValueSources/OrdFieldSource.cs     | 270 +++---
 .../Function/ValueSources/PowFloatFunction.cs   |  49 +-
 .../ValueSources/ProductFloatFunction.cs        |  45 +-
 .../Function/ValueSources/QueryValueSource.cs   | 590 ++++++-------
 .../ValueSources/RangeMapFloatFunction.cs       | 193 +++--
 .../ValueSources/ReciprocalFloatFunction.cs     | 181 ++--
 .../ValueSources/ReverseOrdFieldSource.cs       | 168 ++--
 .../Function/ValueSources/ScaleFloatFunction.cs |  54 +-
 .../Function/ValueSources/ShortFieldSource.cs   | 243 +++---
 .../Function/ValueSources/SimpleBoolFunction.cs | 129 ++-
 .../ValueSources/SimpleFloatFunction.cs         |  79 +-
 .../Function/ValueSources/SingleFunction.cs     |  65 +-
 .../Function/ValueSources/SumFloatFunction.cs   |  43 +-
 .../ValueSources/SumTotalTermFreqValueSource.cs | 173 ++--
 .../Function/ValueSources/TFValueSource.cs      |  16 +-
 .../ValueSources/TermFreqValueSource.cs         | 306 ++++---
 .../ValueSources/TotalTermFreqValueSource.cs    | 168 ++--
 .../Function/ValueSources/VectorValueSource.cs  | 471 ++++++-----
 src/Lucene.Net.Queries/TermsFilter.cs           |   4 +-
 49 files changed, 3633 insertions(+), 3845 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Core/Search/Query.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Search/Query.cs b/src/Lucene.Net.Core/Search/Query.cs
index 8e084ff..6111cba 100644
--- a/src/Lucene.Net.Core/Search/Query.cs
+++ b/src/Lucene.Net.Core/Search/Query.cs
@@ -105,7 +105,7 @@ namespace Lucene.Net.Search
         /// Expert: adds all terms occurring in this query to the terms set. Only
         /// works if this query is in its <seealso cref="#rewrite rewritten"/> form.
         /// </summary>
-        /// <exception cref="UnsupportedOperationException"> if this query is not yet rewritten </exception>
+        /// <exception cref="InvalidOperationException"> if this query is not yet rewritten </exception>
         public virtual void ExtractTerms(ISet<Term> terms)
         {
             // needs to be implemented by query subclasses
@@ -148,7 +148,7 @@ namespace Lucene.Net.Search
             {
                 return false;
             }
-            Query other = (Query)obj;
+            var other = (Query)obj;
             if (Number.FloatToIntBits(boost) != Number.FloatToIntBits(other.boost))
             {
                 return false;

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/BooleanFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/BooleanFilter.cs b/src/Lucene.Net.Queries/BooleanFilter.cs
index 65b6d4e..7136fe1 100644
--- a/src/Lucene.Net.Queries/BooleanFilter.cs
+++ b/src/Lucene.Net.Queries/BooleanFilter.cs
@@ -164,7 +164,7 @@ namespace Lucene.Net.Queries
                 return false;
             }
 
-            BooleanFilter other = (BooleanFilter)obj;
+            var other = (BooleanFilter)obj;
             return clauses.Equals(other.clauses);
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/BoostingQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/BoostingQuery.cs b/src/Lucene.Net.Queries/BoostingQuery.cs
index 8212f98..7a73eb5 100644
--- a/src/Lucene.Net.Queries/BoostingQuery.cs
+++ b/src/Lucene.Net.Queries/BoostingQuery.cs
@@ -1,178 +1,172 @@
-namespace org.apache.lucene.queries
-{
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
 
-	/*
-	 * 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 = org.apache.lucene.index.IndexReader;
-	using org.apache.lucene.search;
-
-	/// <summary>
-	/// The BoostingQuery class can be used to effectively demote results that match a given query. 
-	/// Unlike the "NOT" clause, this still selects documents that contain undesirable terms, 
-	/// but reduces their overall score:
-	/// 
-	///     Query balancedQuery = new BoostingQuery(positiveQuery, negativeQuery, 0.01f);
-	/// In this scenario the positiveQuery contains the mandatory, desirable criteria which is used to 
-	/// select all matching documents, and the negativeQuery contains the undesirable elements which 
-	/// are simply used to lessen the scores. Documents that match the negativeQuery have their score 
-	/// multiplied by the supplied "boost" parameter, so this should be less than 1 to achieve a 
-	/// demoting effect
-	/// 
-	/// This code was originally made available here: [WWW] http://marc.theaimsgroup.com/?l=lucene-user&m=108058407130459&w=2
-	/// and is documented here: http://wiki.apache.org/lucene-java/CommunityContributions
-	/// </summary>
-	public class BoostingQuery : Query
-	{
-		private readonly float boost; // the amount to boost by
-		private readonly Query match; // query to match
-		private readonly Query context; // boost when matches too
-
-		public BoostingQuery(Query match, Query context, float boost)
-		{
-		  this.match = match;
-		  this.context = context.clone(); // clone before boost
-		  this.boost = boost;
-		  this.context.Boost = 0.0f; // ignore context-only matches
-		}
-
-//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-//ORIGINAL LINE: @Override public Query rewrite(org.apache.lucene.index.IndexReader reader) throws java.io.IOException
-		public override Query rewrite(IndexReader reader)
-		{
-		  BooleanQuery result = new BooleanQueryAnonymousInnerClassHelper(this);
-
-		  result.add(match, BooleanClause.Occur.MUST);
-		  result.add(context, BooleanClause.Occur.SHOULD);
-
-		  return result;
-		}
-
-		private class BooleanQueryAnonymousInnerClassHelper : BooleanQuery
-		{
-			private readonly BoostingQuery outerInstance;
-
-			public BooleanQueryAnonymousInnerClassHelper(BoostingQuery outerInstance)
-			{
-				this.outerInstance = outerInstance;
-			}
-
-//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-//ORIGINAL LINE: @Override public Weight CreateWeight(IndexSearcher searcher) throws java.io.IOException
-			public override Weight CreateWeight(IndexSearcher searcher)
-			{
-			  return new BooleanWeightAnonymousInnerClassHelper(this, searcher);
-			}
-
-			private class BooleanWeightAnonymousInnerClassHelper : BooleanWeight
-			{
-				private readonly BooleanQueryAnonymousInnerClassHelper outerInstance;
-
-				public BooleanWeightAnonymousInnerClassHelper(BooleanQueryAnonymousInnerClassHelper outerInstance, IndexSearcher searcher) : base(searcher, false)
-				{
-					this.outerInstance = outerInstance;
-				}
-
-
-				public override float coord(int overlap, int max)
-				{
-				  switch (overlap)
-				  {
-
-				  case 1: // matched only one clause
-					return 1.0f; // use the score as-is
-
-				  case 2: // matched both clauses
-					return outerInstance.outerInstance.boost; // multiply by boost
-
-				  default:
-					return 0.0f;
-
-				  }
-				}
-			}
-		}
-
-		public override int GetHashCode()
-		{
-		  const int prime = 31;
-		  int result = base.GetHashCode();
-		  result = prime * result + Number.FloatToIntBits(boost);
-		  result = prime * result + ((context == null) ? 0 : context.GetHashCode());
-		  result = prime * result + ((match == null) ? 0 : match.GetHashCode());
-		  return result;
-		}
-
-		public override bool Equals(object obj)
-		{
-		  if (this == obj)
-		  {
-			return true;
-		  }
-		  if (obj == null)
-		  {
-			return false;
-		  }
-		  if (this.GetType() != obj.GetType())
-		  {
-			return false;
-		  }
-
-		  if (!base.Equals(obj))
-		  {
-			return false;
-		  }
-
-		  BoostingQuery other = (BoostingQuery) obj;
-		  if (Number.FloatToIntBits(boost) != Number.FloatToIntBits(other.boost))
-		  {
-			return false;
-		  }
-
-		  if (context == null)
-		  {
-			if (other.context != null)
-			{
-			  return false;
-			}
-		  }
-		  else if (!context.Equals(other.context))
-		  {
-			return false;
-		  }
-
-		  if (match == null)
-		  {
-			if (other.match != null)
-			{
-			  return false;
-			}
-		  }
-		  else if (!match.Equals(other.match))
-		  {
-			return false;
-		  }
-		  return true;
-		}
-
-		public override string ToString(string field)
-		{
-		  return match.ToString(field) + "/" + context.ToString(field);
-		}
-	}
+namespace Lucene.Net.Queries
+{
 
+    /*
+     * 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.
+     */
+
+    /// <summary>
+    /// The BoostingQuery class can be used to effectively demote results that match a given query. 
+    /// Unlike the "NOT" clause, this still selects documents that contain undesirable terms, 
+    /// but reduces their overall score:
+    /// 
+    ///     Query balancedQuery = new BoostingQuery(positiveQuery, negativeQuery, 0.01f);
+    /// In this scenario the positiveQuery contains the mandatory, desirable criteria which is used to 
+    /// select all matching documents, and the negativeQuery contains the undesirable elements which 
+    /// are simply used to lessen the scores. Documents that match the negativeQuery have their score 
+    /// multiplied by the supplied "boost" parameter, so this should be less than 1 to achieve a 
+    /// demoting effect
+    /// 
+    /// This code was originally made available here: [WWW] http://marc.theaimsgroup.com/?l=lucene-user&m=108058407130459&w=2
+    /// and is documented here: http://wiki.apache.org/lucene-java/CommunityContributions
+    /// </summary>
+    public class BoostingQuery : Query
+    {
+        private readonly float boost; // the amount to boost by
+        private readonly Query match; // query to match
+        private readonly Query context; // boost when matches too
+
+        public BoostingQuery(Query match, Query context, float boost)
+        {
+            this.match = match;
+            this.context = context.Clone(); // clone before boost
+            this.boost = boost;
+            this.context.Boost = 0.0f; // ignore context-only matches
+        }
+
+        public override Query Rewrite(IndexReader reader)
+        {
+            BooleanQuery result = new BooleanQueryAnonymousInnerClassHelper(this);
+            result.Add(match, BooleanClause.Occur.MUST);
+            result.Add(context, BooleanClause.Occur.SHOULD);
+            return result;
+        }
+
+        private class BooleanQueryAnonymousInnerClassHelper : BooleanQuery
+        {
+            private readonly BoostingQuery outerInstance;
+
+            public BooleanQueryAnonymousInnerClassHelper(BoostingQuery outerInstance)
+            {
+                this.outerInstance = outerInstance;
+            }
+
+            public override Weight CreateWeight(IndexSearcher searcher)
+            {
+                return new BooleanWeightAnonymousInnerClassHelper(this, searcher);
+            }
+
+            private class BooleanWeightAnonymousInnerClassHelper : BooleanWeight
+            {
+                private readonly BooleanQueryAnonymousInnerClassHelper outerInstance;
+
+                public BooleanWeightAnonymousInnerClassHelper(BooleanQueryAnonymousInnerClassHelper outerInstance, IndexSearcher searcher)
+                    : base(searcher, false)
+                {
+                    this.outerInstance = outerInstance;
+                }
+
+                public override float Coord(int overlap, int max)
+                {
+                    switch (overlap)
+                    {
+
+                        case 1: // matched only one clause
+                            return 1.0f; // use the score as-is
+
+                        case 2: // matched both clauses
+                            return outerInstance.outerInstance.boost; // multiply by boost
+
+                        default:
+                            return 0.0f;
+
+                    }
+                }
+            }
+        }
+
+        public override int GetHashCode()
+        {
+            const int prime = 31;
+            int result = base.GetHashCode();
+            result = prime * result + Number.FloatToIntBits(boost);
+            result = prime * result + ((context == null) ? 0 : context.GetHashCode());
+            result = prime * result + ((match == null) ? 0 : match.GetHashCode());
+            return result;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (this == obj)
+            {
+                return true;
+            }
+            if (obj == null)
+            {
+                return false;
+            }
+            if (this.GetType() != obj.GetType())
+            {
+                return false;
+            }
+
+            if (!base.Equals(obj))
+            {
+                return false;
+            }
+
+            var other = (BoostingQuery)obj;
+            if (Number.FloatToIntBits(boost) != Number.FloatToIntBits(other.boost))
+            {
+                return false;
+            }
+
+            if (context == null)
+            {
+                if (other.context != null)
+                {
+                    return false;
+                }
+            }
+            else if (!context.Equals(other.context))
+            {
+                return false;
+            }
+
+            if (match == null)
+            {
+                if (other.match != null)
+                {
+                    return false;
+                }
+            }
+            else if (!match.Equals(other.match))
+            {
+                return false;
+            }
+            return true;
+        }
+
+        public override string ToString(string field)
+        {
+            return match.ToString(field) + "/" + context.ToString(field);
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/CommonTermsQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/CommonTermsQuery.cs b/src/Lucene.Net.Queries/CommonTermsQuery.cs
index 70f093d..a31f248 100644
--- a/src/Lucene.Net.Queries/CommonTermsQuery.cs
+++ b/src/Lucene.Net.Queries/CommonTermsQuery.cs
@@ -67,7 +67,7 @@ namespace Lucene.Net.Queries
         protected internal readonly BooleanClause.Occur highFreqOccur;
         protected internal float lowFreqBoost = 1.0f;
         protected internal float highFreqBoost = 1.0f;
-       
+
 
         /// <summary>
         /// Creates a new <seealso cref="CommonTermsQuery"/>
@@ -174,16 +174,15 @@ namespace Lucene.Net.Queries
             {
                 return (int)minNrShouldMatch;
             }
-            return Math.Round(minNrShouldMatch * numOptional);
+            return (int)Math.Round(minNrShouldMatch * numOptional);
         }
 
-         protected internal virtual Query BuildQuery(int maxDoc, TermContext[] contextArray, Term[] queryTerms)
+        protected internal virtual Query BuildQuery(int maxDoc, TermContext[] contextArray, Term[] queryTerms)
         {
-            BooleanQuery lowFreq = new BooleanQuery(disableCoord);
-            BooleanQuery highFreq = new BooleanQuery(disableCoord);
-            highFreq.Boost = highFreqBoost;
+            var lowFreq = new BooleanQuery(disableCoord);
+            var highFreq = new BooleanQuery(disableCoord) { Boost = highFreqBoost };
             lowFreq.Boost = lowFreqBoost;
-            BooleanQuery query = new BooleanQuery(true);
+            var query = new BooleanQuery(true);
             for (int i = 0; i < queryTerms.Length; i++)
             {
                 TermContext termContext = contextArray[i];
@@ -230,7 +229,7 @@ namespace Lucene.Net.Queries
                 {
                     foreach (BooleanClause booleanClause in highFreq)
                     {
-                        booleanClause.Occur = BooleanClause.Occur.MUST;
+                        booleanClause.Occur_ = BooleanClause.Occur.MUST;
                     }
                 }
                 highFreq.Boost = Boost;
@@ -347,14 +346,14 @@ namespace Lucene.Net.Queries
         public float HighFreqMinimumNumberShouldMatch { get; set; }
 
 
-        public override void ExtractTerms(HashSet<Term> terms)
+        public override void ExtractTerms(ISet<Term> terms)
         {
             terms.AddAll(this.terms);
         }
 
         public override string ToString(string field)
         {
-            StringBuilder buffer = new StringBuilder();
+            var buffer = new StringBuilder();
             bool needParens = (Boost != 1.0) || (LowFreqMinimumNumberShouldMatch > 0);
             if (needParens)
             {
@@ -419,7 +418,7 @@ namespace Lucene.Net.Queries
             {
                 return false;
             }
-            CommonTermsQuery other = (CommonTermsQuery)obj;
+            var other = (CommonTermsQuery)obj;
             if (disableCoord != other.disableCoord)
             {
                 return false;

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/CustomScoreQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/CustomScoreQuery.cs b/src/Lucene.Net.Queries/CustomScoreQuery.cs
index 016b87c..770422b 100644
--- a/src/Lucene.Net.Queries/CustomScoreQuery.cs
+++ b/src/Lucene.Net.Queries/CustomScoreQuery.cs
@@ -25,415 +25,416 @@ namespace Lucene.Net.Queries
 	 * See the License for the specific language governing permissions and
 	 * limitations under the License.
 	 */
-    /// <summary>
-	/// Query that sets document score as a programmatic function of several (sub) scores:
-	/// <ol>
-	///    <li>the score of its subQuery (any query)</li>
-	///    <li>(optional) the score of its <seealso cref="FunctionQuery"/> (or queries).</li>
-	/// </ol>
-	/// Subclasses can modify the computation by overriding <seealso cref="#getCustomScoreProvider"/>.
-	/// 
-	/// @lucene.experimental
-	/// </summary>
-	public class CustomScoreQuery : Query
-	{
-
-	  private Query subQuery;
-	  private Query[] scoringQueries; // never null (empty array if there are no valSrcQueries).
-	  private bool strict = false; // if true, valueSource part of query does not take part in weights normalization.
-
-	  /// <summary>
-	  /// Create a CustomScoreQuery over input subQuery. </summary>
-	  /// <param name="subQuery"> the sub query whose scored is being customized. Must not be null.  </param>
-	  public CustomScoreQuery(Query subQuery) : this(subQuery, new FunctionQuery[0])
-	  {
-	  }
-
-	  /// <summary>
-	  /// Create a CustomScoreQuery over input subQuery and a <seealso cref="FunctionQuery"/>. </summary>
-	  /// <param name="subQuery"> the sub query whose score is being customized. Must not be null. </param>
-	  /// <param name="scoringQuery"> a value source query whose scores are used in the custom score
-	  /// computation.  This parameter is optional - it can be null. </param>
-	  public CustomScoreQuery(Query subQuery, FunctionQuery scoringQuery) : this(subQuery, scoringQuery != null ? new FunctionQuery[] {scoringQuery} : new FunctionQuery[0]) // don't want an array that contains a single null..
-	  {
-	  }
-
-	  /// <summary>
-	  /// Create a CustomScoreQuery over input subQuery and a <seealso cref="FunctionQuery"/>. </summary>
-	  /// <param name="subQuery"> the sub query whose score is being customized. Must not be null. </param>
-	  /// <param name="scoringQueries"> value source queries whose scores are used in the custom score
-	  /// computation.  This parameter is optional - it can be null or even an empty array. </param>
-	  public CustomScoreQuery(Query subQuery, params FunctionQuery[] scoringQueries)
-	  {
-		this.subQuery = subQuery;
-		this.scoringQueries = scoringQueries != null? scoringQueries : new Query[0];
-		if (subQuery == null)
-		{
-			throw new System.ArgumentException("<subquery> must not be null!");
-		}
-	  }
-
-	  /*(non-Javadoc) @see org.apache.lucene.search.Query#rewrite(org.apache.lucene.index.IndexReader) */
-	  public override Query Rewrite(IndexReader reader)
-	  {
-		CustomScoreQuery clone = null;
-
-		Query sq = subQuery.Rewrite(reader);
-		if (sq != subQuery)
-		{
-		  clone = Clone();
-		  clone.subQuery = sq;
-		}
-
-		for (int i = 0; i < scoringQueries.Length; i++)
-		{
-		  Query v = scoringQueries[i].Rewrite(reader);
-		  if (v != scoringQueries[i])
-		  {
-			if (clone == null)
-			{
-				clone = Clone();
-			}
-			clone.scoringQueries[i] = v;
-		  }
-		}
-
-		return clone ?? this;
-	  }
-
-	  /*(non-Javadoc) @see org.apache.lucene.search.Query#extractTerms(java.util.Set) */
-	  public override void ExtractTerms(HashSet<Term> terms)
-	  {
-		subQuery.ExtractTerms(terms);
-		foreach (Query scoringQuery in scoringQueries)
-		{
-		  scoringQuery.ExtractTerms(terms);
-		}
-	  }
-
-	  /*(non-Javadoc) @see org.apache.lucene.search.Query#clone() */
-	  public override CustomScoreQuery Clone()
-	  {
-		CustomScoreQuery clone = (CustomScoreQuery)base.Clone();
-		clone.subQuery = subQuery.Clone();
-		clone.scoringQueries = new Query[scoringQueries.Length];
-		for (int i = 0; i < scoringQueries.Length; i++)
-		{
-		  clone.scoringQueries[i] = scoringQueries[i].Clone();
-		}
-		return clone;
-	  }
-
-	  /* (non-Javadoc) @see org.apache.lucene.search.Query#toString(java.lang.String) */
-	  public override string ToString(string field)
-	  {
-		StringBuilder sb = (new StringBuilder(name())).Append("(");
-		sb.Append(subQuery.ToString(field));
-		foreach (Query scoringQuery in scoringQueries)
-		{
-		  sb.Append(", ").Append(scoringQuery.ToString(field));
-		}
-		sb.Append(")");
-		sb.Append(strict?" STRICT" : "");
-		return sb.ToString() + ToStringUtils.Boost(Boost);
-	  }
-
-	  /// <summary>
-	  /// Returns true if <code>o</code> is equal to this. </summary>
-	  public override bool Equals(object o)
-	  {
-		if (this == o)
-		{
-		  return true;
-		}
-		if (!base.Equals(o))
-		{
-		  return false;
-		}
-		if (this.GetType() != o.GetType())
-		{
-		  return false;
-		}
-		CustomScoreQuery other = (CustomScoreQuery)o;
-		if (this.Boost != other.Boost || !this.subQuery.Equals(other.subQuery) || this.strict != other.strict || this.scoringQueries.Length != other.scoringQueries.Length)
-		{
-		  return false;
-		}
-		return Arrays.Equals(scoringQueries, other.scoringQueries);
-	  }
-
-	  /// <summary>
-	  /// Returns a hash code value for this object. </summary>
-	  public override int GetHashCode()
-	  {
-		return (this.GetType().GetHashCode() + subQuery.GetHashCode() + Arrays.GetHashCode(scoringQueries)) ^ Number.FloatToIntBits(Boost) ^ (strict ? 1234 : 4321);
-	  }
-
-	  /// <summary>
-	  /// Returns a <seealso cref="CustomScoreProvider"/> that calculates the custom scores
-	  /// for the given <seealso cref="IndexReader"/>. The default implementation returns a default
-	  /// implementation as specified in the docs of <seealso cref="CustomScoreProvider"/>.
-	  /// @since 2.9.2
-	  /// </summary>
-	  protected internal virtual CustomScoreProvider GetCustomScoreProvider(AtomicReaderContext context)
-	  {
-		return new CustomScoreProvider(context);
-	  }
-
-	  //=========================== W E I G H T ============================
-
-	  private class CustomWeight : Weight
-	  {
-		  private readonly CustomScoreQuery outerInstance;
-
-		internal Weight subQueryWeight;
-		internal Weight[] valSrcWeights;
-		internal bool qStrict;
-		internal float queryWeight;
-
-		public CustomWeight(CustomScoreQuery outerInstance, IndexSearcher searcher)
-		{
-			this.outerInstance = outerInstance;
-		  this.subQueryWeight = outerInstance.subQuery.CreateWeight(searcher);
-		  this.valSrcWeights = new Weight[outerInstance.scoringQueries.Length];
-		  for (int i = 0; i < outerInstance.scoringQueries.Length; i++)
-		  {
-			this.valSrcWeights[i] = outerInstance.scoringQueries[i].CreateWeight(searcher);
-		  }
-		  this.qStrict = outerInstance.strict;
-		}
-
-		/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */
-		public override Query Query
-		{
-			get
-			{
-			  return outerInstance;
-			}
-		}
-
-		public override float ValueForNormalization
-		{
-			get
-			{
-			  float sum = subQueryWeight.ValueForNormalization;
-			  foreach (Weight valSrcWeight in valSrcWeights)
-			  {
-				if (qStrict)
-				{
-				  valSrcWeight.ValueForNormalization; // do not include ValueSource part in the query normalization
-				}
-				else
-				{
-				  sum += valSrcWeight.ValueForNormalization;
-				}
-			  }
-			  return sum;
-			}
-		}
-
-		/*(non-Javadoc) @see org.apache.lucene.search.Weight#normalize(float) */
-		public override void Normalize(float norm, float topLevelBoost)
-		{
-		  // note we DONT incorporate our boost, nor pass down any topLevelBoost 
-		  // (e.g. from outer BQ), as there is no guarantee that the CustomScoreProvider's 
-		  // function obeys the distributive law... it might call sqrt() on the subQuery score
-		  // or some other arbitrary function other than multiplication.
-		  // so, instead boosts are applied directly in score()
-		  subQueryWeight.Normalize(norm, 1f);
-		  foreach (Weight valSrcWeight in valSrcWeights)
-		  {
-			if (qStrict)
-			{
-			  valSrcWeight.Normalize(1, 1); // do not normalize the ValueSource part
-			}
-			else
-			{
-			  valSrcWeight.Normalize(norm, 1f);
-			}
-		  }
-		  queryWeight = topLevelBoost * Boost;
-		}
-
-		public override Scorer Scorer(AtomicReaderContext context, Bits acceptDocs)
-		{
-		  Scorer subQueryScorer = subQueryWeight.Scorer(context, acceptDocs);
-		  if (subQueryScorer == null)
-		  {
-			return null;
-		  }
-		  Scorer[] valSrcScorers = new Scorer[valSrcWeights.Length];
-		  for (int i = 0; i < valSrcScorers.Length; i++)
-		  {
-			 valSrcScorers[i] = valSrcWeights[i].Scorer(context, acceptDocs);
-		  }
-		  return new CustomScorer(outerInstance, outerInstance.GetCustomScoreProvider(context), this, queryWeight, subQueryScorer, valSrcScorers);
-		}
-
-	      public override Explanation Explain(AtomicReaderContext context, int doc)
-	      {
-	          Explanation explain = DoExplain(context, doc);
-	          return explain ?? new Explanation(0.0f, "no matching docs");
-	      }
-
-		internal virtual Explanation DoExplain(AtomicReaderContext info, int doc)
-		{
-		  Explanation subQueryExpl = subQueryWeight.Explain(info, doc);
-		  if (!subQueryExpl.Match)
-		  {
-			return subQueryExpl;
-		  }
-		  // match
-		  Explanation[] valSrcExpls = new Explanation[valSrcWeights.Length];
-		  for (int i = 0; i < valSrcWeights.Length; i++)
-		  {
-			valSrcExpls[i] = valSrcWeights[i].Explain(info, doc);
-		  }
-		  Explanation customExp = outerInstance.GetCustomScoreProvider(info).CustomExplain(doc,subQueryExpl,valSrcExpls);
-		  float sc = Boost * customExp.Value;
-		  Explanation res = new ComplexExplanation(true, sc, outerInstance.ToString() + ", product of:");
-		  res.AddDetail(customExp);
-		  res.AddDetail(new Explanation(Boost, "queryBoost")); // actually using the q boost as q weight (== weight value)
-		  return res;
-		}
-
-		public override bool ScoresDocsOutOfOrder()
-		{
-		  return false;
-		}
-	  
-
-
-	  //=========================== S C O R E R ============================
-
-	  /// <summary>
-	  /// A scorer that applies a (callback) function on scores of the subQuery.
-	  /// </summary>
-	  private class CustomScorer : Scorer
-	  {
-		  private readonly CustomScoreQuery outerInstance;
-
-		internal readonly float qWeight;
-		internal readonly Scorer subQueryScorer;
-		internal readonly Scorer[] valSrcScorers;
-		internal readonly CustomScoreProvider provider;
-		internal readonly float[] vScores; // reused in score() to avoid allocating this array for each doc
-
-		// constructor
-		internal CustomScorer(CustomScoreQuery outerInstance, CustomScoreProvider provider, CustomWeight w, float qWeight, Scorer subQueryScorer, Scorer[] valSrcScorers) : base(w)
-		{
-			this.outerInstance = outerInstance;
-		  this.qWeight = qWeight;
-		  this.subQueryScorer = subQueryScorer;
-		  this.valSrcScorers = valSrcScorers;
-		  this.vScores = new float[valSrcScorers.Length];
-		  this.provider = provider;
-		}
-
-		public override int NextDoc()
-		{
-		  int doc = subQueryScorer.NextDoc();
-		  if (doc != NO_MORE_DOCS)
-		  {
-			foreach (Scorer valSrcScorer in valSrcScorers)
-			{
-			  valSrcScorer.Advance(doc);
-			}
-		  }
-		  return doc;
-		}
-
-		public override int DocID()
-		{
-		  return subQueryScorer.DocID();
-		}
-
-		/*(non-Javadoc) @see org.apache.lucene.search.Scorer#score() */
-		public override float Score()
-		{
-		  for (int i = 0; i < valSrcScorers.Length; i++)
-		  {
-			vScores[i] = valSrcScorers[i].Score();
-		  }
-		  return qWeight * provider.customScore(subQueryScorer.docID(), subQueryScorer.score(), vScores);
-		}
-
-		public override int Freq()
-		{
-		  return subQueryScorer.Freq();
-		}
-
-		public override ICollection<ChildScorer> Children
-		{
-			get
-			{
-			  return Collections.Singleton(new ChildScorer(subQueryScorer, "CUSTOM"));
-			}
-		}
-
-		public override int Advance(int target)
-		{
-		  int doc = subQueryScorer.Advance(target);
-		  if (doc != NO_MORE_DOCS)
-		  {
-			foreach (Scorer valSrcScorer in valSrcScorers)
-			{
-			  valSrcScorer.Advance(doc);
-			}
-		  }
-		  return doc;
-		}
-
-		public override long Cost()
-		{
-		  return subQueryScorer.Cost();
-		}
-	  }
-
-	  public override Weight CreateWeight(IndexSearcher searcher)
-	  {
-		return new CustomWeight(this, searcher);
-	  }
-
-	  /// <summary>
-	  /// Checks if this is strict custom scoring.
-	  /// In strict custom scoring, the <seealso cref="ValueSource"/> part does not participate in weight normalization.
-	  /// This may be useful when one wants full control over how scores are modified, and does 
-	  /// not care about normalizing by the <seealso cref="ValueSource"/> part.
-	  /// One particular case where this is useful if for testing this query.   
-	  /// <P>
-	  /// Note: only has effect when the <seealso cref="ValueSource"/> part is not null.
-	  /// </summary>
-	  public virtual bool Strict { get; set; }
-
-
-	  /// <summary>
-	  /// The sub-query that CustomScoreQuery wraps, affecting both the score and which documents match. </summary>
-	  public virtual Query SubQuery
-	  {
-		  get
-		  {
-			return subQuery;
-		  }
-	  }
-
-	  /// <summary>
-	  /// The scoring queries that only affect the score of CustomScoreQuery. </summary>
-	  public virtual Query[] ScoringQueries
-	  {
-		  get
-		  {
-			return scoringQueries;
-		  }
-	  }
-
-	      /// <summary>
-	      /// A short name of this query, used in <seealso cref="#toString(String)"/>.
-	      /// </summary>
-	      public virtual string Name
-	      {
-	          get { return "custom"; }
-	      }
-	  }
 
+    /// <summary>
+    /// Query that sets document score as a programmatic function of several (sub) scores:
+    /// <ol>
+    ///    <li>the score of its subQuery (any query)</li>
+    ///    <li>(optional) the score of its <seealso cref="FunctionQuery"/> (or queries).</li>
+    /// </ol>
+    /// Subclasses can modify the computation by overriding <seealso cref="#getCustomScoreProvider"/>.
+    /// 
+    /// @lucene.experimental
+    /// </summary>
+    public class CustomScoreQuery : Query
+    {
+
+        private Query subQuery;
+        private Query[] scoringQueries; // never null (empty array if there are no valSrcQueries).
+        private bool strict = false; // if true, valueSource part of query does not take part in weights normalization.
+
+        /// <summary>
+        /// Create a CustomScoreQuery over input subQuery. </summary>
+        /// <param name="subQuery"> the sub query whose scored is being customized. Must not be null.  </param>
+        public CustomScoreQuery(Query subQuery) : this(subQuery, new FunctionQuery[0])
+        {
+        }
+
+        /// <summary>
+        /// Create a CustomScoreQuery over input subQuery and a <seealso cref="FunctionQuery"/>. </summary>
+        /// <param name="subQuery"> the sub query whose score is being customized. Must not be null. </param>
+        /// <param name="scoringQuery"> a value source query whose scores are used in the custom score
+        /// computation.  This parameter is optional - it can be null. </param>
+        public CustomScoreQuery(Query subQuery, FunctionQuery scoringQuery)
+            : this(subQuery, scoringQuery != null ? new FunctionQuery[] {scoringQuery} : new FunctionQuery[0])
+            // don't want an array that contains a single null..
+        {
+        }
+
+        /// <summary>
+        /// Create a CustomScoreQuery over input subQuery and a <seealso cref="FunctionQuery"/>. </summary>
+        /// <param name="subQuery"> the sub query whose score is being customized. Must not be null. </param>
+        /// <param name="scoringQueries"> value source queries whose scores are used in the custom score
+        /// computation.  This parameter is optional - it can be null or even an empty array. </param>
+        public CustomScoreQuery(Query subQuery, params FunctionQuery[] scoringQueries)
+        {
+            this.subQuery = subQuery;
+            this.scoringQueries = scoringQueries != null ? scoringQueries : new Query[0];
+            if (subQuery == null)
+            {
+                throw new System.ArgumentException("<subquery> must not be null!");
+            }
+        }
+
+        public override Query Rewrite(IndexReader reader)
+        {
+            CustomScoreQuery clone = null;
+
+            Query sq = subQuery.Rewrite(reader);
+            if (sq != subQuery)
+            {
+                clone = Clone();
+                clone.subQuery = sq;
+            }
+
+            for (int i = 0; i < scoringQueries.Length; i++)
+            {
+                Query v = scoringQueries[i].Rewrite(reader);
+                if (v != scoringQueries[i])
+                {
+                    if (clone == null)
+                    {
+                        clone = Clone();
+                    }
+                    clone.scoringQueries[i] = v;
+                }
+            }
+
+            return clone ?? this;
+        }
+
+        public override void ExtractTerms(ISet<Term> terms)
+        {
+            subQuery.ExtractTerms(terms);
+            foreach (Query scoringQuery in scoringQueries)
+            {
+                scoringQuery.ExtractTerms(terms);
+            }
+        }
+
+        /*(non-Javadoc) @see org.apache.lucene.search.Query#clone() */
+
+        public override CustomScoreQuery Clone()
+        {
+            CustomScoreQuery clone = (CustomScoreQuery) base.Clone();
+            clone.subQuery = subQuery.Clone();
+            clone.scoringQueries = new Query[scoringQueries.Length];
+            for (int i = 0; i < scoringQueries.Length; i++)
+            {
+                clone.scoringQueries[i] = scoringQueries[i].Clone();
+            }
+            return clone;
+        }
+
+        /* (non-Javadoc) @see org.apache.lucene.search.Query#toString(java.lang.String) */
+
+        public override string ToString(string field)
+        {
+            StringBuilder sb = (new StringBuilder(Name)).Append("(");
+            sb.Append(subQuery.ToString(field));
+            foreach (Query scoringQuery in scoringQueries)
+            {
+                sb.Append(", ").Append(scoringQuery.ToString(field));
+            }
+            sb.Append(")");
+            sb.Append(strict ? " STRICT" : "");
+            return sb.ToString() + ToStringUtils.Boost(Boost);
+        }
+
+        /// <summary>
+        /// Returns true if <code>o</code> is equal to this. </summary>
+        public override bool Equals(object o)
+        {
+            if (this == o)
+            {
+                return true;
+            }
+            if (!base.Equals(o))
+            {
+                return false;
+            }
+            if (this.GetType() != o.GetType())
+            {
+                return false;
+            }
+            var other = (CustomScoreQuery) o;
+            if (this.Boost != other.Boost || !this.subQuery.Equals(other.subQuery) || this.strict != other.strict ||
+                this.scoringQueries.Length != other.scoringQueries.Length)
+            {
+                return false;
+            }
+            return Arrays.Equals(scoringQueries, other.scoringQueries);
+        }
+
+        /// <summary>
+        /// Returns a hash code value for this object. </summary>
+        public override int GetHashCode()
+        {
+            return (this.GetType().GetHashCode() + subQuery.GetHashCode() + Arrays.GetHashCode(scoringQueries)) ^
+                   Number.FloatToIntBits(Boost) ^ (strict ? 1234 : 4321);
+        }
+
+        /// <summary>
+        /// Returns a <seealso cref="CustomScoreProvider"/> that calculates the custom scores
+        /// for the given <seealso cref="IndexReader"/>. The default implementation returns a default
+        /// implementation as specified in the docs of <seealso cref="CustomScoreProvider"/>.
+        /// @since 2.9.2
+        /// </summary>
+        protected internal virtual CustomScoreProvider GetCustomScoreProvider(AtomicReaderContext context)
+        {
+            return new CustomScoreProvider(context);
+        }
+
+        //=========================== W E I G H T ============================
+
+        private class CustomWeight : Weight
+        {
+            private readonly CustomScoreQuery outerInstance;
+
+            private readonly Weight subQueryWeight;
+            private readonly Weight[] valSrcWeights;
+            private readonly bool qStrict;
+            private float queryWeight;
+
+            public CustomWeight(CustomScoreQuery outerInstance, IndexSearcher searcher)
+            {
+                this.outerInstance = outerInstance;
+                this.subQueryWeight = outerInstance.subQuery.CreateWeight(searcher);
+                this.valSrcWeights = new Weight[outerInstance.scoringQueries.Length];
+                for (int i = 0; i < outerInstance.scoringQueries.Length; i++)
+                {
+                    this.valSrcWeights[i] = outerInstance.scoringQueries[i].CreateWeight(searcher);
+                }
+                this.qStrict = outerInstance.strict;
+            }
+
+            /*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */
+
+            public override Query Query
+            {
+                get { return outerInstance; }
+            }
+
+            public override float ValueForNormalization
+            {
+                get
+                {
+                    float sum = subQueryWeight.ValueForNormalization;
+                    foreach (Weight valSrcWeight in valSrcWeights)
+                    {
+                        if (qStrict)
+                        {
+                            valSrcWeight.ValueForNormalization;
+                                // do not include ValueSource part in the query normalization
+                        }
+                        else
+                        {
+                            sum += valSrcWeight.ValueForNormalization;
+                        }
+                    }
+                    return sum;
+                }
+            }
+
+            /*(non-Javadoc) @see org.apache.lucene.search.Weight#normalize(float) */
+
+            public override void Normalize(float norm, float topLevelBoost)
+            {
+                // note we DONT incorporate our boost, nor pass down any topLevelBoost 
+                // (e.g. from outer BQ), as there is no guarantee that the CustomScoreProvider's 
+                // function obeys the distributive law... it might call sqrt() on the subQuery score
+                // or some other arbitrary function other than multiplication.
+                // so, instead boosts are applied directly in score()
+                subQueryWeight.Normalize(norm, 1f);
+                foreach (Weight valSrcWeight in valSrcWeights)
+                {
+                    if (qStrict)
+                    {
+                        valSrcWeight.Normalize(1, 1); // do not normalize the ValueSource part
+                    }
+                    else
+                    {
+                        valSrcWeight.Normalize(norm, 1f);
+                    }
+                }
+                queryWeight = topLevelBoost*Boost;
+            }
+
+            public override Scorer Scorer(AtomicReaderContext context, Bits acceptDocs)
+            {
+                Scorer subQueryScorer = subQueryWeight.Scorer(context, acceptDocs);
+                if (subQueryScorer == null)
+                {
+                    return null;
+                }
+                var valSrcScorers = new Scorer[valSrcWeights.Length];
+                for (int i = 0; i < valSrcScorers.Length; i++)
+                {
+                    valSrcScorers[i] = valSrcWeights[i].Scorer(context, acceptDocs);
+                }
+                return new CustomScorer(outerInstance, outerInstance.GetCustomScoreProvider(context), this, queryWeight,
+                    subQueryScorer, valSrcScorers);
+            }
+
+            public override Explanation Explain(AtomicReaderContext context, int doc)
+            {
+                Explanation explain = DoExplain(context, doc);
+                return explain ?? new Explanation(0.0f, "no matching docs");
+            }
+
+            internal virtual Explanation DoExplain(AtomicReaderContext info, int doc)
+            {
+                Explanation subQueryExpl = subQueryWeight.Explain(info, doc);
+                if (!subQueryExpl.IsMatch)
+                {
+                    return subQueryExpl;
+                }
+                // match
+                Explanation[] valSrcExpls = new Explanation[valSrcWeights.Length];
+                for (int i = 0; i < valSrcWeights.Length; i++)
+                {
+                    valSrcExpls[i] = valSrcWeights[i].Explain(info, doc);
+                }
+                Explanation customExp = outerInstance.GetCustomScoreProvider(info)
+                    .CustomExplain(doc, subQueryExpl, valSrcExpls);
+                float sc = Boost*customExp.Value;
+                Explanation res = new ComplexExplanation(true, sc, outerInstance.ToString() + ", product of:");
+                res.AddDetail(customExp);
+                res.AddDetail(new Explanation(Boost, "queryBoost"));
+                    // actually using the q boost as q weight (== weight value)
+                return res;
+            }
+
+            public override bool ScoresDocsOutOfOrder()
+            {
+                return false;
+            }
+
+
+
+            //=========================== S C O R E R ============================
+
+            /// <summary>
+            /// A scorer that applies a (callback) function on scores of the subQuery.
+            /// </summary>
+            private class CustomScorer : Scorer
+            {
+                private readonly CustomScoreQuery outerInstance;
+
+                private readonly float qWeight;
+                private readonly Scorer subQueryScorer;
+                private readonly Scorer[] valSrcScorers;
+                private readonly CustomScoreProvider provider;
+                private readonly float[] vScores; // reused in score() to avoid allocating this array for each doc
+
+                // constructor
+                internal CustomScorer(CustomScoreQuery outerInstance, CustomScoreProvider provider, CustomWeight w,
+                    float qWeight, Scorer subQueryScorer, Scorer[] valSrcScorers) : base(w)
+                {
+                    this.outerInstance = outerInstance;
+                    this.qWeight = qWeight;
+                    this.subQueryScorer = subQueryScorer;
+                    this.valSrcScorers = valSrcScorers;
+                    this.vScores = new float[valSrcScorers.Length];
+                    this.provider = provider;
+                }
+
+                public override int NextDoc()
+                {
+                    int doc = subQueryScorer.NextDoc();
+                    if (doc != NO_MORE_DOCS)
+                    {
+                        foreach (Scorer valSrcScorer in valSrcScorers)
+                        {
+                            valSrcScorer.Advance(doc);
+                        }
+                    }
+                    return doc;
+                }
+
+                public override int DocID()
+                {
+                    return subQueryScorer.DocID();
+                }
+
+                /*(non-Javadoc) @see org.apache.lucene.search.Scorer#score() */
+
+                public override float Score()
+                {
+                    for (int i = 0; i < valSrcScorers.Length; i++)
+                    {
+                        vScores[i] = valSrcScorers[i].Score();
+                    }
+                    return qWeight*provider.CustomScore(subQueryScorer.DocID, subQueryScorer.Score, vScores);
+                }
+
+                public override int Freq()
+                {
+                    return subQueryScorer.Freq();
+                }
+
+                public override ICollection<ChildScorer> Children
+                {
+                    get { return Collections.Singleton(new ChildScorer(subQueryScorer, "CUSTOM")); }
+                }
+
+                public override int Advance(int target)
+                {
+                    int doc = subQueryScorer.Advance(target);
+                    if (doc != NO_MORE_DOCS)
+                    {
+                        foreach (Scorer valSrcScorer in valSrcScorers)
+                        {
+                            valSrcScorer.Advance(doc);
+                        }
+                    }
+                    return doc;
+                }
+
+                public override long Cost()
+                {
+                    return subQueryScorer.Cost();
+                }
+            }
+
+            public override Weight CreateWeight(IndexSearcher searcher)
+            {
+                return new CustomWeight(this, searcher);
+            }
+
+            /// <summary>
+            /// Checks if this is strict custom scoring.
+            /// In strict custom scoring, the <seealso cref="ValueSource"/> part does not participate in weight normalization.
+            /// This may be useful when one wants full control over how scores are modified, and does 
+            /// not care about normalizing by the <seealso cref="ValueSource"/> part.
+            /// One particular case where this is useful if for testing this query.   
+            /// <P>
+            /// Note: only has effect when the <seealso cref="ValueSource"/> part is not null.
+            /// </summary>
+            public virtual bool Strict { get; set; }
+
+
+            /// <summary>
+            /// The sub-query that CustomScoreQuery wraps, affecting both the score and which documents match. </summary>
+            public virtual Query SubQuery
+            {
+                get { return subQuery; }
+            }
+
+            /// <summary>
+            /// The scoring queries that only affect the score of CustomScoreQuery. </summary>
+            public virtual Query[] ScoringQueries
+            {
+                get { return scoringQueries; }
+            }
+
+            /// <summary>
+            /// A short name of this query, used in <seealso cref="#toString(String)"/>.
+            /// </summary>
+            public virtual string Name
+            {
+                get { return "custom"; }
+            }
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/BoostedQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/BoostedQuery.cs b/src/Lucene.Net.Queries/Function/BoostedQuery.cs
index 369617c..157d238 100644
--- a/src/Lucene.Net.Queries/Function/BoostedQuery.cs
+++ b/src/Lucene.Net.Queries/Function/BoostedQuery.cs
@@ -5,7 +5,6 @@ using Lucene.Net.Index;
 using Lucene.Net.Search;
 using Lucene.Net.Support;
 using Lucene.Net.Util;
-using org.apache.lucene.queries.function;
 
 namespace Lucene.Net.Queries.Function
 {
@@ -83,9 +82,9 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly BoostedQuery outerInstance;
 
-            internal readonly IndexSearcher searcher;
-            internal Weight qWeight;
-            internal IDictionary fcontext;
+            private readonly IndexSearcher searcher;
+            private readonly Weight qWeight;
+            private readonly IDictionary fcontext;
 
             //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
             //ORIGINAL LINE: public BoostedWeight(IndexSearcher searcher) throws java.io.IOException
@@ -94,7 +93,7 @@ namespace Lucene.Net.Queries.Function
                 this.outerInstance = outerInstance;
                 this.searcher = searcher;
                 this.qWeight = outerInstance.q.CreateWeight(searcher);
-                this.fcontext = ValueSource.newContext(searcher);
+                this.fcontext = ValueSource.NewContext(searcher);
                 outerInstance.boostVal.CreateWeight(fcontext, searcher);
             }
 
@@ -106,8 +105,6 @@ namespace Lucene.Net.Queries.Function
                 }
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public float getValueForNormalization() throws java.io.IOException
             public override float ValueForNormalization
             {
                 get
@@ -118,7 +115,7 @@ namespace Lucene.Net.Queries.Function
                 }
             }
 
-            public override void normalize(float norm, float topLevelBoost)
+            public override void Normalize(float norm, float topLevelBoost)
             {
                 topLevelBoost *= Boost;
                 qWeight.Normalize(norm, topLevelBoost);
@@ -145,7 +142,7 @@ namespace Lucene.Net.Queries.Function
                 float sc = subQueryExpl.Value * vals.FloatVal(doc);
                 Explanation res = new ComplexExplanation(true, sc, outerInstance.ToString() + ", product of:");
                 res.AddDetail(subQueryExpl);
-                res.AddDetail(vals.explain(doc));
+                res.AddDetail(vals.Explain(doc));
                 return res;
             }
         }
@@ -155,15 +152,13 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly BoostedQuery outerInstance;
 
-            internal readonly BoostedQuery.BoostedWeight weight;
-            internal readonly float qWeight;
-            internal readonly Scorer scorer;
-            internal readonly FunctionValues vals;
-            internal readonly AtomicReaderContext readerContext;
+            private readonly BoostedQuery.BoostedWeight weight;
+            private readonly float qWeight;
+            private readonly Scorer scorer;
+            private readonly FunctionValues vals;
+            private readonly AtomicReaderContext readerContext;
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: private CustomScorer(org.apache.lucene.index.AtomicReaderContext readerContext, BoostedQuery.BoostedWeight w, float qWeight, Scorer scorer, ValueSource vs) throws java.io.IOException
-            internal CustomScorer(BoostedQuery outerInstance, AtomicReaderContext readerContext, BoostedQuery.BoostedWeight w, float qWeight, Scorer scorer, ValueSource vs)
+            private CustomScorer(BoostedQuery outerInstance, AtomicReaderContext readerContext, BoostedQuery.BoostedWeight w, float qWeight, Scorer scorer, ValueSource vs)
                 : base(w)
             {
                 this.outerInstance = outerInstance;
@@ -179,22 +174,16 @@ namespace Lucene.Net.Queries.Function
                 return scorer.DocID();
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public int advance(int target) throws java.io.IOException
             public override int Advance(int target)
             {
                 return scorer.Advance(target);
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public int nextDoc() throws java.io.IOException
             public override int NextDoc()
             {
                 return scorer.NextDoc();
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public float score() throws java.io.IOException
             public override float Score()
             {
                 float score = qWeight * scorer.Score() * vals.FloatVal(scorer.DocID());
@@ -230,7 +219,7 @@ namespace Lucene.Net.Queries.Function
                 float sc = subQueryExpl.Value * vals.FloatVal(doc);
                 Explanation res = new ComplexExplanation(true, sc, outerInstance.ToString() + ", product of:");
                 res.AddDetail(subQueryExpl);
-                res.AddDetail(vals.explain(doc));
+                res.AddDetail(vals.Explain(doc));
                 return res;
             }
 
@@ -243,7 +232,7 @@ namespace Lucene.Net.Queries.Function
 
         public override string ToString(string field)
         {
-            StringBuilder sb = new StringBuilder();
+            var sb = new StringBuilder();
             sb.Append("boost(").Append(q.ToString(field)).Append(',').Append(boostVal).Append(')');
             sb.Append(ToStringUtils.Boost(Boost));
             return sb.ToString();
@@ -255,7 +244,7 @@ namespace Lucene.Net.Queries.Function
             {
                 return false;
             }
-            BoostedQuery other = (BoostedQuery)o;
+            var other = (BoostedQuery)o;
             return this.q.Equals(other.q) && this.boostVal.Equals(other.boostVal);
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/FunctionQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/FunctionQuery.cs b/src/Lucene.Net.Queries/Function/FunctionQuery.cs
index 13044b3..b7b8735 100644
--- a/src/Lucene.Net.Queries/Function/FunctionQuery.cs
+++ b/src/Lucene.Net.Queries/Function/FunctionQuery.cs
@@ -2,8 +2,8 @@
 using System.Collections.Generic;
 using Lucene.Net.Index;
 using Lucene.Net.Search;
+using Lucene.Net.Support;
 using Lucene.Net.Util;
-using org.apache.lucene.queries.function;
 
 namespace Lucene.Net.Queries.Function
 {
@@ -56,7 +56,7 @@ namespace Lucene.Net.Queries.Function
             return this;
         }
 
-        public override void ExtractTerms(HashSet<Term> terms)
+        public override void ExtractTerms(ISet<Term> terms)
         {
         }
 
@@ -64,18 +64,16 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly FunctionQuery outerInstance;
 
-            protected internal readonly IndexSearcher searcher;
+            protected readonly IndexSearcher searcher;
             protected internal float queryNorm;
-            protected internal float queryWeight;
+            protected float queryWeight;
             protected internal readonly IDictionary context;
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: public FunctionWeight(IndexSearcher searcher) throws java.io.IOException
             public FunctionWeight(FunctionQuery outerInstance, IndexSearcher searcher)
             {
                 this.outerInstance = outerInstance;
                 this.searcher = searcher;
-                this.context = ValueSource.newContext(searcher);
+                this.context = ValueSource.NewContext(searcher);
                 outerInstance.func.CreateWeight(context, searcher);
             }
 
@@ -102,14 +100,14 @@ namespace Lucene.Net.Queries.Function
                 queryWeight *= this.queryNorm;
             }
 
-            public override Scorer Scorer(AtomicReaderContext context, Bits acceptDocs)
+            public override Scorer Scorer(AtomicReaderContext ctx, Bits acceptDocs)
             {
-                return new AllScorer(outerInstance, context, acceptDocs, this, queryWeight);
+                return new AllScorer(outerInstance, ctx, acceptDocs, this, queryWeight);
             }
 
-            public override Explanation Explain(AtomicReaderContext context, int doc)
+            public override Explanation Explain(AtomicReaderContext ctx, int doc)
             {
-                return ((AllScorer)Scorer(context, context.reader().LiveDocs)).Explain(doc);
+                return ((AllScorer)Scorer(ctx, ctx.AtomicReader.LiveDocs)).Explain(doc);
             }
         }
 
@@ -165,8 +163,6 @@ namespace Lucene.Net.Queries.Function
                 }
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public int advance(int target) throws java.io.IOException
             public override int Advance(int target)
             {
                 // this will work even if target==NO_MORE_DOCS
@@ -174,8 +170,6 @@ namespace Lucene.Net.Queries.Function
                 return NextDoc();
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public float score() throws java.io.IOException
             public override float Score()
             {
                 float score = qWeight * vals.FloatVal(doc);
@@ -191,43 +185,36 @@ namespace Lucene.Net.Queries.Function
                 return maxDoc;
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: @Override public int freq() throws java.io.IOException
             public override int Freq()
             {
                 return 1;
             }
 
-            //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-            //ORIGINAL LINE: public Explanation explain(int doc) throws java.io.IOException
-            public virtual Explanation Explain(int doc)
+            public virtual Explanation Explain(int d)
             {
-                float sc = qWeight * vals.FloatVal(doc);
+                float sc = qWeight * vals.FloatVal(d);
 
                 Explanation result = new ComplexExplanation(true, sc, "FunctionQuery(" + outerInstance.func + "), product of:");
 
-                result.AddDetail(vals.Explain(doc));
+                result.AddDetail(vals.Explain(d));
                 result.AddDetail(new Explanation(Boost, "boost"));
                 result.AddDetail(new Explanation(weight.queryNorm, "queryNorm"));
                 return result;
             }
         }
 
-
-        //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-        //ORIGINAL LINE: @Override public Weight CreateWeight(IndexSearcher searcher) throws java.io.IOException
         public override Weight CreateWeight(IndexSearcher searcher)
         {
             return new FunctionQuery.FunctionWeight(this, searcher);
         }
 
-
         /// <summary>
-        /// Prints a user-readable version of this query. </summary>
+        /// Prints a user-readable version of this query.
+        /// </summary>
         public override string ToString(string field)
         {
             float boost = Boost;
-            return (boost != 1.0 ? "(" : "") + func.ToString() + (boost == 1.0 ? "" : ")^" + boost);
+            return (boost != 1.0 ? "(" : "") + func + (boost == 1.0 ? "" : ")^" + boost);
         }
 
 
@@ -235,12 +222,12 @@ namespace Lucene.Net.Queries.Function
         /// Returns true if <code>o</code> is equal to this. </summary>
         public override bool Equals(object o)
         {
-            if (!typeof(FunctionQuery).IsInstanceOfType(o))
+            var other = o as FunctionQuery;
+            if (other == null)
             {
                 return false;
             }
-            FunctionQuery other = (FunctionQuery)o;
-            return this.Boost == other.Boost && this.func.Equals(other.func);
+            return Boost == other.Boost && func.Equals(other.func);
         }
 
         /// <summary>
@@ -249,7 +236,5 @@ namespace Lucene.Net.Queries.Function
         {
             return func.GetHashCode() * 31 + Number.FloatToIntBits(Boost);
         }
-
     }
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/FunctionValues.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/FunctionValues.cs b/src/Lucene.Net.Queries/Function/FunctionValues.cs
index b9443dd..3cc23c3 100644
--- a/src/Lucene.Net.Queries/Function/FunctionValues.cs
+++ b/src/Lucene.Net.Queries/Function/FunctionValues.cs
@@ -82,7 +82,7 @@ namespace Lucene.Net.Queries.Function
         }
 
         /// <summary>
-        /// returns the bytes representation of the string val - TODO: should this return the indexed raw bytes not? </summary>
+        /// returns the bytes representation of the str val - TODO: should this return the indexed raw bytes not? </summary>
         public virtual bool BytesVal(int doc, BytesRef target)
         {
             string s = StrVal(doc);
@@ -274,8 +274,8 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly FunctionValues outerInstance;
 
-            private float l;
-            private float u;
+            private readonly float l;
+            private readonly float u;
 
             public ValueSourceScorerAnonymousInnerClassHelper(FunctionValues outerInstance, IndexReader reader,
                 FunctionValues @this, float l, float u)
@@ -297,8 +297,8 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly FunctionValues outerInstance;
 
-            private float l;
-            private float u;
+            private readonly float l;
+            private readonly float u;
 
             public ValueSourceScorerAnonymousInnerClassHelper2(FunctionValues outerInstance, IndexReader reader,
                 FunctionValues @this, float l, float u)
@@ -320,8 +320,8 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly FunctionValues outerInstance;
 
-            private float l;
-            private float u;
+            private readonly float l;
+            private readonly float u;
 
             public ValueSourceScorerAnonymousInnerClassHelper3(FunctionValues outerInstance, IndexReader reader,
                 FunctionValues @this, float l, float u)
@@ -343,8 +343,8 @@ namespace Lucene.Net.Queries.Function
         {
             private readonly FunctionValues outerInstance;
 
-            private float l;
-            private float u;
+            private readonly float l;
+            private readonly float u;
 
             public ValueSourceScorerAnonymousInnerClassHelper4(FunctionValues outerInstance, IndexReader reader,
                 FunctionValues @this, float l, float u)

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSource.cs b/src/Lucene.Net.Queries/Function/ValueSource.cs
index 2e29a02..0f8ed03 100644
--- a/src/Lucene.Net.Queries/Function/ValueSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSource.cs
@@ -1,4 +1,5 @@
 using System.Collections;
+using System.Collections.Generic;
 using Lucene.Net.Index;
 using Lucene.Net.Search;
 using Lucene.Net.Support;
@@ -65,9 +66,9 @@ namespace Lucene.Net.Queries.Function
         /// <summary>
         /// Returns a new non-threadsafe context map.
         /// </summary>
-        public static IDictionary NewContext(IndexSearcher searcher)
+        public static IDictionary<string, IndexSearcher> NewContext(IndexSearcher searcher)
         {
-            IDictionary context = new IdentityHashMap<,>();
+            var context = new IdentityHashMap<string, IndexSearcher>();
             context["searcher"] = searcher;
             return context;
         }
@@ -104,7 +105,7 @@ namespace Lucene.Net.Queries.Function
 
             public override SortField Rewrite(IndexSearcher searcher)
             {
-                IDictionary context = NewContext(searcher);
+                var context = NewContext(searcher);
                 outerInstance.CreateWeight(context, searcher);
                 return new SortField(Field, new ValueSourceComparatorSource(outerInstance, context), Reverse);
             }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSources/ByteFieldSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSources/ByteFieldSource.cs b/src/Lucene.Net.Queries/Function/ValueSources/ByteFieldSource.cs
index 88c5559..33d2554 100644
--- a/src/Lucene.Net.Queries/Function/ValueSources/ByteFieldSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSources/ByteFieldSource.cs
@@ -117,11 +117,9 @@ namespace Lucene.Net.Queries.Function.ValueSources
 
         public override bool Equals(object o)
         {
-            if (o.GetType() != typeof(ByteFieldSource))
-            {
+            var other = o as ByteFieldSource;
+            if (other == null)
                 return false;
-            }
-            ByteFieldSource other = (ByteFieldSource)o;
             return base.Equals(other) && (this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType());
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSources/BytesRefFieldSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSources/BytesRefFieldSource.cs b/src/Lucene.Net.Queries/Function/ValueSources/BytesRefFieldSource.cs
index a277bb2..99af053 100644
--- a/src/Lucene.Net.Queries/Function/ValueSources/BytesRefFieldSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSources/BytesRefFieldSource.cs
@@ -24,7 +24,7 @@ namespace Lucene.Net.Queries.Function.ValueSources
      * limitations under the License.
      */
     /// <summary>
-    /// An implementation for retrieving <seealso cref="FunctionValues"/> instances for string based fields.
+    /// An implementation for retrieving <seealso cref="FunctionValues"/> instances for str based fields.
     /// </summary>
     public class BytesRefFieldSource : FieldCacheSource
     {

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSources/DoubleConstValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSources/DoubleConstValueSource.cs b/src/Lucene.Net.Queries/Function/ValueSources/DoubleConstValueSource.cs
index fc2131a..6e468ec 100644
--- a/src/Lucene.Net.Queries/Function/ValueSources/DoubleConstValueSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSources/DoubleConstValueSource.cs
@@ -22,138 +22,139 @@ using Lucene.Net.Queries.Function.DocValues;
 namespace Lucene.Net.Queries.Function.ValueSources
 {
     /// <summary>
-	/// Function that returns a constant double value for every document.
-	/// </summary>
-	public class DoubleConstValueSource : ConstNumberSource
-	{
-	  internal readonly double constant;
-	  private readonly float fv;
-	  private readonly long lv;
-
-	  public DoubleConstValueSource(double constant)
-	  {
-		this.constant = constant;
-		this.fv = (float)constant;
-		this.lv = (long)constant;
-	  }
+    /// Function that returns a constant double value for every document.
+    /// </summary>
+    public class DoubleConstValueSource : ConstNumberSource
+    {
+        internal readonly double constant;
+        private readonly float fv;
+        private readonly long lv;
+
+        public DoubleConstValueSource(double constant)
+        {
+            this.constant = constant;
+            this.fv = (float)constant;
+            this.lv = (long)constant;
+        }
 
         public override string Description
         {
             get { return "const(" + constant + ")"; }
         }
 
-	  public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
-	  {
-		return new DoubleDocValuesAnonymousInnerClassHelper(this, this);
-	  }
-
-	  private class DoubleDocValuesAnonymousInnerClassHelper : DoubleDocValues
-	  {
-		  private readonly DoubleConstValueSource outerInstance;
-
-		  public DoubleDocValuesAnonymousInnerClassHelper(DoubleConstValueSource outerInstance, DoubleConstValueSource @this) : base(@this)
-		  {
-			  this.outerInstance = outerInstance;
-		  }
-
-		  public override float FloatVal(int doc)
-		  {
-			return outerInstance.fv;
-		  }
-
-		  public override int IntVal(int doc)
-		  {
-			return (int) outerInstance.lv;
-		  }
-
-		  public override long LongVal(int doc)
-		  {
-			return outerInstance.lv;
-		  }
-
-		  public override double DoubleVal(int doc)
-		  {
-			return outerInstance.constant;
-		  }
-
-		  public override string StrVal(int doc)
-		  {
-			return Convert.ToString(outerInstance.constant);
-		  }
-
-		  public override object ObjectVal(int doc)
-		  {
-			return outerInstance.constant;
-		  }
-
-		  public override string ToString(int doc)
-		  {
-			return outerInstance.Description;
-		  }
-	  }
-
-	  public override int GetHashCode()
-	  {
-		long bits = Number.DoubleToRawLongBits(constant);
-		return (int)(bits ^ ((long)((ulong)bits >> 32)));
-	  }
-
-	  public override bool Equals(object o)
-	  {
-	      var other = o as DoubleConstValueSource;
-		if (other == null)
-		{
-			return false;
-		}
-		return this.constant == other.constant;
-	  }
-
-	  public override int Int
-	  {
-		  get
-		  {
-			return (int)lv;
-		  }
-	  }
-
-	  public override long Long
-	  {
-		  get
-		  {
-			return lv;
-		  }
-	  }
-
-	  public override float Float
-	  {
-		  get
-		  {
-			return fv;
-		  }
-	  }
-
-	  public override double Double
-	  {
-		  get
-		  {
-			return constant;
-		  }
-	  }
-
-	  public override Number Number
-	  {
-		  get
-		  {
-			return constant;
-		  }
-	  }
-
-	  public override bool Bool
-	  {
-		  get
-		  {
-			return constant != 0;
-		  }
-	  }
-	}
+        public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
+        {
+            return new DoubleDocValuesAnonymousInnerClassHelper(this, this);
+        }
+
+        private class DoubleDocValuesAnonymousInnerClassHelper : DoubleDocValues
+        {
+            private readonly DoubleConstValueSource outerInstance;
+
+            public DoubleDocValuesAnonymousInnerClassHelper(DoubleConstValueSource outerInstance, DoubleConstValueSource @this)
+                : base(@this)
+            {
+                this.outerInstance = outerInstance;
+            }
+
+            public override float FloatVal(int doc)
+            {
+                return outerInstance.fv;
+            }
+
+            public override int IntVal(int doc)
+            {
+                return (int)outerInstance.lv;
+            }
+
+            public override long LongVal(int doc)
+            {
+                return outerInstance.lv;
+            }
+
+            public override double DoubleVal(int doc)
+            {
+                return outerInstance.constant;
+            }
+
+            public override string StrVal(int doc)
+            {
+                return Convert.ToString(outerInstance.constant);
+            }
+
+            public override object ObjectVal(int doc)
+            {
+                return outerInstance.constant;
+            }
+
+            public override string ToString(int doc)
+            {
+                return outerInstance.Description;
+            }
+        }
+
+        public override int GetHashCode()
+        {
+            long bits = Number.DoubleToRawLongBits(constant);
+            return (int)(bits ^ ((long)((ulong)bits >> 32)));
+        }
+
+        public override bool Equals(object o)
+        {
+            var other = o as DoubleConstValueSource;
+            if (other == null)
+            {
+                return false;
+            }
+            return this.constant == other.constant;
+        }
+
+        public override int Int
+        {
+            get
+            {
+                return (int)lv;
+            }
+        }
+
+        public override long Long
+        {
+            get
+            {
+                return lv;
+            }
+        }
+
+        public override float Float
+        {
+            get
+            {
+                return fv;
+            }
+        }
+
+        public override double Double
+        {
+            get
+            {
+                return constant;
+            }
+        }
+
+        public override Number Number
+        {
+            get
+            {
+                return constant;
+            }
+        }
+
+        public override bool Bool
+        {
+            get
+            {
+                return constant != 0;
+            }
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSources/EnumFieldSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSources/EnumFieldSource.cs b/src/Lucene.Net.Queries/Function/ValueSources/EnumFieldSource.cs
index 7aa50d9..1958daf 100644
--- a/src/Lucene.Net.Queries/Function/ValueSources/EnumFieldSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSources/EnumFieldSource.cs
@@ -30,7 +30,7 @@ namespace Lucene.Net.Queries.Function.ValueSources
     /// <summary>
 	/// Obtains int field values from <seealso cref="IFieldCache#getInts"/> and makes
 	/// those values available as other numeric types, casting as needed.
-	/// StrVal of the value is not the int value, but its string (displayed) value
+	/// StrVal of the value is not the int value, but its str (displayed) value
 	/// </summary>
 	public class EnumFieldSource : FieldCacheSource
 	{
@@ -85,19 +85,19 @@ namespace Lucene.Net.Queries.Function.ValueSources
 
 		int? intValue;
 		int? enumInt = enumStringToIntMap[stringVal];
-		if (enumInt != null) //enum int found for string
+		if (enumInt != null) //enum int found for str
 		{
 		  return enumInt;
 		}
 
-		//enum int not found for string
+		//enum int not found for str
 		intValue = TryParseInt(stringVal);
 		if (intValue == null) //not Integer
 		{
 		  intValue = DEFAULT_VALUE;
 		}
 		string enumString = enumIntToStringMap[intValue];
-		if (enumString != null) //has matching string
+		if (enumString != null) //has matching str
 		{
 		  return intValue;
 		}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/5506faf0/src/Lucene.Net.Queries/Function/ValueSources/FloatFieldSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Queries/Function/ValueSources/FloatFieldSource.cs b/src/Lucene.Net.Queries/Function/ValueSources/FloatFieldSource.cs
index 67c5c3d..b3ba445 100644
--- a/src/Lucene.Net.Queries/Function/ValueSources/FloatFieldSource.cs
+++ b/src/Lucene.Net.Queries/Function/ValueSources/FloatFieldSource.cs
@@ -19,128 +19,121 @@ using Lucene.Net.Index;
 using Lucene.Net.Queries.Function.DocValues;
 using Lucene.Net.Search;
 using Lucene.Net.Util;
+using Lucene.Net.Util.Mutable;
 
 namespace Lucene.Net.Queries.Function.ValueSources
 {
     /// <summary>
-	/// Obtains float field values from <seealso cref="IFieldCache#getFloats"/> and makes those
-	/// values available as other numeric types, casting as needed.
-	/// </summary>
-	public class FloatFieldSource : FieldCacheSource
-	{
+    /// Obtains float field values from <seealso cref="IFieldCache#getFloats"/> and makes those
+    /// values available as other numeric types, casting as needed.
+    /// </summary>
+    public class FloatFieldSource : FieldCacheSource
+    {
 
-	  protected internal readonly FieldCache.FloatParser parser;
+        protected internal readonly FieldCache.IFloatParser parser;
 
-	  public FloatFieldSource(string field) : this(field, null)
-	  {
-	  }
+        public FloatFieldSource(string field)
+            : this(field, null)
+        {
+        }
 
-	  public FloatFieldSource(string field, IFieldCache.FloatParser parser) : base(field)
-	  {
-		this.parser = parser;
-	  }
+        public FloatFieldSource(string field, FieldCache.IFloatParser parser)
+            : base(field)
+        {
+            this.parser = parser;
+        }
 
         public override string Description
         {
             get { return "float(" + field + ')'; }
         }
 
-//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
-//ORIGINAL LINE: @Override public org.apache.lucene.queries.function.FunctionValues GetValues(java.util.Map context, org.apache.lucene.index.AtomicReaderContext readerContext) throws java.io.IOException
-	  public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
-	  {
-//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
-//ORIGINAL LINE: final org.apache.lucene.search.FieldCache.Floats arr = cache.getFloats(readerContext.reader(), field, parser, true);
-		FieldCache.Floats arr = cache.GetFloats(readerContext.AtomicReader, field, parser, true);
-//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
-//ORIGINAL LINE: final org.apache.lucene.util.Bits valid = cache.getDocsWithField(readerContext.reader(), field);
-		Bits valid = cache.GetDocsWithField(readerContext.AtomicReader, field);
-
-		return new FloatDocValuesAnonymousInnerClassHelper(this, this, arr, valid);
-	  }
-
-	  private class FloatDocValuesAnonymousInnerClassHelper : FloatDocValues
-	  {
-		  private readonly FloatFieldSource outerInstance;
-
-		  private readonly FieldCache.Floats arr;
-		  private readonly Bits valid;
-
-		  public FloatDocValuesAnonymousInnerClassHelper(FloatFieldSource outerInstance, FloatFieldSource this, FieldCache.Floats arr, Bits valid) : base(this)
-		  {
-			  this.outerInstance = outerInstance;
-			  this.arr = arr;
-			  this.valid = valid;
-		  }
-
-		  public override float FloatVal(int doc)
-		  {
-			return arr.get(doc);
-		  }
-
-		  public override object objectVal(int doc)
-		  {
-			return valid.get(doc) ? arr.get(doc) : null;
-		  }
-
-		  public override bool exists(int doc)
-		  {
-			return arr.get(doc) != 0 || valid.get(doc);
-		  }
-
-		  public override ValueFiller ValueFiller
-		  {
-			  get
-			  {
-				return new ValueFillerAnonymousInnerClassHelper(this);
-			  }
-		  }
-
-		  private class ValueFillerAnonymousInnerClassHelper : ValueFiller
-		  {
-			  private readonly FloatDocValuesAnonymousInnerClassHelper outerInstance;
-
-			  public ValueFillerAnonymousInnerClassHelper(FloatDocValuesAnonymousInnerClassHelper outerInstance)
-			  {
-				  this.outerInstance = outerInstance;
-				  mval = new MutableValueFloat();
-			  }
-
-			  private readonly MutableValueFloat mval;
-
-			  public override MutableValue Value
-			  {
-				  get
-				  {
-					return mval;
-				  }
-			  }
-
-			  public override void fillValue(int doc)
-			  {
-				mval.value = outerInstance.arr.get(doc);
-				mval.exists = mval.value != 0 || outerInstance.valid.get(doc);
-			  }
-		  }
-
-	  }
-
-	  public override bool Equals(object o)
-	  {
-		if (o.GetType() != typeof(FloatFieldSource))
-		{
-			return false;
-		}
-		FloatFieldSource other = (FloatFieldSource)o;
-		return base.Equals(other) && (this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType());
-	  }
-
-	  public override int GetHashCode()
-	  {
-		int h = parser == null ? typeof(float?).GetHashCode() : parser.GetType().GetHashCode();
-		h += base.GetHashCode();
-		return h;
-	  }
-	}
+        public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
+        {
+            var arr = cache.GetFloats(readerContext.AtomicReader, field, parser, true);
+            var valid = cache.GetDocsWithField(readerContext.AtomicReader, field);
+            return new FloatDocValuesAnonymousInnerClassHelper(this, this, arr, valid);
+        }
+
+        private class FloatDocValuesAnonymousInnerClassHelper : FloatDocValues
+        {
+            private readonly FloatFieldSource outerInstance;
+
+            private readonly FieldCache.Floats arr;
+            private readonly Bits valid;
+
+            public FloatDocValuesAnonymousInnerClassHelper(FloatFieldSource outerInstance, FloatFieldSource @this, FieldCache.Floats arr, Bits valid)
+                : base(@this)
+            {
+                this.outerInstance = outerInstance;
+                this.arr = arr;
+                this.valid = valid;
+            }
+
+            public override float FloatVal(int doc)
+            {
+                return arr.Get(doc);
+            }
+
+            public override object ObjectVal(int doc)
+            {
+                return valid.Get(doc) ? arr.Get(doc) : (float?)null;
+            }
+
+            public override bool Exists(int doc)
+            {
+                return arr.Get(doc) != 0 || valid.Get(doc);
+            }
+
+            public override AbstractValueFiller ValueFiller
+            {
+                get
+                {
+                    return new ValueFillerAnonymousInnerClassHelper(this);
+                }
+            }
+
+            private class ValueFillerAnonymousInnerClassHelper : AbstractValueFiller
+            {
+                private readonly FloatDocValuesAnonymousInnerClassHelper outerInstance;
+
+                public ValueFillerAnonymousInnerClassHelper(FloatDocValuesAnonymousInnerClassHelper outerInstance)
+                {
+                    this.outerInstance = outerInstance;
+                    mval = new MutableValueFloat();
+                }
+
+                private readonly MutableValueFloat mval;
+
+                public override MutableValue Value
+                {
+                    get
+                    {
+                        return mval;
+                    }
+                }
+
+                public override void FillValue(int doc)
+                {
+                    mval.Value = outerInstance.arr.Get(doc);
+                    mval.Exists = mval.Value != 0 || outerInstance.valid.Get(doc);
+                }
+            }
+        }
 
+        public override bool Equals(object o)
+        {
+            var other = o as FloatFieldSource;
+            if (other == null)
+                return false;
+            return base.Equals(other) && (this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType());
+        }
+
+        public override int GetHashCode()
+        {
+            int h = parser == null ? typeof(float?).GetHashCode() : parser.GetType().GetHashCode();
+            h += base.GetHashCode();
+            return h;
+        }
+    }
 }
\ No newline at end of file