You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by cc...@apache.org on 2012/03/23 02:32:54 UTC

svn commit: r1304159 [2/3] - in /incubator/lucene.net/trunk: src/core/QueryParser/ test/contrib/Analyzers/De/ test/contrib/Core/Analysis/Ext/ test/core/QueryParser/ test/core/Search/

Modified: incubator/lucene.net/trunk/src/core/QueryParser/QueryParser.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/QueryParser/QueryParser.cs?rev=1304159&r1=1304158&r2=1304159&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/QueryParser/QueryParser.cs (original)
+++ incubator/lucene.net/trunk/src/core/QueryParser/QueryParser.cs Fri Mar 23 01:32:53 2012
@@ -1,26 +1,31 @@
-/* 
- * 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.
- */
+/*
+ * 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.
+*/
 
 /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Globalization;
-using System.Linq;
+using System.IO;
+using System.Text;
+using Lucene.Net.Analysis;
 using Lucene.Net.Support;
 using Lucene.Net.Util;
 using Analyzer = Lucene.Net.Analysis.Analyzer;
@@ -48,742 +53,728 @@ using Version = Lucene.Net.Util.Version;
 
 namespace Lucene.Net.QueryParsers
 {
-	
-	/// <summary> This class is generated by JavaCC.  The most important method is
-	/// <see cref="Parse(String)" />.
-	/// 
-	/// The syntax for query strings is as follows:
-	/// A Query is a series of clauses.
-	/// A clause may be prefixed by:
-	/// <list type="bullet">
-	/// <item> a plus (<c>+</c>) or a minus (<c>-</c>) sign, indicating
-	/// that the clause is required or prohibited respectively; or</item>
-	/// <item> a term followed by a colon, indicating the field to be searched.
-	/// This enables one to construct queries which search multiple fields.</item>
-	/// </list>
-	/// 
-	/// A clause may be either:
-	/// <list type="bullet">
-	/// <item> a term, indicating all the documents that contain this term; or</item>
-	/// <item> a nested query, enclosed in parentheses.  Note that this may be used
-	/// with a <c>+</c>/<c>-</c> prefix to require any of a set of
-	/// terms.</item>
-	/// </list>
-	/// 
-	/// Thus, in BNF, the query grammar is:
+    /// <summary> This class is generated by JavaCC.  The most important method is
+    /// <see cref="Parse(String)" />.
+    /// 
+    /// The syntax for query strings is as follows:
+    /// A Query is a series of clauses.
+    /// A clause may be prefixed by:
+    /// <list type="bullet">
+    /// <item> a plus (<c>+</c>) or a minus (<c>-</c>) sign, indicating
+    /// that the clause is required or prohibited respectively; or</item>
+    /// <item> a term followed by a colon, indicating the field to be searched.
+    /// This enables one to construct queries which search multiple fields.</item>
+    /// </list>
+    /// 
+    /// A clause may be either:
+    /// <list type="bullet">
+    /// <item> a term, indicating all the documents that contain this term; or</item>
+    /// <item> a nested query, enclosed in parentheses.  Note that this may be used
+    /// with a <c>+</c>/<c>-</c> prefix to require any of a set of
+    /// terms.</item>
+    /// </list>
+    /// 
+    /// Thus, in BNF, the query grammar is:
     /// <code>
-	/// Query  ::= ( Clause )*
-	/// Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
+    /// Query  ::= ( Clause )*
+    /// Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
     /// </code>
-	/// 
-	/// <p/>
-	/// Examples of appropriately formatted queries can be found in the <a
-	/// href="../../../../../../queryparsersyntax.html">query syntax
-	/// documentation</a>.
-	/// <p/>
-	/// 
-	/// <p/>
-	/// In <see cref="TermRangeQuery" />s, QueryParser tries to detect date values, e.g.
-	/// <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches
-	/// for "date" fields between 2005-06-01 and 2005-06-04. Note that the format
-	/// of the accepted input depends on <see cref="SetLocale(System.Globalization.CultureInfo)">the locale</see>.
-	/// By default a date is converted into a search term using the deprecated
-	/// <see cref="DateField" /> for compatibility reasons.
-	/// To use the new <see cref="DateTools" /> to convert dates, a
-	/// <see cref="Lucene.Net.Documents.DateTools.Resolution" /> has to be set.
-	/// <p/>
-	/// <p/>
-	/// The date resolution that shall be used for RangeQueries can be set
-	/// using <see cref="SetDateResolution(DateTools.Resolution)" />
-	/// or <see cref="SetDateResolution(String, DateTools.Resolution)" />. The former
-	/// sets the default date resolution for all fields, whereas the latter can
-	/// be used to set field specific date resolutions. Field specific date
-	/// resolutions take, if set, precedence over the default date resolution.
-	/// <p/>
-	/// <p/>
-	/// If you use neither <see cref="DateField" /> nor <see cref="DateTools" /> in your
-	/// index, you can create your own
-	/// query parser that inherits QueryParser and overwrites
-	/// <see cref="GetRangeQuery(String, String, String, bool)" /> to
-	/// use a different method for date conversion.
-	/// <p/>
-	/// 
-	/// <p/>Note that QueryParser is <em>not</em> thread-safe.<p/> 
-	/// 
-	/// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
-	/// the same syntax as this class, but is more modular,
-	/// enabling substantial customization to how a query is created.
-	/// 
-	/// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
-	/// the same syntax as this class, but is more modular,
-	/// enabling substantial customization to how a query is created.
-	/// <b>NOTE</b>: You must specify the required <see cref="Version" /> compatibility when
-	/// creating QueryParser:
-	/// <list type="bullet">
-	/// <item>As of 2.9, <see cref="EnablePositionIncrements" /> is true by default.</item>
-	/// </list>
-	/// </summary>
-	public class QueryParser : QueryParserConstants
-	{
-		private void  InitBlock()
-		{
-			multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
-			fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
-			fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
-			jj_2_rtns = new JJCalls[1];
-			jj_ls = new LookaheadSuccess();
-		}
-		
-		private const int CONJ_NONE = 0;
-		private const int CONJ_AND = 1;
-		private const int CONJ_OR = 2;
-		
-		private const int MOD_NONE = 0;
-		private const int MOD_NOT = 10;
-		private const int MOD_REQ = 11;
-		
-		// make it possible to call setDefaultOperator() without accessing 
-		// the nested class:
-		/// <summary>Alternative form of QueryParser.Operator.AND </summary>
-		public static readonly Operator AND_OPERATOR = Operator.AND;
-		/// <summary>Alternative form of QueryParser.Operator.OR </summary>
-		public static readonly Operator OR_OPERATOR = Operator.OR;
-		
-		/// <summary>The actual operator that parser uses to combine query terms </summary>
-		private Operator operator_Renamed = OR_OPERATOR;
-		
-		internal bool lowercaseExpandedTerms = true;
-		internal MultiTermQuery.RewriteMethod multiTermRewriteMethod;
-		internal bool allowLeadingWildcard = false;
-		internal bool enablePositionIncrements = true;
-		
-		internal Analyzer analyzer;
-		internal System.String field;
-		internal int phraseSlop = 0;
-		internal float fuzzyMinSim;
-		internal int fuzzyPrefixLength;
-		internal System.Globalization.CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
-		
-		// the default date resolution
-		internal DateTools.Resolution dateResolution = null;
-		// maps field names to date resolutions
-		internal IDictionary<string, DateTools.Resolution> fieldToDateResolution = null;
-		
-		// The collator to use when determining range inclusion,
-		// for use when constructing RangeQuerys.
-		internal System.Globalization.CompareInfo rangeCollator = null;
-		
-		/// <summary>The default operator for parsing queries. 
-		/// Use <see cref="QueryParser.SetDefaultOperator" /> to change it.
-		/// </summary>
-        public enum Operator { OR, AND }
-		
-		/// <summary> Constructs a query parser.
-		/// 
-		/// </summary>
-		/// <param name="matchVersion">Lucene version to match. See <a href="#version">above</a>)
-		/// </param>
-		/// <param name="f">the default field for query terms.
-		/// </param>
-		/// <param name="a">used to find terms in the query text.
-		/// </param>
-		public QueryParser(Version matchVersion, System.String f, Analyzer a):this(new FastCharStream(new System.IO.StringReader("")))
-		{
-			analyzer = a;
-			field = f;
-			if (matchVersion.OnOrAfter(Version.LUCENE_29))
-			{
-				enablePositionIncrements = true;
-			}
-			else
-			{
-				enablePositionIncrements = false;
-			}
-		}
-		
-		/// <summary>Parses a query string, returning a <see cref="Lucene.Net.Search.Query" />.</summary>
-		/// <param name="query"> the query string to be parsed.
-		/// </param>
-		/// <throws>  ParseException if the parsing fails </throws>
-		public virtual Query Parse(System.String query)
-		{
-			ReInit(new FastCharStream(new System.IO.StringReader(query)));
-			try
-			{
-				// TopLevelQuery is a Query followed by the end-of-input (EOF)
-				Query res = TopLevelQuery(field);
-				return res != null?res:NewBooleanQuery(false);
-			}
-			catch (ParseException tme)
-			{
-				// rethrow to include the original query:
-				ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
-				throw e;
-			}
-			catch (TokenMgrError tme)
-			{
-				ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
-				throw e;
-			}
-			catch (BooleanQuery.TooManyClauses tmc)
-			{
-				ParseException e = new ParseException("Cannot parse '" + query + "': too many boolean clauses", tmc);
-				throw e;
-			}
-		}
-
-	    /// <value> Returns the analyzer. </value>
-	    public virtual Analyzer Analyzer
-	    {
-	        get { return analyzer; }
-	    }
-
-	    /// <value> Returns the field. </value>
-	    public virtual string Field
-	    {
-	        get { return field; }
-	    }
+    /// 
+    /// <p/>
+    /// Examples of appropriately formatted queries can be found in the <a
+    /// href="../../../../../../queryparsersyntax.html">query syntax
+    /// documentation</a>.
+    /// <p/>
+    /// 
+    /// <p/>
+    /// In <see cref="TermRangeQuery" />s, QueryParser tries to detect date values, e.g.
+    /// <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches
+    /// for "date" fields between 2005-06-01 and 2005-06-04. Note that the format
+    /// of the accepted input depends on <see cref="SetLocale(System.Globalization.CultureInfo)">the locale</see>.
+    /// By default a date is converted into a search term using the deprecated
+    /// <see cref="DateField" /> for compatibility reasons.
+    /// To use the new <see cref="DateTools" /> to convert dates, a
+    /// <see cref="Lucene.Net.Documents.DateTools.Resolution" /> has to be set.
+    /// <p/>
+    /// <p/>
+    /// The date resolution that shall be used for RangeQueries can be set
+    /// using <see cref="SetDateResolution(DateTools.Resolution)" />
+    /// or <see cref="SetDateResolution(String, DateTools.Resolution)" />. The former
+    /// sets the default date resolution for all fields, whereas the latter can
+    /// be used to set field specific date resolutions. Field specific date
+    /// resolutions take, if set, precedence over the default date resolution.
+    /// <p/>
+    /// <p/>
+    /// If you use neither <see cref="DateField" /> nor <see cref="DateTools" /> in your
+    /// index, you can create your own
+    /// query parser that inherits QueryParser and overwrites
+    /// <see cref="GetRangeQuery(String, String, String, bool)" /> to
+    /// use a different method for date conversion.
+    /// <p/>
+    /// 
+    /// <p/>Note that QueryParser is <em>not</em> thread-safe.<p/> 
+    /// 
+    /// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
+    /// the same syntax as this class, but is more modular,
+    /// enabling substantial customization to how a query is created.
+    /// 
+    /// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
+    /// the same syntax as this class, but is more modular,
+    /// enabling substantial customization to how a query is created.
+    /// <b>NOTE</b>: You must specify the required <see cref="Version" /> compatibility when
+    /// creating QueryParser:
+    /// <list type="bullet">
+    /// <item>As of 2.9, <see cref="EnablePositionIncrements" /> is true by default.</item>
+    /// </list>
+    /// </summary>
+    public class QueryParser : QueryParserConstants
+    {
+
+        private static int CONJ_NONE = 0;
+        private static int CONJ_AND = 1;
+        private static int CONJ_OR = 2;
+
+        private static int MOD_NONE = 0;
+        private static int MOD_NOT = 10;
+        private static int MOD_REQ = 11;
+
+        // make it possible to call setDefaultOperator() without accessing 
+        // the nested class:
+        /// <summary>Alternative form of QueryParser.Operator.AND </summary>
+        public static Operator AND_OPERATOR = Operator.AND;
+
+        /// <summary>Alternative form of QueryParser.Operator.OR </summary>
+        public static Operator OR_OPERATOR = Operator.OR;
+
+        /// <summary>The actual operator that parser uses to combine query terms </summary>
+        private Operator operator_Renamed = OR_OPERATOR;
+
+        private bool lowercaseExpandedTerms = true;
+        private MultiTermQuery.RewriteMethod multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
+        private bool allowLeadingWildcard = false;
+        private bool enablePositionIncrements = true;
+
+        // LUCENENET-423 - DateRange differences with Java and .NET
+        private bool _useJavaStyleDateRangeParsing = false;
+
+        private Analyzer analyzer;
+        private String field;
+        private int phraseSlop = 0;
+        private float fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
+        private int fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
+        private System.Globalization.CultureInfo locale = System.Globalization.CultureInfo.CurrentCulture;
+
+        // the default date resolution
+        private DateTools.Resolution dateResolution = null;
+        // maps field names to date resolutions
+        private IDictionary<String, DateTools.Resolution> fieldToDateResolution = null;
+
+        // The collator to use when determining range inclusion,
+        // for use when constructing RangeQuerys.
+        private System.Globalization.CompareInfo rangeCollator = null;
+
+        /** The default operator_Renamed for parsing queries. 
+         * Use {@link QueryParser#setDefaultOperator} to change it.
+         */
+
+        public enum Operator
+        {
+            OR,
+            AND
+        }
+
+        /** Constructs a query parser.
+         *  @param matchVersion  Lucene version to match.  See <a href="#version">above</a>)
+         *  @param f  the default field for query terms.
+         *  @param a   used to find terms in the query text.
+         */
+
+        public QueryParser(Version matchVersion, String f, Analyzer a)
+            : this(new FastCharStream(new StringReader("")))
+        {
+            analyzer = a;
+            field = f;
+            if (matchVersion.OnOrAfter(Version.LUCENE_29))
+            {
+                enablePositionIncrements = true;
+            }
+            else
+            {
+                enablePositionIncrements = false;
+            }
+
+            // LUCENENET-423 - DateRange differences with Java and .NET
+            if (matchVersion.OnOrAfter(Version.LUCENE_30))
+            {
+                _useJavaStyleDateRangeParsing = true;
+            }
+        }
+
+        /// <summary>Parses a query string, returning a {@link Lucene.Net.Search.Query}.</summary>
+        /// <param name="query"> the query string to be parsed.
+        /// </param>
+        /// <throws>  ParseException if the parsing fails </throws>
+        public virtual Query Parse(String query)
+        {
+            ReInit(new FastCharStream(new StringReader(query)));
+            try
+            {
+                // TopLevelQuery is a Query followed by the end-of-input (EOF)
+                Query res = TopLevelQuery(field);
+                return res ?? NewBooleanQuery(false);
+            }
+            catch (ParseException tme)
+            {
+                // rethrow to include the original query:
+                throw new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
+            }
+            catch (TokenMgrError tme)
+            {
+                throw new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
+            }
+            catch (BooleanQuery.TooManyClauses tmc)
+            {
+                throw new ParseException("Cannot parse '" + query + "': too many bool clauses", tmc);
+            }
+        }
+
+        /// <value> Returns the analyzer. </value>
+        public virtual Analyzer Analyzer
+        {
+            get { return analyzer; }
+        }
 
-	    /// <summary> 
+        /// <value> Returns the field. </value>
+        public virtual string Field
+        {
+            get { return field; }
+        }
+
+        /// <summary> 
         /// Gets or sets the minimal similarity for fuzzy queries.
-	    /// Default is 0.5f.
-	    /// </summary>
-	    public virtual float FuzzyMinSim
-	    {
-	        get { return fuzzyMinSim; }
-	        set { this.fuzzyMinSim = value; }
-	    }
+        /// Default is 0.5f.
+        /// </summary>
+        public virtual float FuzzyMinSim
+        {
+            get { return fuzzyMinSim; }
+            set { this.fuzzyMinSim = value; }
+        }
 
         /// <summary> Gets or sets the prefix length for fuzzy queries. </summary>
-	    /// <value> Returns the fuzzyPrefixLength. </value>
-	    public virtual int FuzzyPrefixLength
-	    {
-	        get { return fuzzyPrefixLength; }
-	        set { this.fuzzyPrefixLength = value; }
-	    }
-
-	    /// <summary> Gets or sets the default slop for phrases.  If zero, then exact phrase matches
-	    /// are required.  Default value is zero.
-	    /// </summary>
-	    public virtual int PhraseSlop
-	    {
-	        set { this.phraseSlop = value; }
-	        get { return phraseSlop; }
-	    }
-
-	    /// <summary> Set to <c>true</c> to allow leading wildcard characters.
-	    /// <p/>
-	    /// When set, <c>*</c> or <c>?</c> are allowed as 
-	    /// the first character of a PrefixQuery and WildcardQuery.
-	    /// Note that this can produce very slow
-	    /// queries on big indexes. 
-	    /// <p/>
-	    /// Default: false.
-	    /// </summary>
-	    public virtual bool AllowLeadingWildcard
-	    {
-	        set { this.allowLeadingWildcard = value; }
-	        get { return allowLeadingWildcard; }
-	    }
-
-	    public class SetEnablePositionIncrementsParams
-	    {
-	        private bool _enable;
-
-	        public SetEnablePositionIncrementsParams(bool enable)
-	        {
-	            _enable = enable;
-	        }
-
-	        public bool Enable
-	        {
-	            get { return _enable; }
-	        }
-	    }
-
-	    /// <summary> Set to <c>true</c> to enable position increments in result query.
-		/// <p/>
-		/// When set, result phrase and multi-phrase queries will
-		/// be aware of position increments.
-		/// Useful when e.g. a StopFilter increases the position increment of
-		/// the token that follows an omitted token.
-		/// <p/>
-		/// Default: false.
-		/// </summary>
-		public virtual void SetEnablePositionIncrements(SetEnablePositionIncrementsParams setEnablePositionIncrementsParams)
-		{
-			this.enablePositionIncrements = setEnablePositionIncrementsParams.Enable;
-		}
-
-	    public virtual bool EnablePositionIncrements
-	    {
-	        get { return enablePositionIncrements; }
-	    }
-
-	    /// <summary> Gets or sets the boolean operator of the QueryParser.
-	    /// In default mode (<c>OR_OPERATOR</c>) terms without any modifiers
-	    /// are considered optional: for example <c>capital of Hungary</c> is equal to
-	    /// <c>capital OR of OR Hungary</c>.<br/>
-	    /// In <c>AND_OPERATOR</c> mode terms are considered to be in conjunction: the
-	    /// above mentioned query is parsed as <c>capital AND of AND Hungary</c>
-	    /// </summary>
-	    public virtual Operator DefaultOperator
-	    {
-	        set { this.operator_Renamed = value; }
-	        get { return operator_Renamed; }
-	    }
-
-	    /// <summary> Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
-	    /// lower-cased or not.  Default is <c>true</c>.
-	    /// </summary>
-	    public virtual bool LowercaseExpandedTerms
-	    {
-	        set { this.lowercaseExpandedTerms = value; }
-	        get { return lowercaseExpandedTerms; }
-	    }
-
-
-	    /// <summary> By default QueryParser uses <see cref="MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT" />
-	    /// when creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable because it 
-	    /// a) Runs faster b) Does not have the scarcity of terms unduly influence score 
-	    /// c) avoids any "TooManyBooleanClauses" exception.
-	    /// However, if your application really needs to use the
-	    /// old-fashioned BooleanQuery expansion rewriting and the above
-	    /// points are not relevant then use this to change
-	    /// the rewrite method.
-	    /// </summary>
-	    public virtual MultiTermQuery.RewriteMethod MultiTermRewriteMethod
-	    {
-	        set { multiTermRewriteMethod = value; }
-	        get { return multiTermRewriteMethod; }
-	    }
-
-
-	    /// <summary>Gets or sets locale used by date range parsing.</summary>
-	    public virtual CultureInfo Locale
-	    {
-	        set { this.locale = value; }
-	        get { return locale; }
-	    }
-
-	    /// <summary> Sets the default date resolution used by RangeQueries for fields for which no
-		/// specific date resolutions has been set. Field specific resolutions can be set
-		/// with <see cref="SetDateResolution(String, DateTools.Resolution)" />.
-		/// 
-		/// </summary>
-		/// <param name="dateResolution">the default date resolution to set
-		/// </param>
-		public virtual void  SetDateResolution(DateTools.Resolution dateResolution)
-		{
-			this.dateResolution = dateResolution;
-		}
+        /// <value> Returns the fuzzyPrefixLength. </value>
+        public virtual int FuzzyPrefixLength
+        {
+            get { return fuzzyPrefixLength; }
+            set { this.fuzzyPrefixLength = value; }
+        }
+
+        /// <summary> Gets or sets the default slop for phrases.  If zero, then exact phrase matches
+        /// are required.  Default value is zero.
+        /// </summary>
+        public virtual int PhraseSlop
+        {
+            set { this.phraseSlop = value; }
+            get { return phraseSlop; }
+        }
+
+        /// <summary> Set to <c>true</c> to allow leading wildcard characters.
+        /// <p/>
+        /// When set, <c>*</c> or <c>?</c> are allowed as 
+        /// the first character of a PrefixQuery and WildcardQuery.
+        /// Note that this can produce very slow
+        /// queries on big indexes. 
+        /// <p/>
+        /// Default: false.
+        /// </summary>
+        public virtual bool AllowLeadingWildcard
+        {
+            set { this.allowLeadingWildcard = value; }
+            get { return allowLeadingWildcard; }
+        }
+
+        /// <summary>Set to <code>true</code> to enable position increments in result query.
+        /// <p/>
+        /// When set, result phrase and multi-phrase queries will
+        /// be aware of position increments.
+        /// Useful when e.g. a StopFilter increases the position increment of
+        /// the token that follows an omitted token.
+        /// <p/>
+        /// Default: false.
+        /// </summary>
+        public virtual bool EnablePositionIncrements
+        {
+            set { this.enablePositionIncrements = value; }
+            get { return enablePositionIncrements; }
+        }
+
+        /// <summary> Gets or sets the boolean operator of the QueryParser.
+        /// In default mode (<c>OR_OPERATOR</c>) terms without any modifiers
+        /// are considered optional: for example <c>capital of Hungary</c> is equal to
+        /// <c>capital OR of OR Hungary</c>.<br/>
+        /// In <c>AND_OPERATOR</c> mode terms are considered to be in conjunction: the
+        /// above mentioned query is parsed as <c>capital AND of AND Hungary</c>
+        /// </summary>
+        public virtual Operator DefaultOperator
+        {
+            set { this.operator_Renamed = value; }
+            get { return operator_Renamed; }
+        }
+
+        /// <summary> Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
+        /// lower-cased or not.  Default is <c>true</c>.
+        /// </summary>
+        public virtual bool LowercaseExpandedTerms
+        {
+            set { this.lowercaseExpandedTerms = value; }
+            get { return lowercaseExpandedTerms; }
+        }
+
+
+        /// <summary> By default QueryParser uses <see cref="MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT" />
+        /// when creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable because it 
+        /// a) Runs faster b) Does not have the scarcity of terms unduly influence score 
+        /// c) avoids any "TooManyBooleanClauses" exception.
+        /// However, if your application really needs to use the
+        /// old-fashioned BooleanQuery expansion rewriting and the above
+        /// points are not relevant then use this to change
+        /// the rewrite method.
+        /// </summary>
+        public virtual MultiTermQuery.RewriteMethod MultiTermRewriteMethod
+        {
+            set { multiTermRewriteMethod = value; }
+            get { return multiTermRewriteMethod; }
+        }
+
+        /// <summary>Gets or sets locale used by date range parsing.</summary>
+        public virtual CultureInfo Locale
+        {
+            set { this.locale = value; }
+            get { return locale; }
+        }
+
+        /// <summary> Returns current locale, allowing access by subclasses.</summary>
+        public virtual System.Globalization.CultureInfo GetLocale()
+        {
+            return locale;
+        }
+
+        /// <summary> Sets the default date resolution used by RangeQueries for fields for which no
+        /// specific date resolutions has been set. Field specific resolutions can be set
+        /// with {@link #SetDateResolution(String, DateTools.Resolution)}.
+        /// 
+        /// </summary>
+        /// <param name="dateResolution">the default date resolution to set
+        /// </param>
+        public virtual void SetDateResolution(DateTools.Resolution dateResolution)
+        {
+            this.dateResolution = dateResolution;
+        }
+
+        /// <summary> Sets the date resolution used by RangeQueries for a specific field.
+        /// 
+        /// </summary>
+        /// <param name="fieldName">field for which the date resolution is to be set 
+        /// </param>
+        /// <param name="dateResolution">date resolution to set
+        /// </param>
+        public virtual void SetDateResolution(String fieldName, DateTools.Resolution dateResolution)
+        {
+            if (fieldName == null)
+            {
+                throw new ArgumentException("Field cannot be null.");
+            }
+
+            if (fieldToDateResolution == null)
+            {
+                // lazily initialize HashMap
+                fieldToDateResolution = new HashMap<String, DateTools.Resolution>();
+            }
+
+            fieldToDateResolution.Add(fieldName, dateResolution);
+        }
 
         /// <summary> Returns the date resolution that is used by RangeQueries for the given field. 
         /// Returns null, if no default or field specific date resolution has been set
         /// for the given field.
-		/// </summary>
-		/// <param name="fieldName">field for which the date resolution is to be set 
-		/// </param>
-		/// <param name="dateResolution">date resolution to set
-		/// </param>
-		public virtual void  SetDateResolution(System.String fieldName, DateTools.Resolution dateResolution)
-		{
-			if (fieldName == null)
-			{
-				throw new System.ArgumentException("Field cannot be null.");
-			}
-			
-			if (fieldToDateResolution == null)
-			{
-				// lazily initialize Dictionary
-				fieldToDateResolution = new HashMap<string,DateTools.Resolution>();
-			}
-			
-			fieldToDateResolution[fieldName] = dateResolution;
-		}
-		
-		/// <summary> Returns the date resolution that is used by RangeQueries for the given field. 
-		/// Returns null, if no default or field specific date resolution has been set
-		/// for the given field.
-		/// 
-		/// </summary>
-		public virtual DateTools.Resolution GetDateResolution(System.String fieldName)
-		{
-			if (fieldName == null)
-			{
-				throw new System.ArgumentException("Field cannot be null.");
-			}
-			
-			if (fieldToDateResolution == null)
-			{
-				// no field specific date resolutions set; return default date resolution instead
-				return this.dateResolution;
-			}
-			
-			DateTools.Resolution resolution = fieldToDateResolution[fieldName];
-			if (resolution == null)
-			{
-				// no date resolutions set for the given field; return default date resolution instead
-				resolution = this.dateResolution;
-			}
-			
-			return resolution;
-		}
-
-	    /// <summary> Gets or sets the collator used to determine index term inclusion in ranges
-	    /// for RangeQuerys.
-	    /// <p/>
-	    /// <strong>WARNING:</strong> Setting the rangeCollator to a non-null
-	    /// collator using this method will cause every single index Term in the
-	    /// Field referenced by lowerTerm and/or upperTerm to be examined.
-	    /// Depending on the number of index Terms in this Field, the operation could
-	    /// be very slow.
-	    /// 
-	    /// </summary>
-	    /// <value> the collator to use when constructing RangeQuerys </value>
-	    public virtual CompareInfo RangeCollator
-	    {
-	        set { rangeCollator = value; }
-	        get { return rangeCollator; }
-	    }
-
-	    protected internal virtual void AddClause(IList<BooleanClause> clauses, int conj, int mods, Query q)
-		{
-			bool required, prohibited;
-			
-			// If this term is introduced by AND, make the preceding term required,
-			// unless it's already prohibited
-			if (clauses.Count > 0 && conj == CONJ_AND)
-			{
-				BooleanClause c = clauses[clauses.Count - 1];
+        /// </summary>
+        public virtual DateTools.Resolution getDateResolution(String fieldName)
+        {
+            if (fieldName == null)
+            {
+                throw new ArgumentException("Field cannot be null.");
+            }
+
+            if (fieldToDateResolution == null)
+            {
+                // no field specific date resolutions set; return default date resolution instead
+                return this.dateResolution;
+            }
+
+            DateTools.Resolution resolution = fieldToDateResolution[fieldName];
+            if (resolution == null)
+            {
+                // no date resolutions set for the given field; return default date resolution instead
+                resolution = this.dateResolution;
+            }
+
+            return resolution;
+        }
+
+        /// <summary> Gets or sets the collator used to determine index term inclusion in ranges
+        /// for RangeQuerys.
+        /// <p/>
+        /// <strong>WARNING:</strong> Setting the rangeCollator to a non-null
+        /// collator using this method will cause every single index Term in the
+        /// Field referenced by lowerTerm and/or upperTerm to be examined.
+        /// Depending on the number of index Terms in this Field, the operation could
+        /// be very slow.
+        /// 
+        /// </summary>
+        /// <value> the collator to use when constructing RangeQuerys </value>
+        public virtual CompareInfo RangeCollator
+        {
+            set { rangeCollator = value; }
+            get { return rangeCollator; }
+        }
+
+        protected internal virtual void AddClause(List<BooleanClause> clauses, int conj, int mods, Query q)
+        {
+            bool required, prohibited;
+
+            // If this term is introduced by AND, make the preceding term required,
+            // unless it's already prohibited
+            if (clauses.Count > 0 && conj == CONJ_AND)
+            {
+                BooleanClause c = clauses[clauses.Count - 1];
                 if (!c.Prohibited)
-					c.SetOccur(BooleanClause.Occur.MUST);
-			}
-			
-			if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR)
-			{
-				// If this term is introduced by OR, make the preceding term optional,
-				// unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
-				// notice if the input is a OR b, first term is parsed as required; without
-				// this modification a OR b would parsed as +a OR b
-				BooleanClause c = clauses[clauses.Count - 1];
+                    c.SetOccur(BooleanClause.Occur.MUST);
+            }
+
+            if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR)
+            {
+                // If this term is introduced by OR, make the preceding term optional,
+                // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
+                // notice if the input is a OR b, first term is parsed as required; without
+                // this modification a OR b would parsed as +a OR b
+                BooleanClause c = clauses[clauses.Count - 1];
                 if (!c.Prohibited)
-					c.SetOccur(BooleanClause.Occur.SHOULD);
-			}
-			
-			// We might have been passed a null query; the term might have been
-			// filtered away by the analyzer.
-			if (q == null)
-				return ;
-			
-			if (operator_Renamed == OR_OPERATOR)
-			{
-				// We set REQUIRED if we're introduced by AND or +; PROHIBITED if
-				// introduced by NOT or -; make sure not to set both.
-				prohibited = (mods == MOD_NOT);
-				required = (mods == MOD_REQ);
-				if (conj == CONJ_AND && !prohibited)
-				{
-					required = true;
-				}
-			}
-			else
-			{
-				// We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
-				// if not PROHIBITED and not introduced by OR
-				prohibited = (mods == MOD_NOT);
-				required = (!prohibited && conj != CONJ_OR);
-			}
-			if (required && !prohibited)
-				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST));
-			else if (!required && !prohibited)
-				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.SHOULD));
-			else if (!required && prohibited)
-				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST_NOT));
-			else
-				throw new System.SystemException("Clause cannot be both required and prohibited");
-		}
-		
-		
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		public /*protected internal*/ virtual Query GetFieldQuery(System.String field, System.String queryText)
-		{
-			// Use the analyzer to get all the tokens, and then build a TermQuery,
-			// PhraseQuery, or nothing based on the term count
-			
-			TokenStream source;
-			try
-			{
-				source = analyzer.ReusableTokenStream(field, new System.IO.StringReader(queryText));
-				source.Reset();
-			}
-			catch (System.IO.IOException e)
-			{
-				source = analyzer.TokenStream(field, new System.IO.StringReader(queryText));
-			}
-			CachingTokenFilter buffer = new CachingTokenFilter(source);
-			TermAttribute termAtt = null;
-			PositionIncrementAttribute posIncrAtt = null;
-			int numTokens = 0;
-			
-			bool success = false;
-			try
-			{
-				buffer.Reset();
-				success = true;
-			}
-			catch (System.IO.IOException e)
-			{
-				// success==false if we hit an exception
-			}
-			if (success)
-			{
+                    c.SetOccur(BooleanClause.Occur.SHOULD);
+            }
+
+            // We might have been passed a null query; the term might have been
+            // filtered away by the analyzer.
+            if (q == null)
+                return;
+
+            if (operator_Renamed == OR_OPERATOR)
+            {
+                // We set REQUIRED if we're introduced by AND or +; PROHIBITED if
+                // introduced by NOT or -; make sure not to set both.
+                prohibited = (mods == MOD_NOT);
+                required = (mods == MOD_REQ);
+                if (conj == CONJ_AND && !prohibited)
+                {
+                    required = true;
+                }
+            }
+            else
+            {
+                // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
+                // if not PROHIBITED and not introduced by OR
+                prohibited = (mods == MOD_NOT);
+                required = (!prohibited && conj != CONJ_OR);
+            }
+            if (required && !prohibited)
+                clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST));
+            else if (!required && !prohibited)
+                clauses.Add(NewBooleanClause(q, BooleanClause.Occur.SHOULD));
+            else if (!required && prohibited)
+                clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST_NOT));
+            else
+                throw new SystemException("Clause cannot be both required and prohibited");
+        }
+
+
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetFieldQuery(String field, String queryText)
+        {
+            // Use the analyzer to get all the tokens, and then build a TermQuery,
+            // PhraseQuery, or nothing based on the term count
+
+            TokenStream source;
+            try
+            {
+                source = analyzer.ReusableTokenStream(field, new StringReader(queryText));
+                source.Reset();
+            }
+            catch (IOException e)
+            {
+                source = analyzer.TokenStream(field, new StringReader(queryText));
+            }
+            CachingTokenFilter buffer = new CachingTokenFilter(source);
+            TermAttribute termAtt = null;
+            PositionIncrementAttribute posIncrAtt = null;
+            int numTokens = 0;
+
+            bool success = false;
+            try
+            {
+                buffer.Reset();
+                success = true;
+            }
+            catch (IOException e)
+            {
+                // success==false if we hit an exception
+            }
+            if (success)
+            {
                 if (buffer.HasAttribute<TermAttribute>())
-				{
+                {
                     termAtt = buffer.GetAttribute<TermAttribute>();
-				}
+                }
                 if (buffer.HasAttribute<PositionIncrementAttribute>())
-				{
-					posIncrAtt = buffer.GetAttribute<PositionIncrementAttribute>();
-				}
-			}
-			
-			int positionCount = 0;
-			bool severalTokensAtSamePosition = false;
-			
-			bool hasMoreTokens = false;
-			if (termAtt != null)
-			{
-				try
-				{
-					hasMoreTokens = buffer.IncrementToken();
-					while (hasMoreTokens)
-					{
-						numTokens++;
-						int positionIncrement = (posIncrAtt != null)?posIncrAtt.PositionIncrement:1;
-						if (positionIncrement != 0)
-						{
-							positionCount += positionIncrement;
-						}
-						else
-						{
-							severalTokensAtSamePosition = true;
-						}
-						hasMoreTokens = buffer.IncrementToken();
-					}
-				}
-				catch (System.IO.IOException e)
-				{
-					// ignore
-				}
-			}
-			try
-			{
-				// rewind the buffer stream
-				buffer.Reset();
-				
-				// close original stream - all tokens buffered
-				source.Close();
-			}
-			catch (System.IO.IOException e)
-			{
-				// ignore
-			}
-			
-			if (numTokens == 0)
-				return null;
-			else if (numTokens == 1)
-			{
-				System.String term = null;
-				try
-				{
-					bool hasNext = buffer.IncrementToken();
-					System.Diagnostics.Debug.Assert(hasNext == true);
-					term = termAtt.Term();
-				}
-				catch (System.IO.IOException e)
-				{
-					// safe to ignore, because we know the number of tokens
-				}
-				return NewTermQuery(new Term(field, term));
-			}
-			else
-			{
-				if (severalTokensAtSamePosition)
-				{
-					if (positionCount == 1)
-					{
-						// no phrase query:
-						BooleanQuery q = NewBooleanQuery(true);
-						for (int i = 0; i < numTokens; i++)
-						{
-							System.String term = null;
-							try
-							{
-								bool hasNext = buffer.IncrementToken();
-								System.Diagnostics.Debug.Assert(hasNext == true);
-								term = termAtt.Term();
-							}
-							catch (System.IO.IOException e)
-							{
-								// safe to ignore, because we know the number of tokens
-							}
-							
-							Query currentQuery = NewTermQuery(new Term(field, term));
-							q.Add(currentQuery, BooleanClause.Occur.SHOULD);
-						}
-						return q;
-					}
-					else
-					{
-						// phrase query:
-						MultiPhraseQuery mpq = NewMultiPhraseQuery();
-						mpq.Slop = phraseSlop;
-						IList<Term> multiTerms = new List<Term>();
-						int position = - 1;
-						for (int i = 0; i < numTokens; i++)
-						{
-							System.String term = null;
-							int positionIncrement = 1;
-							try
-							{
-								bool hasNext = buffer.IncrementToken();
-								System.Diagnostics.Debug.Assert(hasNext == true);
-								term = termAtt.Term();
-								if (posIncrAtt != null)
-								{
-									positionIncrement = posIncrAtt.PositionIncrement;
-								}
-							}
-							catch (System.IO.IOException e)
-							{
-								// safe to ignore, because we know the number of tokens
-							}
-							
-							if (positionIncrement > 0 && multiTerms.Count > 0)
-							{
-								if (enablePositionIncrements)
-								{
-                                    mpq.Add(multiTerms.ToArray(), position);
-								}
-								else
-								{
-                                    mpq.Add(multiTerms.ToArray());
-								}
-								multiTerms.Clear();
-							}
-							position += positionIncrement;
-							multiTerms.Add(new Term(field, term));
-						}
-						if (enablePositionIncrements)
-						{
-                            mpq.Add(multiTerms.ToArray(), position);
-						}
-						else
-						{
-                            mpq.Add(multiTerms.ToArray());
-						}
-						return mpq;
-					}
-				}
-				else
-				{
-					PhraseQuery pq = NewPhraseQuery();
-					pq.Slop = phraseSlop;
-					int position = - 1;
-					
-					
-					for (int i = 0; i < numTokens; i++)
-					{
-						System.String term = null;
-						int positionIncrement = 1;
-						
-						try
-						{
-							bool hasNext = buffer.IncrementToken();
-							System.Diagnostics.Debug.Assert(hasNext == true);
-							term = termAtt.Term();
-							if (posIncrAtt != null)
-							{
-								positionIncrement = posIncrAtt.PositionIncrement;
-							}
-						}
-						catch (System.IO.IOException e)
-						{
-							// safe to ignore, because we know the number of tokens
-						}
-						
-						if (enablePositionIncrements)
-						{
-							position += positionIncrement;
-							pq.Add(new Term(field, term), position);
-						}
-						else
-						{
-							pq.Add(new Term(field, term));
-						}
-					}
-					return pq;
-				}
-			}
-		}
-		
-		
-		
-		/// <summary> Base implementation delegates to <see cref="GetFieldQuery(String,String)" />.
-		/// This method may be overridden, for example, to return
-		/// a SpanNearQuery instead of a PhraseQuery.
-		/// 
-		/// </summary>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		protected internal virtual Query GetFieldQuery(System.String field, System.String queryText, int slop)
-		{
-			Query query = GetFieldQuery(field, queryText);
-			
-			if (query is PhraseQuery)
-			{
-				((PhraseQuery) query).Slop = slop;
-			}
-			if (query is MultiPhraseQuery)
-			{
-				((MultiPhraseQuery) query).Slop = slop;
-			}
-			
-			return query;
-		}
-		
-		
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		protected internal virtual Query GetRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
-		{
-			if (lowercaseExpandedTerms)
-			{
-				part1 = part1.ToLower();
-				part2 = part2.ToLower();
-			}
+                {
+                    posIncrAtt = buffer.GetAttribute<PositionIncrementAttribute>();
+                }
+            }
+
+            int positionCount = 0;
+            bool severalTokensAtSamePosition = false;
+
+            bool hasMoreTokens = false;
+            if (termAtt != null)
+            {
+                try
+                {
+                    hasMoreTokens = buffer.IncrementToken();
+                    while (hasMoreTokens)
+                    {
+                        numTokens++;
+                        int positionIncrement = (posIncrAtt != null) ? posIncrAtt.PositionIncrement : 1;
+                        if (positionIncrement != 0)
+                        {
+                            positionCount += positionIncrement;
+                        }
+                        else
+                        {
+                            severalTokensAtSamePosition = true;
+                        }
+                        hasMoreTokens = buffer.IncrementToken();
+                    }
+                }
+                catch (IOException e)
+                {
+                    // ignore
+                }
+            }
             try
             {
-                System.DateTime d1;
-                System.DateTime d2;
+                // rewind the buffer stream
+                buffer.Reset();
 
+                // close original stream - all tokens buffered
+                source.Close();
+            }
+            catch (IOException e)
+            {
+                // ignore
+            }
+
+            if (numTokens == 0)
+                return null;
+            else if (numTokens == 1)
+            {
+                String term = null;
                 try
                 {
-                    d1 = System.DateTime.Parse(part1, locale);
+                    bool hasNext = buffer.IncrementToken();
+                    Debug.Assert(hasNext);
+                    term = termAtt.Term();
                 }
-                catch (System.Exception)
+                catch (IOException e)
                 {
-                    d1 = System.DateTime.Parse(part1);
+                    // safe to ignore, because we know the number of tokens
                 }
-                try
+                return NewTermQuery(new Term(field, term));
+            }
+            else
+            {
+                if (severalTokensAtSamePosition)
                 {
-                    d2 = System.DateTime.Parse(part2, locale);
+                    if (positionCount == 1)
+                    {
+                        // no phrase query:
+                        BooleanQuery q = NewBooleanQuery(true);
+                        for (int i = 0; i < numTokens; i++)
+                        {
+                            String term = null;
+                            try
+                            {
+                                bool hasNext = buffer.IncrementToken();
+                                Debug.Assert(hasNext);
+                                term = termAtt.Term();
+                            }
+                            catch (IOException e)
+                            {
+                                // safe to ignore, because we know the number of tokens
+                            }
+
+                            Query currentQuery = NewTermQuery(
+                                new Term(field, term));
+                            q.Add(currentQuery, BooleanClause.Occur.SHOULD);
+                        }
+                        return q;
+                    }
+                    else
+                    {
+                        // phrase query:
+                        MultiPhraseQuery mpq = NewMultiPhraseQuery();
+                        mpq.Slop = phraseSlop;
+                        List<Term> multiTerms = new List<Term>();
+                        int position = -1;
+                        for (int i = 0; i < numTokens; i++)
+                        {
+                            String term = null;
+                            int positionIncrement = 1;
+                            try
+                            {
+                                bool hasNext = buffer.IncrementToken();
+                                Debug.Assert(hasNext == true);
+                                term = termAtt.Term();
+                                if (posIncrAtt != null)
+                                {
+                                    positionIncrement = posIncrAtt.PositionIncrement;
+                                }
+                            }
+                            catch (IOException e)
+                            {
+                                // safe to ignore, because we know the number of tokens
+                            }
+
+                            if (positionIncrement > 0 && multiTerms.Count > 0)
+                            {
+                                if (enablePositionIncrements)
+                                {
+                                    mpq.Add(multiTerms.ToArray(), position);
+                                }
+                                else
+                                {
+                                    mpq.Add(multiTerms.ToArray());
+                                }
+                                multiTerms.Clear();
+                            }
+                            position += positionIncrement;
+                            multiTerms.Add(new Term(field, term));
+                        }
+                        if (enablePositionIncrements)
+                        {
+                            mpq.Add(multiTerms.ToArray(), position);
+                        }
+                        else
+                        {
+                            mpq.Add(multiTerms.ToArray());
+                        }
+                        return mpq;
+                    }
                 }
-                catch (System.Exception)
+                else
                 {
-                    d2 = System.DateTime.Parse(part2);
+                    PhraseQuery pq = NewPhraseQuery();
+                    pq.Slop = phraseSlop;
+                    int position = -1;
+
+
+                    for (int i = 0; i < numTokens; i++)
+                    {
+                        String term = null;
+                        int positionIncrement = 1;
+
+                        try
+                        {
+                            bool hasNext = buffer.IncrementToken();
+                            Debug.Assert(hasNext == true);
+                            term = termAtt.Term();
+                            if (posIncrAtt != null)
+                            {
+                                positionIncrement = posIncrAtt.PositionIncrement;
+                            }
+                        }
+                        catch (IOException e)
+                        {
+                            // safe to ignore, because we know the number of tokens
+                        }
+
+                        if (enablePositionIncrements)
+                        {
+                            position += positionIncrement;
+                            pq.Add(new Term(field, term), position);
+                        }
+                        else
+                        {
+                            pq.Add(new Term(field, term));
+                        }
+                    }
+                    return pq;
+                }
+            }
+        }
+
+
+        /// <summary> Base implementation delegates to {@link #GetFieldQuery(String,String)}.
+        /// This method may be overridden, for example, to return
+        /// a SpanNearQuery instead of a PhraseQuery.
+        /// 
+        /// </summary>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetFieldQuery(String field, String queryText, int slop)
+        {
+            Query query = GetFieldQuery(field, queryText);
+
+            if (query is PhraseQuery)
+            {
+                ((PhraseQuery)query).Slop = slop;
+            }
+            if (query is MultiPhraseQuery)
+            {
+                ((MultiPhraseQuery)query).Slop = slop;
+            }
+
+            return query;
+        }
+
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetRangeQuery(String field,
+                                      String part1,
+                                      String part2,
+                                      bool inclusive)
+        {
+            if (lowercaseExpandedTerms)
+            {
+                part1 = part1.ToLower();
+                part2 = part2.ToLower();
+            }
+
+            try
+            {
+                DateTime d1, d2;
+                if (_useJavaStyleDateRangeParsing)
+                {
+                    // TODO: This doesn't emulate java perfectly.
+                    // Java allows parsing of the string up to the end of the pattern
+                    // and then ignores everything else.  .NET will throw an exception, 
+                    // so this will fail in those cases, though the code below is clear
+                    // that users can only specify the date, not the time.
+                    var shortFormat = locale.DateTimeFormat.ShortDatePattern;
+                    d1 = DateTime.ParseExact(part1, shortFormat, locale);
+                    d2 = DateTime.ParseExact(part2, shortFormat, locale);
+                }
+                else
+                {
+                    d1 = DateTime.Parse(part1, locale);
+                    d2 = DateTime.Parse(part2, locale);
                 }
 
                 if (inclusive)
@@ -791,18 +782,17 @@ namespace Lucene.Net.QueryParsers
                     // The user can only specify the date, not the time, so make sure
                     // the time is set to the latest possible time of that date to really
                     // include all documents:
-                    System.Globalization.Calendar cal = new System.Globalization.GregorianCalendar();
-                    System.DateTime tempDate = d2;
-                    d2 = d2.AddHours(23 - tempDate.Hour);
-                    d2 = d2.AddMinutes(59 - tempDate.Minute);
-                    d2 = d2.AddSeconds(59 - tempDate.Second);
-                    d2 = d2.AddMilliseconds(999 - tempDate.Millisecond);
+                    var cal = locale.Calendar;
+                    d2 = cal.AddHours(d2, 23);
+                    d2 = cal.AddMinutes(d2, 59);
+                    d2 = cal.AddSeconds(d2, 59);
+                    d2 = cal.AddMilliseconds(d2, 999);
                 }
-                DateTools.Resolution resolution = GetDateResolution(field);
+                DateTools.Resolution resolution = getDateResolution(field);
                 if (resolution == null)
                 {
                     // no default or field specific date resolution has been set,
-					// use deprecated DateField to maintain compatibility with
+                    // use deprecated DateField to maintain compatibility with
                     // pre-1.9 Lucene versions.
                     part1 = DateField.DateToString(d1);
                     part2 = DateField.DateToString(d2);
@@ -813,1404 +803,1299 @@ namespace Lucene.Net.QueryParsers
                     part2 = DateTools.DateToString(d2, resolution);
                 }
             }
-            catch (System.Exception)
+            catch (Exception)
             {
             }
 
             return NewRangeQuery(field, part1, part2, inclusive);
         }
-		
-		/// <summary> Builds a new BooleanQuery instance</summary>
-		/// <param name="disableCoord">disable coord
-		/// </param>
-		/// <returns> new BooleanQuery instance
-		/// </returns>
-		protected internal virtual BooleanQuery NewBooleanQuery(bool disableCoord)
-		{
-			return new BooleanQuery(disableCoord);
-		}
-		
-		/// <summary> Builds a new BooleanClause instance</summary>
-		/// <param name="q">sub query
-		/// </param>
-		/// <param name="occur">how this clause should occur when matching documents
-		/// </param>
-		/// <returns> new BooleanClause instance
-		/// </returns>
-		protected internal virtual BooleanClause NewBooleanClause(Query q, BooleanClause.Occur occur)
-		{
-			return new BooleanClause(q, occur);
-		}
-		
-		/// <summary> Builds a new TermQuery instance</summary>
-		/// <param name="term">term
-		/// </param>
-		/// <returns> new TermQuery instance
-		/// </returns>
-		protected internal virtual Query NewTermQuery(Term term)
-		{
-			return new TermQuery(term);
-		}
-		
-		/// <summary> Builds a new PhraseQuery instance</summary>
-		/// <returns> new PhraseQuery instance
-		/// </returns>
-		protected internal virtual PhraseQuery NewPhraseQuery()
-		{
-			return new PhraseQuery();
-		}
-		
-		/// <summary> Builds a new MultiPhraseQuery instance</summary>
-		/// <returns> new MultiPhraseQuery instance
-		/// </returns>
-		protected internal virtual MultiPhraseQuery NewMultiPhraseQuery()
-		{
-			return new MultiPhraseQuery();
-		}
-		
-		/// <summary> Builds a new PrefixQuery instance</summary>
-		/// <param name="prefix">Prefix term
-		/// </param>
-		/// <returns> new PrefixQuery instance
-		/// </returns>
-		protected internal virtual Query NewPrefixQuery(Term prefix)
-		{
-			PrefixQuery query = new PrefixQuery(prefix);
-			query.QueryRewriteMethod = multiTermRewriteMethod;
-			return query;
-		}
-		
-		/// <summary> Builds a new FuzzyQuery instance</summary>
-		/// <param name="term">Term
-		/// </param>
-		/// <param name="minimumSimilarity">minimum similarity
-		/// </param>
-		/// <param name="prefixLength">prefix length
-		/// </param>
-		/// <returns> new FuzzyQuery Instance
-		/// </returns>
-		protected internal virtual Query NewFuzzyQuery(Term term, float minimumSimilarity, int prefixLength)
-		{
-			// FuzzyQuery doesn't yet allow constant score rewrite
-			return new FuzzyQuery(term, minimumSimilarity, prefixLength);
-		}
-		
-		/// <summary> Builds a new TermRangeQuery instance</summary>
-		/// <param name="field">Field
-		/// </param>
-		/// <param name="part1">min
-		/// </param>
-		/// <param name="part2">max
-		/// </param>
-		/// <param name="inclusive">true if range is inclusive
-		/// </param>
-		/// <returns> new TermRangeQuery instance
-		/// </returns>
-		protected internal virtual Query NewRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
-		{
-			TermRangeQuery query = new TermRangeQuery(field, part1, part2, inclusive, inclusive, rangeCollator);
-			query.QueryRewriteMethod = multiTermRewriteMethod;
-			return query;
-		}
-		
-		/// <summary> Builds a new MatchAllDocsQuery instance</summary>
-		/// <returns> new MatchAllDocsQuery instance
-		/// </returns>
-		protected internal virtual Query NewMatchAllDocsQuery()
-		{
-			return new MatchAllDocsQuery();
-		}
-		
-		/// <summary> Builds a new WildcardQuery instance</summary>
-		/// <param name="t">wildcard term
-		/// </param>
-		/// <returns> new WildcardQuery instance
-		/// </returns>
-		protected internal virtual Query NewWildcardQuery(Term t)
-		{
-			WildcardQuery query = new WildcardQuery(t);
-			query.QueryRewriteMethod = multiTermRewriteMethod;
-			return query;
-		}
-		
-		/// <summary> Factory method for generating query, given a set of clauses.
-		/// By default creates a boolean query composed of clauses passed in.
-		/// 
-		/// Can be overridden by extending classes, to modify query being
-		/// returned.
-		/// 
-		/// </summary>
-		/// <param name="clauses">List that contains <see cref="BooleanClause" /> instances
-		/// to join.
-		/// 
-		/// </param>
-		/// <returns> Resulting <see cref="Query" /> object.
-		/// </returns>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses)
-		{
-			return GetBooleanQuery(clauses, false);
-		}
-		
-		/// <summary> Factory method for generating query, given a set of clauses.
-		/// By default creates a boolean query composed of clauses passed in.
-		/// 
-		/// Can be overridden by extending classes, to modify query being
-		/// returned.
-		/// 
-		/// </summary>
-		/// <param name="clauses">List that contains <see cref="BooleanClause" /> instances
-		/// to join.
-		/// </param>
-		/// <param name="disableCoord">true if coord scoring should be disabled.
-		/// 
-		/// </param>
-		/// <returns> Resulting <see cref="Query" /> object.
-		/// </returns>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses, bool disableCoord)
-		{
-			if (clauses.Count == 0)
-			{
-				return null; // all clause words were filtered away by the analyzer.
-			}
-			BooleanQuery query = NewBooleanQuery(disableCoord);
-			foreach(BooleanClause clause in clauses)
-			{
+
+        /// <summary> Builds a new BooleanQuery instance</summary>
+        /// <param name="disableCoord">disable coord
+        /// </param>
+        /// <returns> new BooleanQuery instance
+        /// </returns>
+        protected internal virtual BooleanQuery NewBooleanQuery(bool disableCoord)
+        {
+            return new BooleanQuery(disableCoord);
+        }
+
+        /// <summary> Builds a new BooleanClause instance</summary>
+        /// <param name="q">sub query
+        /// </param>
+        /// <param name="occur">how this clause should occur when matching documents
+        /// </param>
+        /// <returns> new BooleanClause instance
+        /// </returns>
+        protected internal virtual BooleanClause NewBooleanClause(Query q, BooleanClause.Occur occur)
+        {
+            return new BooleanClause(q, occur);
+        }
+
+        /// <summary> Builds a new TermQuery instance</summary>
+        /// <param name="term">term
+        /// </param>
+        /// <returns> new TermQuery instance
+        /// </returns>
+        protected internal virtual Query NewTermQuery(Term term)
+        {
+            return new TermQuery(term);
+        }
+
+        /// <summary> Builds a new PhraseQuery instance</summary>
+        /// <returns> new PhraseQuery instance
+        /// </returns>
+        protected internal virtual PhraseQuery NewPhraseQuery()
+        {
+            return new PhraseQuery();
+        }
+
+        /// <summary> Builds a new MultiPhraseQuery instance</summary>
+        /// <returns> new MultiPhraseQuery instance
+        /// </returns>
+        protected internal virtual MultiPhraseQuery NewMultiPhraseQuery()
+        {
+            return new MultiPhraseQuery();
+        }
+
+        /// <summary> Builds a new PrefixQuery instance</summary>
+        /// <param name="prefix">Prefix term
+        /// </param>
+        /// <returns> new PrefixQuery instance
+        /// </returns>
+        protected internal virtual Query NewPrefixQuery(Term prefix)
+        {
+            return new PrefixQuery(prefix) { QueryRewriteMethod = multiTermRewriteMethod };
+        }
+
+        /// <summary> Builds a new FuzzyQuery instance</summary>
+        /// <param name="term">Term
+        /// </param>
+        /// <param name="minimumSimilarity">minimum similarity
+        /// </param>
+        /// <param name="prefixLength">prefix length
+        /// </param>
+        /// <returns> new FuzzyQuery Instance
+        /// </returns>
+        protected internal virtual Query NewFuzzyQuery(Term term, float minimumSimilarity, int prefixLength)
+        {
+            // FuzzyQuery doesn't yet allow constant score rewrite
+            return new FuzzyQuery(term, minimumSimilarity, prefixLength);
+        }
+
+        /// <summary> Builds a new TermRangeQuery instance</summary>
+        /// <param name="field">Field
+        /// </param>
+        /// <param name="part1">min
+        /// </param>
+        /// <param name="part2">max
+        /// </param>
+        /// <param name="inclusive">true if range is inclusive
+        /// </param>
+        /// <returns> new TermRangeQuery instance
+        /// </returns>
+        protected internal virtual Query NewRangeQuery(String field, String part1, String part2, bool inclusive)
+        {
+            return new TermRangeQuery(field, part1, part2, inclusive, inclusive, rangeCollator) { QueryRewriteMethod = multiTermRewriteMethod };
+        }
+
+        /// <summary> Builds a new MatchAllDocsQuery instance</summary>
+        /// <returns> new MatchAllDocsQuery instance
+        /// </returns>
+        protected internal virtual Query NewMatchAllDocsQuery()
+        {
+            return new MatchAllDocsQuery();
+        }
+
+        /// <summary> Builds a new WildcardQuery instance</summary>
+        /// <param name="t">wildcard term
+        /// </param>
+        /// <returns> new WildcardQuery instance
+        /// </returns>
+        protected internal virtual Query NewWildcardQuery(Term t)
+        {
+            return new WildcardQuery(t) { QueryRewriteMethod = multiTermRewriteMethod };
+        }
+
+        /// <summary> Factory method for generating query, given a set of clauses.
+        /// By default creates a boolean query composed of clauses passed in.
+        /// 
+        /// Can be overridden by extending classes, to modify query being
+        /// returned.
+        /// 
+        /// </summary>
+        /// <param name="clauses">List that contains {@link BooleanClause} instances
+        /// to join.
+        /// 
+        /// </param>
+        /// <returns> Resulting {@link Query} object.
+        /// </returns>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses)
+        {
+            return GetBooleanQuery(clauses, false);
+        }
+
+        /// <summary> Factory method for generating query, given a set of clauses.
+        /// By default creates a boolean query composed of clauses passed in.
+        /// 
+        /// Can be overridden by extending classes, to modify query being
+        /// returned.
+        /// 
+        /// </summary>
+        /// <param name="clauses">List that contains {@link BooleanClause} instances
+        /// to join.
+        /// </param>
+        /// <param name="disableCoord">true if coord scoring should be disabled.
+        /// 
+        /// </param>
+        /// <returns> Resulting {@link Query} object.
+        /// </returns>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses, bool disableCoord)
+        {
+            if (clauses.Count == 0)
+            {
+                return null; // all clause words were filtered away by the analyzer.
+            }
+            BooleanQuery query = NewBooleanQuery(disableCoord);
+            foreach (var clause in clauses)
+            {
                 query.Add(clause);
-			}
-			return query;
-		}
-		
-		/// <summary> Factory method for generating a query. Called when parser
-		/// parses an input term token that contains one or more wildcard
-		/// characters (? and *), but is not a prefix term token (one
-		/// that has just a single * character at the end)
-		/// <p/>
-		/// Depending on settings, prefix term may be lower-cased
-		/// automatically. It will not go through the default Analyzer,
-		/// however, since normal Analyzers are unlikely to work properly
-		/// with wildcard templates.
-		/// <p/>
-		/// Can be overridden by extending classes, to provide custom handling for
-		/// wildcard queries, which may be necessary due to missing analyzer calls.
-		/// 
-		/// </summary>
-		/// <param name="field">Name of the field query will use.
-		/// </param>
-		/// <param name="termStr">Term token that contains one or more wild card
-		/// characters (? or *), but is not simple prefix term
-		/// 
-		/// </param>
-		/// <returns> Resulting <see cref="Query" /> built for the term
-		/// </returns>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		public /*protected internal*/ virtual Query GetWildcardQuery(System.String field, System.String termStr)
-		{
-			if ("*".Equals(field))
-			{
-				if ("*".Equals(termStr))
-					return NewMatchAllDocsQuery();
-			}
-			if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?")))
-				throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
-			if (lowercaseExpandedTerms)
-			{
-				termStr = termStr.ToLower();
-			}
-			Term t = new Term(field, termStr);
-			return NewWildcardQuery(t);
-		}
-		
-		/// <summary> Factory method for generating a query (similar to
-		/// <see cref="GetWildcardQuery" />). Called when parser parses an input term
-		/// token that uses prefix notation; that is, contains a single '*' wildcard
-		/// character as its last character. Since this is a special case
-		/// of generic wildcard term, and such a query can be optimized easily,
-		/// this usually results in a different query object.
-		/// <p/>
-		/// Depending on settings, a prefix term may be lower-cased
-		/// automatically. It will not go through the default Analyzer,
-		/// however, since normal Analyzers are unlikely to work properly
-		/// with wildcard templates.
-		/// <p/>
-		/// Can be overridden by extending classes, to provide custom handling for
-		/// wild card queries, which may be necessary due to missing analyzer calls.
-		/// 
-		/// </summary>
-		/// <param name="field">Name of the field query will use.
-		/// </param>
-		/// <param name="termStr">Term token to use for building term for the query
-		/// (<b>without</b> trailing '*' character!)
-		/// 
-		/// </param>
-		/// <returns> Resulting <see cref="Query" /> built for the term
-		/// </returns>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		public /*protected internal*/ virtual Query GetPrefixQuery(System.String field, System.String termStr)
-		{
-			if (!allowLeadingWildcard && termStr.StartsWith("*"))
-				throw new ParseException("'*' not allowed as first character in PrefixQuery");
-			if (lowercaseExpandedTerms)
-			{
-				termStr = termStr.ToLower();
-			}
-			Term t = new Term(field, termStr);
-			return NewPrefixQuery(t);
-		}
-		
-		/// <summary> Factory method for generating a query (similar to
-		/// <see cref="GetWildcardQuery" />). Called when parser parses
-		/// an input term token that has the fuzzy suffix (~) appended.
-		/// 
-		/// </summary>
-		/// <param name="field">Name of the field query will use.
-		/// </param>
-		/// <param name="termStr">Term token to use for building term for the query
-		/// 
-		/// </param>
-		/// <returns> Resulting <see cref="Query" /> built for the term
-		/// </returns>
-		/// <exception cref="ParseException">throw in overridden method to disallow
-		/// </exception>
-		public /*protected internal*/ virtual Query GetFuzzyQuery(System.String field, System.String termStr, float minSimilarity)
-		{
-			if (lowercaseExpandedTerms)
-			{
-				termStr = termStr.ToLower();
-			}
-			Term t = new Term(field, termStr);
-			return NewFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
-		}
-		
-		/// <summary> Returns a String where the escape char has been
-		/// removed, or kept only once if there was a double escape.
-		/// 
-		/// Supports escaped unicode characters, e. g. translates
-		/// <c>\\u0041</c> to <c>A</c>.
-		/// 
-		/// </summary>
-		private System.String DiscardEscapeChar(System.String input)
-		{
-			// Create char array to hold unescaped char sequence
-			char[] output = new char[input.Length];
-			
-			// The length of the output can be less than the input
-			// due to discarded escape chars. This variable holds
-			// the actual length of the output
-			int length = 0;
-			
-			// We remember whether the last processed character was 
-			// an escape character
-			bool lastCharWasEscapeChar = false;
-			
-			// The multiplier the current unicode digit must be multiplied with.
-			// E. g. the first digit must be multiplied with 16^3, the second with 16^2...
-			int codePointMultiplier = 0;
-			
-			// Used to calculate the codepoint of the escaped unicode character
-			int codePoint = 0;
-			
-			for (int i = 0; i < input.Length; i++)
-			{
-				char curChar = input[i];
-				if (codePointMultiplier > 0)
-				{
-					codePoint += HexToInt(curChar) * codePointMultiplier;
-					codePointMultiplier = Number.URShift(codePointMultiplier, 4);
-					if (codePointMultiplier == 0)
-					{
-						output[length++] = (char) codePoint;
-						codePoint = 0;
-					}
-				}
-				else if (lastCharWasEscapeChar)
-				{
-					if (curChar == 'u')
-					{
-						// found an escaped unicode character
-						codePointMultiplier = 16 * 16 * 16;
-					}
-					else
-					{
-						// this character was escaped
-						output[length] = curChar;
-						length++;
-					}
-					lastCharWasEscapeChar = false;
-				}
-				else
-				{
-					if (curChar == '\\')
-					{
-						lastCharWasEscapeChar = true;
-					}
-					else
-					{
-						output[length] = curChar;
-						length++;
-					}
-				}
-			}
-			
-			if (codePointMultiplier > 0)
-			{
-				throw new ParseException("Truncated unicode escape sequence.");
-			}
-			
-			if (lastCharWasEscapeChar)
-			{
-				throw new ParseException("Term can not end with escape character.");
-			}
-			
-			return new System.String(output, 0, length);
-		}
-		
-		/// <summary>Returns the numeric value of the hexadecimal character </summary>
-		private static int HexToInt(char c)
-		{
-			if ('0' <= c && c <= '9')
-			{
-				return c - '0';
-			}
-			else if ('a' <= c && c <= 'f')
-			{
-				return c - 'a' + 10;
-			}
-			else if ('A' <= c && c <= 'F')
-			{
-				return c - 'A' + 10;
-			}
-			else
-			{
-				throw new ParseException("None-hex character in unicode escape sequence: " + c);
-			}
-		}
-		
-		/// <summary> Returns a String where those characters that QueryParser
-		/// expects to be escaped are escaped by a preceding <c>\</c>.
-		/// </summary>
-		public static System.String Escape(System.String s)
-		{
-			System.Text.StringBuilder sb = new System.Text.StringBuilder();
-			for (int i = 0; i < s.Length; i++)
-			{
-				char c = s[i];
-				// These characters are part of the query syntax and must be escaped
-                if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || 
-                    c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || 
-                    c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || 
-                    c == '?' || c == '|' || c == '&')
+            }
+            return query;
+        }
+
+        /// <summary> Factory method for generating a query. Called when parser
+        /// parses an input term token that contains one or more wildcard
+        /// characters (? and *), but is not a prefix term token (one
+        /// that has just a single * character at the end)
+        /// <p/>
+        /// Depending on settings, prefix term may be lower-cased
+        /// automatically. It will not go through the default Analyzer,
+        /// however, since normal Analyzers are unlikely to work properly
+        /// with wildcard templates.
+        /// <p/>
+        /// Can be overridden by extending classes, to provide custom handling for
+        /// wildcard queries, which may be necessary due to missing analyzer calls.
+        /// 
+        /// </summary>
+        /// <param name="field">Name of the field query will use.
+        /// </param>
+        /// <param name="termStr">Term token that contains one or more wild card
+        /// characters (? or *), but is not simple prefix term
+        /// 
+        /// </param>
+        /// <returns> Resulting {@link Query} built for the term
+        /// </returns>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetWildcardQuery(String field, String termStr)
+        {
+            if ("*".Equals(field))
+            {
+                if ("*".Equals(termStr)) return NewMatchAllDocsQuery();
+            }
+            if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?")))
+                throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
+            if (lowercaseExpandedTerms)
+            {
+                termStr = termStr.ToLower();
+            }
+            Term t = new Term(field, termStr);
+            return NewWildcardQuery(t);
+        }
+
+        /// <summary> Factory method for generating a query (similar to
+        /// {@link #getWildcardQuery}). Called when parser parses an input term
+        /// token that uses prefix notation; that is, contains a single '*' wildcard
+        /// character as its last character. Since this is a special case
+        /// of generic wildcard term, and such a query can be optimized easily,
+        /// this usually results in a different query object.
+        /// <p/>
+        /// Depending on settings, a prefix term may be lower-cased
+        /// automatically. It will not go through the default Analyzer,
+        /// however, since normal Analyzers are unlikely to work properly
+        /// with wildcard templates.
+        /// <p/>
+        /// Can be overridden by extending classes, to provide custom handling for
+        /// wild card queries, which may be necessary due to missing analyzer calls.
+        /// 
+        /// </summary>
+        /// <param name="field">Name of the field query will use.
+        /// </param>
+        /// <param name="termStr">Term token to use for building term for the query
+        /// (<b>without</b> trailing '*' character!)
+        /// 
+        /// </param>
+        /// <returns> Resulting {@link Query} built for the term
+        /// </returns>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetPrefixQuery(String field, String termStr)
+        {
+            if (!allowLeadingWildcard && termStr.StartsWith("*"))
+                throw new ParseException("'*' not allowed as first character in PrefixQuery");
+            if (lowercaseExpandedTerms)
+            {
+                termStr = termStr.ToLower();
+            }
+            Term t = new Term(field, termStr);
+            return NewPrefixQuery(t);
+        }
+
+        /// <summary> Factory method for generating a query (similar to
+        /// {@link #getWildcardQuery}). Called when parser parses
+        /// an input term token that has the fuzzy suffix (~) appended.
+        /// 
+        /// </summary>
+        /// <param name="field">Name of the field query will use.
+        /// </param>
+        /// <param name="termStr">Term token to use for building term for the query
+        /// 
+        /// </param>
+        /// <returns> Resulting {@link Query} built for the term
+        /// </returns>
+        /// <exception cref="ParseException">throw in overridden method to disallow
+        /// </exception>
+        protected internal virtual Query GetFuzzyQuery(String field, String termStr, float minSimilarity)
+        {
+            if (lowercaseExpandedTerms)
+            {
+                termStr = termStr.ToLower();
+            }
+            Term t = new Term(field, termStr);
+            return NewFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
+        }
+
+
+        /// <summary> Returns a String where the escape char has been
+        /// removed, or kept only once if there was a double escape.
+        /// 
+        /// Supports escaped unicode characters, e. g. translates
+        /// <code>\\u0041</code> to <code>A</code>.
+        /// 
+        /// </summary>
+        private String DiscardEscapeChar(String input)
+        {
+            // Create char array to hold unescaped char sequence
+            char[] output = new char[input.Length];
+
+            // The Length of the output can be less than the input
+            // due to discarded escape chars. This variable holds
+            // the actual Length of the output
+            int Length = 0;
+
+            // We remember whether the last processed character was 
+            // an escape character
+            bool lastCharWasEscapeChar = false;
+
+            // The multiplier the current unicode digit must be multiplied with.
+            // E. g. the first digit must be multiplied with 16^3, the second with 16^2...
+            int codePointMultiplier = 0;
+
+            // Used to calculate the codepoint of the escaped unicode character
+            int codePoint = 0;
+
+            for (int i = 0; i < input.Length; i++)
+            {
+                char curChar = input[i];
+                if (codePointMultiplier > 0)
+                {
+                    codePoint += HexToInt(curChar) * codePointMultiplier;
+                    codePointMultiplier = Number.URShift(codePointMultiplier, 4);
+                    if (codePointMultiplier == 0)
+                    {
+                        output[Length++] = (char)codePoint;
+                        codePoint = 0;
+                    }
+                }
+                else if (lastCharWasEscapeChar)
+                {
+                    if (curChar == 'u')
+                    {
+                        // found an escaped unicode character
+                        codePointMultiplier = 16 * 16 * 16;
+                    }
+                    else
+                    {
+                        // this character was escaped
+                        output[Length] = curChar;
+                        Length++;
+                    }
+                    lastCharWasEscapeChar = false;
+                }
+                else
+                {
+                    if (curChar == '\\')
+                    {
+                        lastCharWasEscapeChar = true;
+                    }
+                    else
+                    {
+                        output[Length] = curChar;
+                        Length++;
+                    }
+                }
+            }
+
+            if (codePointMultiplier > 0)
+            {
+                throw new ParseException("Truncated unicode escape sequence.");
+            }
+
+            if (lastCharWasEscapeChar)
+            {
+                throw new ParseException("Term can not end with escape character.");
+            }
+
+            return new String(output, 0, Length);
+        }
+
+        /// <summary>Returns the numeric value of the hexadecimal character </summary>
+        private static int HexToInt(char c)
+        {
+            if ('0' <= c && c <= '9')
+            {
+                return c - '0';
+            }
+            else if ('a' <= c && c <= 'f')
+            {
+                return c - 'a' + 10;
+            }
+            else if ('A' <= c && c <= 'F')
+            {
+                return c - 'A' + 10;
+            }
+            else
+            {
+                throw new ParseException("None-hex character in unicode escape sequence: " + c);
+            }
+        }
+
+        /// <summary> Returns a String where those characters that QueryParser
+        /// expects to be escaped are escaped by a preceding <code>\</code>.
+        /// </summary>
+        public static String Escape(String s)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < s.Length; i++)
+            {
+                char c = s[i];
+                // These characters are part of the query syntax and must be escaped
+                if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
+                    || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
+                    || c == '*' || c == '?' || c == '|' || c == '&')
                 {
                     sb.Append('\\');
                 }
-			    sb.Append(c);
-			}
-			return sb.ToString();
-		}
-		
-		/// <summary> Command line tool to test QueryParser, using <see cref="Lucene.Net.Analysis.SimpleAnalyzer" />.
-		/// Usage:<br/>
-		/// <c>java Lucene.Net.QueryParsers.QueryParser &lt;input&gt;</c>
-		/// </summary>
-		[STAThread]
-		public static void  Main(System.String[] args)
-		{
-			if (args.Length == 0)
-			{
-				System.Console.Out.WriteLine("Usage: java Lucene.Net.QueryParsers.QueryParser <input>");
-				System.Environment.Exit(0);
-			}
-			QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new Lucene.Net.Analysis.SimpleAnalyzer());
-			Query q = qp.Parse(args[0]);
-			System.Console.Out.WriteLine(q.ToString("field"));
-		}
-		
-		// *   Query  ::= ( Clause )*
-		// *   Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
-		public int Conjunction()
-		{
-			int ret = CONJ_NONE;
-			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
-			{
-				case Lucene.Net.QueryParsers.QueryParserConstants.AndToken: 
-				case Lucene.Net.QueryParsers.QueryParserConstants.OrToken: 
-					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
-					{
-						
-						case Lucene.Net.QueryParsers.QueryParserConstants.AndToken: 
-							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.AndToken);
-							ret = CONJ_AND;
-							break;
-						
-						case Lucene.Net.QueryParsers.QueryParserConstants.OrToken: 
-							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.OrToken);
-							ret = CONJ_OR;
-							break;
-						
-						default: 
-							jj_la1[0] = jj_gen;
-							Jj_consume_token(- 1);
-							throw new ParseException();
-						
-					}
-					break;
-				
-				default: 
-					jj_la1[1] = jj_gen;
-					;
-					break;
-				
-			}
-			{
-				if (true)
-					return ret;
-			}
-			throw new System.ApplicationException("Missing return statement in function");
-		}
-		
-		public int Modifiers()
-		{
-			int ret = MOD_NONE;
-			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
-			{
-				
-				case Lucene.Net.QueryParsers.QueryParserConstants.NotToken: 
-				case Lucene.Net.QueryParsers.QueryParserConstants.PlusToken: 
-				case Lucene.Net.QueryParsers.QueryParserConstants.MinusToken: 
-					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
-					{
-						
-						case Lucene.Net.QueryParsers.QueryParserConstants.PlusToken: 
-							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.PlusToken);
-							ret = MOD_REQ;
-							break;
-						
-						case Lucene.Net.QueryParsers.QueryParserConstants.MinusToken: 
-							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.MinusToken);
-							ret = MOD_NOT;
-							break;
-						
-						case Lucene.Net.QueryParsers.QueryParserConstants.NotToken: 
-							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NotToken);
-							ret = MOD_NOT;
-							break;
-						
-						default: 
-							jj_la1[2] = jj_gen;
-							Jj_consume_token(- 1);
-							throw new ParseException();
-						
-					}
-					break;
-				
-				default: 
-					jj_la1[3] = jj_gen;
-					;
-					break;
-				
-			}
-			{
-				if (true)
-					return ret;
-			}
-			throw new System.ApplicationException("Missing return statement in function");
-		}
-		
-		// This makes sure that there is no garbage after the query string

[... 1800 lines stripped ...]