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 2016/09/11 21:30:56 UTC

[25/50] [abbrv] lucenenet git commit: Moved Lucene.Net.QueryParser and Lucene.Net.Tests.QueryParser projects into src\ directory.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Classic/QueryParserTokenManager.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Classic/QueryParserTokenManager.cs b/src/Lucene.Net.QueryParser/Classic/QueryParserTokenManager.cs
new file mode 100644
index 0000000..aac1505
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Classic/QueryParserTokenManager.cs
@@ -0,0 +1,1356 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+
+namespace Lucene.Net.QueryParser.Classic
+{
+    /*
+     * 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>Token Manager. </summary>
+	public class QueryParserTokenManager //: QueryParserConstants
+	{
+		private void  InitBlock()
+		{
+			StreamWriter temp_writer;
+			temp_writer = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding);
+			temp_writer.AutoFlush = true;
+			debugStream = temp_writer;
+		}
+		
+		/// <summary>Debug output. </summary>
+		public StreamWriter debugStream;
+		/// <summary>Set debug output. </summary>
+		public virtual void  SetDebugStream(StreamWriter ds)
+		{
+			debugStream = ds;
+		}
+		private int JjStopStringLiteralDfa_2(int pos, long active0)
+		{
+			switch (pos)
+			{
+				
+				default: 
+					return - 1;
+				
+			}
+		}
+		private int JjStartNfa_2(int pos, long active0)
+		{
+			return JjMoveNfa_2(JjStopStringLiteralDfa_2(pos, active0), pos + 1);
+		}
+		private int JjStopAtPos(int pos, int kind)
+		{
+			jjmatchedKind = kind;
+			jjmatchedPos = pos;
+			return pos + 1;
+		}
+		private int JjMoveStringLiteralDfa0_2()
+		{
+			switch (curChar)
+			{
+				
+				case (char) (40): 
+					return JjStopAtPos(0, 14);
+				
+				case (char) (41): 
+					return JjStopAtPos(0, 15);
+				
+				case (char) (42): 
+					return JjStartNfaWithStates_2(0, 17, 49);
+				
+				case (char) (43):
+                    return JjStartNfaWithStates_2(0, 11, 15);
+				
+				case (char) (45):
+                    return JjStartNfaWithStates_2(0, 12, 15);
+				
+				case (char) (58): 
+					return JjStopAtPos(0, 16);
+				
+				case (char) (91): 
+					return JjStopAtPos(0, 25);
+				
+				case (char) (94): 
+					return JjStopAtPos(0, 18);
+				
+				case (char) (123): 
+					return JjStopAtPos(0, 26);
+				
+				default:
+                    return JjMoveNfa_2(0, 0);
+				
+			}
+		}
+		private int JjStartNfaWithStates_2(int pos, int kind, int state)
+		{
+			jjmatchedKind = kind;
+			jjmatchedPos = pos;
+			try
+			{
+				curChar = input_stream.ReadChar();
+			}
+			catch (IOException)
+			{
+				return pos + 1;
+			}
+            return JjMoveNfa_2(state, pos + 1);
+		}
+		internal static readonly ulong[] jjbitVec0 = new ulong[]{0x1L, 0x0L, 0x0L, 0x0L};
+		internal static readonly ulong[] jjbitVec1 = new ulong[]{0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL};
+		internal static readonly ulong[] jjbitVec3 = new ulong[]{0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL};
+		internal static readonly ulong[] jjbitVec4 = new ulong[]{0xfffefffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL};
+        private int JjMoveNfa_2(int startState, int curPos)
+		{
+			int startsAt = 0;
+            jjnewStateCnt = 49;
+			int i = 1;
+			jjstateSet[0] = startState;
+			int kind = 0x7fffffff;
+			for (; ; )
+			{
+				if (++jjround == 0x7fffffff)
+					ReInitRounds();
+				if (curChar < 64)
+				{
+					ulong l = (ulong) (1L << (int) curChar);
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 49: 
+							case 33:
+                                if ((0xfbff7cf8ffffd9ffL & l) == (ulong)0L)
+									break;
+								if (kind > 23)
+									kind = 23;
+								JjCheckNAddTwoStates(33, 34);
+								break;
+							
+							case 0:
+                                if ((0xfbff54f8ffffd9ffL & l) != (ulong)0L)
+								{
+									if (kind > 23)
+										kind = 23;
+									JjCheckNAddTwoStates(33, 34);
+								}
+								else if ((0x100002600L & l) != 0L)
+								{
+									if (kind > 7)
+										kind = 7;
+								}
+                                else if ((0x280200000000L & l) != 0L)
+                                    jjstateSet[jjnewStateCnt++] = 15;
+								else if (curChar == 47)
+									JjCheckNAddStates(0, 2);
+								else if (curChar == 34)
+                                    JjCheckNAddStates(3, 5);
+                                if ((0x7bff50f8ffffd9ffL & l) != 0L)
+								{
+									if (kind > 20)
+										kind = 20;
+                                    JjCheckNAddStates(6, 10);
+								}
+                                else if (curChar == 42)
+                                {
+                                    if (kind > 22)
+                                        kind = 22;
+                                }
+                                else if (curChar == 33)
+                                {
+                                    if (kind > 10)
+                                        kind = 10;
+                                }
+								if (curChar == 38)
+									jjstateSet[jjnewStateCnt++] = 4;
+								break;
+							
+							case 4: 
+								if (curChar == 38 && kind > 8)
+									kind = 8;
+								break;
+							
+							case 5: 
+								if (curChar == 38)
+									jjstateSet[jjnewStateCnt++] = 4;
+								break;
+							
+							case 13: 
+								if (curChar == 33 && kind > 10)
+									kind = 10;
+								break;
+							
+							case 14:
+                                if ((0x280200000000L & l) != 0L)
+                                    jjstateSet[jjnewStateCnt++] = 15;
+                                break;
+                            case 15:
+                                if ((0x100002600L & l) != 0L && kind > 13)
+                                    kind = 13;
+                                break;
+                            case 16:
+								if (curChar == 34)
+									JjCheckNAddStates(3, 5);
+								break;
+							case 17: 
+								if ((0xfffffffbffffffffL & l) != (ulong) 0L)
+									JjCheckNAddStates(3, 5);
+								break;
+							
+							case 19: 
+								JjCheckNAddStates(3, 5);
+								break;
+							
+							case 20: 
+								if (curChar == 34 && kind > 19)
+									kind = 19;
+								break;
+							
+							case 22: 
+								if ((0x3ff000000000000L & l) == 0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddStates(11, 14);
+								break;
+							
+							case 23: 
+								if (curChar == 46)
+									JjCheckNAdd(24);
+								break;
+							
+							case 24: 
+								if ((0x3ff000000000000L & l) == 0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+                                JjCheckNAddStates(15, 17);
+								break;
+							
+							case 25:
+                                if ((0x7bff78f8ffffd9ffL & l) == (ulong)0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 27: 
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 28:
+                                if ((0x7bff78f8ffffd9ffL & l) == 0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(28, 29);
+								break;
+							
+							case 30: 
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(28, 29);
+								break;
+							
+							case 31:
+                                if (curChar == 42 && kind > 22)
+                                    kind = 22;
+								break;
+							
+							case 32:
+                                if ((0xfbff54f8ffffd9ffL & l) == (ulong)0L)
+                                    break;
+                                if (kind > 23)
+                                    kind = 23;
+                                JjCheckNAddTwoStates(33, 34);
+                                break;
+                            case 35:
+                                if (kind > 23)
+                                    kind = 23;
+                                JjCheckNAddTwoStates(33, 34);
+                                break;
+                            case 36:
+                            case 38:
+                                if (curChar == 47)
+                                    JjCheckNAddStates(0, 2);
+                                break;
+                            case 37:
+                                if ((0xffff7fffffffffffL & l) != (ulong)0L)
+                                    JjCheckNAddStates(0, 2);
+                                break;
+                            case 40:
+                                if (curChar == 47 && kind > 24)
+                                    kind = 24;
+                                break;
+                            case 41:
+                                if ((0x7bff50f8ffffd9ffL & l) == 0L)
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddStates(6, 10);
+                                break;
+                            case 42:
+                                if ((0x7bff78f8ffffd9ffL & l) == 0L)
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 44:
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 45:
+                                if ((0x7bff78f8ffffd9ffL & l) != 0L)
+                                    JjCheckNAddStates(18, 20);
+                                break;
+                            case 47:
+                                JjCheckNAddStates(18, 20);
+                                break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else if (curChar < 128)
+				{
+                    // NOTE: This didn't change in Java from 3.0.1 to 4.8.0, but it is different in .NET.
+                    // But changing it back made more tests pass, so I am working under the assumption 63
+                    // is the correct value.
+                    //ulong l = (ulong)(1L << (curChar & 077));
+                    ulong l = (ulong) (1L << (curChar & 63)); 
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 49: 
+								if ((0x97ffffff87ffffffL & l) != (ulong) 0L)
+								{
+									if (kind > 23)
+										kind = 23;
+									JjCheckNAddTwoStates(33, 34);
+								}
+								else if (curChar == 92)
+									JjCheckNAddTwoStates(35, 35);
+								break;
+							
+							case 0: 
+								if ((0x97ffffff87ffffffL & l) != (ulong) 0L)
+								{
+									if (kind > 20)
+										kind = 20;
+									JjCheckNAddStates(6, 10);
+								}
+								else if (curChar == 92)
+									JjCheckNAddStates(21, 23);
+								else if (curChar == 126)
+								{
+									if (kind > 21)
+										kind = 21;
+                                    JjCheckNAddStates(24, 26);
+								}
+								if ((0x97ffffff87ffffffL & l) != (ulong) 0L)
+								{
+									if (kind > 23)
+										kind = 23;
+									JjCheckNAddTwoStates(33, 34);
+								}
+								if (curChar == 78)
+									jjstateSet[jjnewStateCnt++] = 11;
+								else if (curChar == 124)
+									jjstateSet[jjnewStateCnt++] = 8;
+								else if (curChar == 79)
+									jjstateSet[jjnewStateCnt++] = 6;
+								else if (curChar == 65)
+									jjstateSet[jjnewStateCnt++] = 2;
+								break;
+							
+							case 1: 
+								if (curChar == 68 && kind > 8)
+									kind = 8;
+								break;
+							
+							case 2: 
+								if (curChar == 78)
+									jjstateSet[jjnewStateCnt++] = 1;
+								break;
+							
+							case 3: 
+								if (curChar == 65)
+									jjstateSet[jjnewStateCnt++] = 2;
+								break;
+							
+							case 6: 
+								if (curChar == 82 && kind > 9)
+									kind = 9;
+								break;
+							
+							case 7: 
+								if (curChar == 79)
+									jjstateSet[jjnewStateCnt++] = 6;
+								break;
+							
+							case 8: 
+								if (curChar == 124 && kind > 9)
+									kind = 9;
+								break;
+							
+							case 9: 
+								if (curChar == 124)
+									jjstateSet[jjnewStateCnt++] = 8;
+								break;
+							
+							case 10: 
+								if (curChar == 84 && kind > 10)
+									kind = 10;
+								break;
+							
+							case 11: 
+								if (curChar == 79)
+									jjstateSet[jjnewStateCnt++] = 10;
+								break;
+							
+							case 12: 
+								if (curChar == 78)
+									jjstateSet[jjnewStateCnt++] = 11;
+								break;
+							
+							case 17: 
+								if ((0xffffffffefffffffL & l) != (ulong) 0L)
+									JjCheckNAddStates(3, 5);
+								break;
+							
+							case 18: 
+								if (curChar == 92)
+									jjstateSet[jjnewStateCnt++] = 19;
+								break;
+							
+							case 19: 
+								JjCheckNAddStates(3, 5);
+								break;
+							
+							case 21: 
+								if (curChar != 126)
+									break;
+								if (kind > 21)
+									kind = 21;
+                                JjCheckNAddStates(24, 26);
+								break;
+							
+							case 25: 
+								if ((0x97ffffff87ffffffL & l) == (ulong) 0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 26: 
+								if (curChar == 92)
+									JjAddStates(27, 28);
+								break;
+							
+							case 27: 
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 28: 
+								if ((0x97ffffff87ffffffL & l) == (ulong) 0L)
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(28, 29);
+								break;
+							
+							case 29:
+                                if (curChar == 92)
+                                    JjAddStates(29, 30);
+                                break;
+                            case 30:
+                                if (kind > 21)
+                                    kind = 21;
+                                JjCheckNAddTwoStates(28, 29);
+                                break;
+                            case 32:
+                                if ((0x97ffffff87ffffffL & l) == (ulong)0L)
+                                    break;
+                                if (kind > 23)
+                                    kind = 23;
+                                JjCheckNAddTwoStates(33, 34);
+                                break;
+                            case 33:
+                                if ((0x97ffffff87ffffffL & l) == (ulong)0L)
+                                    break;
+                                if (kind > 23)
+                                    kind = 23;
+                                JjCheckNAddTwoStates(33, 34);
+                                break;
+                            case 34:
+                                if (curChar == 92)
+                                    JjCheckNAddTwoStates(35, 35);
+                                break;
+                            case 35:
+                                if (kind > 23)
+                                    kind = 23;
+                                JjCheckNAddTwoStates(33, 34);
+                                break;
+                            case 37:
+                                JjAddStates(0, 2);
+                                break;
+                            case 39:
+                                if (curChar == 92)
+                                    jjstateSet[jjnewStateCnt++] = 38;
+                                break;
+                            case 41:
+                                if ((0x97ffffff87ffffffL & l) == (ulong)0L)
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddStates(6, 10);
+                                break;
+                            case 42:
+                                if ((0x97ffffff87ffffffL & l) == (ulong)0L)
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 43:
+                                if (curChar == 92)
+                                    JjCheckNAddTwoStates(44, 44);
+                                break;
+                            case 44:
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 45:
+                                if ((0x97ffffff87ffffffL & l) != (ulong)0L)
+                                    JjCheckNAddStates(18, 20);
+                                break;
+                            case 46:
+                                if (curChar == 92)
+                                    JjCheckNAddTwoStates(47, 47);
+                                break;
+                            case 47:
+                                JjCheckNAddStates(18, 20);
+                                break;
+                            case 48:
+                                if (curChar == 92)
+                                    JjCheckNAddStates(21, 23);
+                                break;
+
+                            default: break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else
+				{
+					int hiByte = (int) (curChar >> 8);
+					int i1 = hiByte >> 6;
+					ulong l1 = (ulong) (1L << (hiByte & 63));
+					int i2 = (curChar & 0xff) >> 6;
+					ulong l2 = (ulong) (1L << (curChar & 63));
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 49: 
+							case 33: 
+								if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 23)
+									kind = 23;
+								JjCheckNAddTwoStates(33, 34);
+								break;
+							
+							case 0: 
+								if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+								{
+									if (kind > 7)
+										kind = 7;
+								}
+								if (JjCanMove_2(hiByte, i1, i2, l1, l2))
+								{
+									if (kind > 23)
+										kind = 23;
+									JjCheckNAddTwoStates(33, 34);
+								}
+								if (JjCanMove_2(hiByte, i1, i2, l1, l2))
+								{
+									if (kind > 20)
+										kind = 20;
+									JjCheckNAddStates(6, 10);
+								}
+								break;
+							
+							case 15: 
+                                if (JjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 13)
+                                    kind = 13;
+                                break;
+							case 17: 
+                            case 19:
+								if (JjCanMove_1(hiByte, i1, i2, l1, l2))
+									JjCheckNAddStates(3, 5);
+								break;
+							
+							case 25: 
+								if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 27: 
+								if (!JjCanMove_1(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(25, 26);
+								break;
+							
+							case 28: 
+								if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 21)
+									kind = 21;
+								JjCheckNAddTwoStates(28, 29);
+								break;
+                            case 30:
+                                if (!JjCanMove_1(hiByte, i1, i2, l1, l2))
+                                    break;
+                                if (kind > 21)
+                                    kind = 21;
+                                JjCheckNAddTwoStates(28, 29);
+                                break;
+							case 32: 
+								if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 23)
+									kind = 23;
+								JjCheckNAddTwoStates(33, 34);
+								break;
+							
+							case 35: 
+								if (!JjCanMove_1(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 23)
+									kind = 23;
+								JjCheckNAddTwoStates(33, 34);
+								break;
+
+                            case 37:
+                                if (JjCanMove_1(hiByte, i1, i2, l1, l2))
+                                    JjAddStates(0, 2);
+                                break;
+                            case 41:
+                                if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddStates(6, 10);
+                                break;
+                            case 42:
+                                if (!JjCanMove_2(hiByte, i1, i2, l1, l2))
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 44:
+                                if (!JjCanMove_1(hiByte, i1, i2, l1, l2))
+                                    break;
+                                if (kind > 20)
+                                    kind = 20;
+                                JjCheckNAddTwoStates(42, 43);
+                                break;
+                            case 45:
+								if (JjCanMove_2(hiByte, i1, i2, l1, l2))
+									JjCheckNAddStates(18, 20);
+								break;
+							
+							case 47: 
+								if (JjCanMove_1(hiByte, i1, i2, l1, l2))
+									JjCheckNAddStates(18, 20);
+								break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				if (kind != 0x7fffffff)
+				{
+					jjmatchedKind = kind;
+					jjmatchedPos = curPos;
+					kind = 0x7fffffff;
+				}
+				++curPos;
+				if ((i = jjnewStateCnt) == (startsAt = 49 - (jjnewStateCnt = startsAt)))
+					return curPos;
+				try
+				{
+					curChar = input_stream.ReadChar();
+				}
+				catch (System.IO.IOException)
+				{
+					return curPos;
+				}
+			}
+		}
+		private int JjMoveStringLiteralDfa0_0()
+		{
+			return JjMoveNfa_0(0, 0);
+		}
+		private int JjMoveNfa_0(int startState, int curPos)
+		{
+			int startsAt = 0;
+			jjnewStateCnt = 3;
+			int i = 1;
+			jjstateSet[0] = startState;
+			int kind = 0x7fffffff;
+			for (; ; )
+			{
+				if (++jjround == 0x7fffffff)
+					ReInitRounds();
+				if (curChar < 64)
+				{
+					ulong l = (ulong) (1L << (int) curChar);
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 0: 
+								if ((0x3ff000000000000L & l) == 0L)
+									break;
+								if (kind > 27)
+									kind = 27;
+								JjAddStates(31, 32);
+								break;
+							
+							case 1: 
+								if (curChar == 46)
+									JjCheckNAdd(2);
+								break;
+							
+							case 2: 
+								if ((0x3ff000000000000L & l) == 0L)
+									break;
+								if (kind > 27)
+									kind = 27;
+								JjCheckNAdd(2);
+								break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else if (curChar < 128)
+				{
+					ulong l = (ulong) (1L << (curChar & 63));
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else
+				{
+					int hiByte = (int) (curChar >> 8);
+					int i1 = hiByte >> 6;
+					long l1 = 1L << (hiByte & 63);
+					int i2 = (curChar & 0xff) >> 6;
+					long l2 = 1L << (curChar & 63);
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				if (kind != 0x7fffffff)
+				{
+					jjmatchedKind = kind;
+					jjmatchedPos = curPos;
+					kind = 0x7fffffff;
+				}
+				++curPos;
+				if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
+					return curPos;
+				try
+				{
+					curChar = input_stream.ReadChar();
+				}
+				catch (System.IO.IOException)
+				{
+					return curPos;
+				}
+			}
+		}
+		private int JjStopStringLiteralDfa_1(int pos, long active0)
+		{
+			switch (pos)
+			{
+				
+				case 0:
+                    if ((active0 & 0x10000000L) != 0L)
+					{
+						jjmatchedKind = 32;
+						return 6;
+					}
+					return - 1;
+				
+				default: 
+					return - 1;
+				
+			}
+		}
+		private int JjStartNfa_1(int pos, long active0)
+		{
+			return JjMoveNfa_1(JjStopStringLiteralDfa_1(pos, active0), pos + 1);
+		}
+		private int JjMoveStringLiteralDfa0_1()
+		{
+			switch (curChar)
+			{
+				
+				case (char)84:
+                    return JjMoveStringLiteralDfa1_1(0x10000000L);
+				
+				case (char)93: 
+					return JjStopAtPos(0, 29);
+
+                case (char)125:
+                    return JjStopAtPos(0, 30);
+
+				default: 
+					return JjMoveNfa_1(0, 0);
+				
+			}
+		}
+		private int JjMoveStringLiteralDfa1_1(long active0)
+		{
+			try
+			{
+				curChar = input_stream.ReadChar();
+			}
+			catch (System.IO.IOException)
+			{
+				JjStopStringLiteralDfa_1(0, active0);
+				return 1;
+			}
+			switch (curChar)
+			{
+				
+				case (char) (79):
+                    if ((active0 & 0x10000000L) != 0L)
+						return JjStartNfaWithStates_1(1, 28, 6);
+					break;
+				
+				default: 
+					break;
+				
+			}
+			return JjStartNfa_1(0, active0);
+		}
+		private int JjStartNfaWithStates_1(int pos, int kind, int state)
+		{
+			jjmatchedKind = kind;
+			jjmatchedPos = pos;
+			try
+			{
+				curChar = input_stream.ReadChar();
+			}
+			catch (System.IO.IOException)
+			{
+				return pos + 1;
+			}
+			return JjMoveNfa_1(state, pos + 1);
+		}
+		private int JjMoveNfa_1(int startState, int curPos)
+		{
+			int startsAt = 0;
+			jjnewStateCnt = 7;
+			int i = 1;
+			jjstateSet[0] = startState;
+			int kind = 0x7fffffff;
+			for (; ; )
+			{
+				if (++jjround == 0x7fffffff)
+					ReInitRounds();
+				if (curChar < 64)
+				{
+					ulong l = (ulong) (1L << (int) curChar);
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 0:
+                                if ((0xfffffffeffffffffL & l) != (ulong)0L)
+								{
+									if (kind > 32)
+										kind = 32;
+									JjCheckNAdd(6);
+								}
+								if ((0x100002600L & l) != 0L)
+								{
+									if (kind > 7)
+										kind = 7;
+								}
+								else if (curChar == 34)
+									JjCheckNAddTwoStates(2, 4);
+								break;
+							
+							case 1: 
+								if (curChar == 34)
+									JjCheckNAddTwoStates(2, 4);
+								break;
+							
+							case 2:
+                                if ((0xfffffffbffffffffL & l) != (ulong)0L)
+									JjCheckNAddStates(33, 35);
+								break;
+							
+							case 3: 
+								if (curChar == 34)
+									JjCheckNAddStates(33, 35);
+								break;
+							
+							case 5: 
+								if (curChar == 34 && kind > 31)
+									kind = 31;
+								break;
+							
+							case 6:
+                                if ((0xfffffffeffffffffL & l) == (ulong)0L)
+									break;
+								if (kind > 32)
+									kind = 32;
+								JjCheckNAdd(6);
+								break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else if (curChar < 128)
+				{
+					ulong l = (ulong) (1L << (curChar & 63));
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 0: 
+							case 6:
+                                if ((0xdfffffffdfffffffL & l) == (ulong)0L)
+									break;
+								if (kind > 32)
+									kind = 32;
+								JjCheckNAdd(6);
+								break;
+							
+							case 2: 
+								JjAddStates(33, 35);
+								break;
+							
+							case 4: 
+								if (curChar == 92)
+									jjstateSet[jjnewStateCnt++] = 3;
+								break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				else
+				{
+					int hiByte = (int) (curChar >> 8);
+					int i1 = hiByte >> 6;
+					ulong l1 = (ulong) (1L << (hiByte & 63));
+					int i2 = (curChar & 0xff) >> 6;
+					ulong l2 = (ulong) (1L << (curChar & 63));
+					do 
+					{
+						switch (jjstateSet[--i])
+						{
+							
+							case 0: 
+								if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+								{
+									if (kind > 7)
+										kind = 7;
+								}
+								if (JjCanMove_1(hiByte, i1, i2, l1, l2))
+								{
+									if (kind > 32)
+										kind = 32;
+									JjCheckNAdd(6);
+								}
+								break;
+							
+							case 2: 
+								if (JjCanMove_1(hiByte, i1, i2, l1, l2))
+									JjAddStates(33, 35);
+								break;
+							
+							case 6: 
+								if (!JjCanMove_1(hiByte, i1, i2, l1, l2))
+									break;
+								if (kind > 32)
+									kind = 32;
+								JjCheckNAdd(6);
+								break;
+							
+							default:  break;
+							
+						}
+					}
+					while (i != startsAt);
+				}
+				if (kind != 0x7fffffff)
+				{
+					jjmatchedKind = kind;
+					jjmatchedPos = curPos;
+					kind = 0x7fffffff;
+				}
+				++curPos;
+				if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt)))
+					return curPos;
+				try
+				{
+					curChar = input_stream.ReadChar();
+				}
+				catch (System.IO.IOException)
+				{
+					return curPos;
+				}
+			}
+		}
+        internal static readonly int[] jjnextStates = new int[]{
+           37, 39, 40, 17, 18, 20, 42, 45, 31, 46, 43, 22, 23, 25, 26, 24, 
+           25, 26, 45, 31, 46, 44, 47, 35, 22, 28, 29, 27, 27, 30, 30, 0, 
+           1, 2, 4, 5
+        };
+		private static bool JjCanMove_0(int hiByte, int i1, int i2, ulong l1, ulong l2)
+		{
+			switch (hiByte)
+			{
+				
+				case 48: 
+					return ((jjbitVec0[i2] & l2) != (ulong) 0L);
+				
+				default: 
+					return false;
+				
+			}
+		}
+		private static bool JjCanMove_1(int hiByte, int i1, int i2, ulong l1, ulong l2)
+		{
+			switch (hiByte)
+			{
+				
+				case 0: 
+					return ((jjbitVec3[i2] & l2) != (ulong) 0L);
+				
+				default: 
+					if ((jjbitVec1[i1] & l1) != (ulong) 0L)
+						return true;
+					return false;
+				
+			}
+		}
+		private static bool JjCanMove_2(int hiByte, int i1, int i2, ulong l1, ulong l2)
+		{
+			switch (hiByte)
+			{
+				
+				case 0: 
+					return ((jjbitVec3[i2] & l2) != (ulong) 0L);
+				
+				case 48: 
+					return ((jjbitVec1[i2] & l2) != (ulong) 0L);
+				
+				default: 
+					if ((jjbitVec4[i1] & l1) != (ulong) 0L)
+						return true;
+					return false;
+				
+			}
+		}
+
+        ///// <summary>Token literal values. </summary>
+        //public static readonly string[] jjstrLiteralImages = new string[] { 
+        //    "", null, null, null, null, null, null, null, null, null, null, "\x002B", "\x002D", 
+        //    "\x0028", "\x0029", "\x003A", "\x002A", "\x005E", null, null, null, null, null, "\x005B", "\x007B", 
+        //    null, "\x0054\x004F", "\x005D", null, null, "\x0054\x004F", "\x007D", null, null };
+		
+
+		/// <summary>Token literal values. </summary>
+		public static readonly string[] jjstrLiteralImages = new string[]{
+            "", null, null, null, null, null, null, null, null, null, null, "\x002B", "\x002D", 
+            null, "\x0028", "\x0029", "\x003A", "\x002A", "\x005E", null, null, null, null, null, null, 
+            "\x005B", "\x007B", null, "\x0054\x004F", "\x005D", "\x007D", null, null };
+		
+		/// <summary>Lexer state names. </summary>
+		public static readonly string[] lexStateNames = new string[] {
+            "Boost", 
+            "Range", 
+            "DEFAULT"
+        };
+		
+		/// <summary>Lex State array. </summary>
+		public static readonly int[] jjnewLexState = new int[] {
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 
+            1, 1, 2, -1, 2, 2, -1, -1
+        };
+        internal static readonly ulong[] jjtoToken = new ulong[] { 0x1ffffff01L };
+        internal static readonly long[] jjtoSkip = new long[] { 0x80L };
+		protected internal ICharStream input_stream;
+		private uint[] jjrounds = new uint[49];
+		private int[] jjstateSet = new int[98];
+		protected internal char curChar;
+		/// <summary>Constructor. </summary>
+		public QueryParserTokenManager(ICharStream stream)
+		{
+			InitBlock();
+			input_stream = stream;
+		}
+		
+		/// <summary>Constructor. </summary>
+		public QueryParserTokenManager(ICharStream stream, int lexState):this(stream)
+		{
+			SwitchTo(lexState);
+		}
+		
+		/// <summary>Reinitialise parser. </summary>
+		public virtual void  ReInit(ICharStream stream)
+		{
+			jjmatchedPos = jjnewStateCnt = 0;
+			curLexState = defaultLexState;
+			input_stream = stream;
+			ReInitRounds();
+		}
+		private void  ReInitRounds()
+		{
+			int i;
+			jjround = 0x80000001;
+			for (i = 49; i-- > 0; )
+				jjrounds[i] = 0x80000000;
+		}
+		
+		/// <summary>Reinitialise parser. </summary>
+		public virtual void  ReInit(ICharStream stream, int lexState)
+		{
+			ReInit(stream);
+			SwitchTo(lexState);
+		}
+		
+		/// <summary>Switch to specified lex state. </summary>
+		public virtual void  SwitchTo(int lexState)
+		{
+			if (lexState >= 3 || lexState < 0)
+				throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+			else
+				curLexState = lexState;
+		}
+		
+		protected internal virtual Token JjFillToken()
+		{
+			Token t;
+			System.String curTokenImage;
+			int beginLine;
+			int endLine;
+			int beginColumn;
+			int endColumn;
+			System.String im = jjstrLiteralImages[jjmatchedKind];
+			curTokenImage = (im == null)?input_stream.Image:im;
+			beginLine = input_stream.BeginLine;
+			beginColumn = input_stream.BeginColumn;
+			endLine = input_stream.EndLine;
+			endColumn = input_stream.EndColumn;
+			t = Token.NewToken(jjmatchedKind, curTokenImage);
+			
+			t.beginLine = beginLine;
+			t.endLine = endLine;
+			t.beginColumn = beginColumn;
+			t.endColumn = endColumn;
+			
+			return t;
+		}
+		
+		internal int curLexState = 2;
+		internal int defaultLexState = 2;
+		internal int jjnewStateCnt;
+		internal uint jjround;
+		internal int jjmatchedPos;
+		internal int jjmatchedKind;
+		
+		/// <summary>Get the next Token. </summary>
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+        public virtual Token GetNextToken()
+		{
+			Token matchedToken;
+			int curPos = 0;
+			
+			for (; ; )
+			{
+				try
+				{
+					curChar = input_stream.BeginToken();
+				}
+				catch (IOException)
+				{
+					jjmatchedKind = 0;
+					matchedToken = JjFillToken();
+					return matchedToken;
+				}
+				
+				switch (curLexState)
+				{
+					
+					case 0: 
+						jjmatchedKind = 0x7fffffff;
+						jjmatchedPos = 0;
+						curPos = JjMoveStringLiteralDfa0_0();
+						break;
+					
+					case 1: 
+						jjmatchedKind = 0x7fffffff;
+						jjmatchedPos = 0;
+						curPos = JjMoveStringLiteralDfa0_1();
+						break;
+					
+					case 2: 
+						jjmatchedKind = 0x7fffffff;
+						jjmatchedPos = 0;
+						curPos = JjMoveStringLiteralDfa0_2();
+						break;
+					}
+				if (jjmatchedKind != 0x7fffffff)
+				{
+					if (jjmatchedPos + 1 < curPos)
+						input_stream.Backup(curPos - jjmatchedPos - 1);
+					if ((jjtoToken[jjmatchedKind >> 6] & ((ulong) 1L << (jjmatchedKind & 63))) != (ulong) 0L)
+					{
+						matchedToken = JjFillToken();
+						if (jjnewLexState[jjmatchedKind] != - 1)
+							curLexState = jjnewLexState[jjmatchedKind];
+						return matchedToken;
+					}
+					else
+					{
+						if (jjnewLexState[jjmatchedKind] != - 1)
+							curLexState = jjnewLexState[jjmatchedKind];
+						goto EOFLoop;
+					}
+				}
+				int error_line = input_stream.EndLine;
+				int error_column = input_stream.EndColumn;
+				System.String error_after = null;
+				bool EOFSeen = false;
+				try
+				{
+					input_stream.ReadChar(); input_stream.Backup(1);
+				}
+				catch (IOException)
+				{
+					EOFSeen = true;
+					error_after = curPos <= 1?"":input_stream.Image;
+					if (curChar == '\n' || curChar == '\r')
+					{
+						error_line++;
+						error_column = 0;
+					}
+					else
+						error_column++;
+				}
+				if (!EOFSeen)
+				{
+					input_stream.Backup(1);
+					error_after = curPos <= 1?"":input_stream.Image;
+				}
+				throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+
+EOFLoop: ;
+			}
+		}
+		
+		private void  JjCheckNAdd(int state)
+		{
+			if (jjrounds[state] != jjround)
+			{
+				jjstateSet[jjnewStateCnt++] = state;
+				jjrounds[state] = jjround;
+			}
+		}
+		private void  JjAddStates(int start, int end)
+		{
+			do 
+			{
+				jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+			}
+			while (start++ != end);
+		}
+		private void  JjCheckNAddTwoStates(int state1, int state2)
+		{
+			JjCheckNAdd(state1);
+			JjCheckNAdd(state2);
+		}
+		
+		private void  JjCheckNAddStates(int start, int end)
+		{
+			do 
+			{
+				JjCheckNAdd(jjnextStates[start]);
+			}
+			while (start++ != end);
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Classic/Token.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Classic/Token.cs b/src/Lucene.Net.QueryParser/Classic/Token.cs
new file mode 100644
index 0000000..389e7b3
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Classic/Token.cs
@@ -0,0 +1,142 @@
+using System;
+
+namespace Lucene.Net.QueryParser.Classic
+{
+    /*
+     * 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> 
+    /// Describes the input token stream.
+    /// </summary>
+    [Serializable]
+	public class Token
+	{
+		
+		/// <summary> 
+        /// An integer that describes the kind of this token.  This numbering
+		/// system is determined by JavaCCParser, and a table of these numbers is
+		/// stored in the file ...Constants.java.
+		/// </summary>
+		public int kind;
+		
+		/// <summary>The line number of the first character of this Token. </summary>
+		public int beginLine;
+		/// <summary>The column number of the first character of this Token. </summary>
+		public int beginColumn;
+		/// <summary>The line number of the last character of this Token. </summary>
+		public int endLine;
+		/// <summary>The column number of the last character of this Token. </summary>
+		public int endColumn;
+		
+		/// <summary>The string image of the token.</summary>
+		public string image;
+		
+		/// <summary> 
+        /// A reference to the next regular (non-special) token from the input
+		/// stream.  If this is the last token from the input stream, or if the
+		/// token manager has not read tokens beyond this one, this field is
+		/// set to null.  This is true only if this token is also a regular
+		/// token.  Otherwise, see below for a description of the contents of
+		/// this field.
+		/// </summary>
+		public Token next;
+		
+		/// <summary> 
+        /// This field is used to access special tokens that occur prior to this
+		/// token, but after the immediately preceding regular (non-special) token.
+		/// If there are no such special tokens, this field is set to null.
+		/// When there are more than one such special token, this field refers
+		/// to the last of these special tokens, which in turn refers to the next
+		/// previous special token through its specialToken field, and so on
+		/// until the first special token (whose specialToken field is null).
+		/// The next fields of special tokens refer to other special tokens that
+		/// immediately follow it (without an intervening regular token).  If there
+		/// is no such token, this field is null.
+		/// </summary>
+		public Token specialToken;
+
+	    /// <summary> 
+        /// An optional attribute value of the Token.
+	    /// Tokens which are not used as syntactic sugar will often contain
+	    /// meaningful values that will be used later on by the compiler or
+	    /// interpreter. This attribute value is often different from the image.
+	    /// Any subclass of Token that actually wants to return a non-null value can
+	    /// override this method as appropriate.
+	    /// </summary>
+	    public virtual object Value
+	    {
+	        get { return null; }
+	    }
+
+	    /// <summary> 
+        /// No-argument constructor
+        /// </summary>
+		public Token()
+		{
+		}
+		
+		/// <summary> 
+        /// Constructs a new token for the specified Image.
+        /// </summary>
+		public Token(int kind)
+            : this(kind, null)
+		{
+		}
+		
+		/// <summary> 
+        /// Constructs a new token for the specified Image and Kind.
+        /// </summary>
+		public Token(int kind, string image)
+		{
+			this.kind = kind;
+			this.image = image;
+		}
+		
+		/// <summary> 
+        /// Returns the image.
+        /// </summary>
+		public override string ToString()
+		{
+			return image;
+		}
+		
+		/// <summary> 
+        /// Returns a new Token object, by default. However, if you want, you
+		/// can create and return subclass objects based on the value of ofKind.
+		/// Simply add the cases to the switch for all those special cases.
+		/// For example, if you have a subclass of Token called IDToken that
+		/// you want to create if ofKind is ID, simply add something like :
+		/// 
+		/// case MyParserConstants.ID : return new IDToken(ofKind, image);
+		/// 
+		/// to the following switch statement. Then you can cast matchedToken
+		/// variable to the appropriate type and use sit in your lexical actions.
+		/// </summary>
+		public static Token NewToken(int ofKind, string image)
+		{
+			switch (ofKind)
+			{
+				default:  return new Token(ofKind, image);
+			}
+		}
+		
+		public static Token NewToken(int ofKind)
+		{
+			return NewToken(ofKind, null);
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Classic/TokenMgrError.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Classic/TokenMgrError.cs b/src/Lucene.Net.QueryParser/Classic/TokenMgrError.cs
new file mode 100644
index 0000000..2f69e13
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Classic/TokenMgrError.cs
@@ -0,0 +1,170 @@
+using System;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Classic
+{
+    /*
+     * 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>Token Manager Error. </summary>
+	[Serializable]
+	public class TokenMgrError : Exception
+	{
+        /*
+		* Ordinals for various reasons why an Error of this type can be thrown.
+		*/
+
+        /// <summary> Lexical error occurred.</summary>
+        internal const int LEXICAL_ERROR = 0;
+
+        /// <summary> An attempt was made to create a second instance of a static token manager.</summary>
+        internal const int STATIC_LEXER_ERROR = 1;
+
+        /// <summary> Tried to change to an invalid lexical state.</summary>
+        internal const int INVALID_LEXICAL_STATE = 2;
+
+        /// <summary> Detected (and bailed out of) an infinite loop in the token manager.</summary>
+        internal const int LOOP_DETECTED = 3;
+
+        /// <summary> Indicates the reason why the exception is thrown. It will have
+        /// one of the above 4 values.
+        /// </summary>
+        internal int errorCode;
+
+        /// <summary> 
+        /// Replaces unprintable characters by their escaped (or unicode escaped)
+        /// equivalents in the given string
+        /// </summary>
+        protected internal static string AddEscapes(string str)
+        {
+            StringBuilder retval = new StringBuilder();
+            char ch;
+            for (int i = 0; i < str.Length; i++)
+            {
+                switch (str[i])
+                {
+
+                    case (char)(0):
+                        continue;
+
+                    case '\b':
+                        retval.Append("\\b");
+                        continue;
+
+                    case '\t':
+                        retval.Append("\\t");
+                        continue;
+
+                    case '\n':
+                        retval.Append("\\n");
+                        continue;
+
+                    case '\f':
+                        retval.Append("\\f");
+                        continue;
+
+                    case '\r':
+                        retval.Append("\\r");
+                        continue;
+
+                    case '\"':
+                        retval.Append("\\\"");
+                        continue;
+
+                    case '\'':
+                        retval.Append("\\\'");
+                        continue;
+
+                    case '\\':
+                        retval.Append("\\\\");
+                        continue;
+
+                    default:
+                        if ((ch = str[i]) < 0x20 || ch > 0x7e)
+                        {
+                            string s = "0000" + Convert.ToString(ch, 16);
+                            retval.Append("\\u" + s.Substring(s.Length - 4, (s.Length) - (s.Length - 4)));
+                        }
+                        else
+                        {
+                            retval.Append(ch);
+                        }
+                        continue;
+
+                }
+            }
+            return retval.ToString();
+        }
+
+        /// <summary>
+        /// Returns a detailed message for the Error when it is thrown by the
+        /// token manager to indicate a lexical error.
+        /// </summary>
+        /// <remarks>You can customize the lexical error message by modifying this method.</remarks>
+        /// <param name="EOFSeen">indicates if EOF caused the lexical error</param>
+        /// <param name="lexState">lexical state in which this error occurred</param>
+        /// <param name="errorLine">line number when the error occurred</param>
+        /// <param name="errorColumn">column number when the error occurred</param>
+        /// <param name="errorAfter">prefix that was seen before this error occurred</param>
+        /// <param name="curChar">the offending character</param>
+        /// <returns>Detailed error message</returns>
+        protected internal static string LexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar)
+        {
+            return ("Lexical error at line " +
+                errorLine + ", column " +
+                errorColumn + ".  Encountered: " +
+                (EOFSeen ? "<EOF> " : ("\"" + AddEscapes(Convert.ToString(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+                "after : \"" + AddEscapes(errorAfter) + "\"");
+        }
+
+		/// <summary> 
+        /// You can also modify the body of this method to customize your error messages.
+		/// For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+		/// of end-users concern, so you can return something like :
+		/// 
+		/// "Internal Error : Please file a bug report .... "
+		/// 
+		/// from this method for such cases in the release version of your parser.
+		/// </summary>
+		public override string Message
+		{
+			get { return base.Message; }
+		}
+		
+		/*
+		* Constructors of various flavors follow.
+		*/
+		
+		/// <summary>No arg constructor. </summary>
+		public TokenMgrError()
+		{
+		}
+		
+		/// <summary>Constructor with message and reason. </summary>
+		public TokenMgrError(string message, int reason)
+            : base(message)
+		{
+			errorCode = reason;
+		}
+		
+		/// <summary>Full Constructor. </summary>
+		public TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar, int reason)
+            : this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason)
+		{
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/ComplexPhrase/ComplexPhraseQueryParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/ComplexPhrase/ComplexPhraseQueryParser.cs b/src/Lucene.Net.QueryParser/ComplexPhrase/ComplexPhraseQueryParser.cs
new file mode 100644
index 0000000..0ac7c5b
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/ComplexPhrase/ComplexPhraseQueryParser.cs
@@ -0,0 +1,468 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.Index;
+using Lucene.Net.QueryParser.Classic;
+using Lucene.Net.Search;
+using Lucene.Net.Search.Spans;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.QueryParser.ComplexPhrase
+{
+    /*
+     * 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>
+    /// QueryParser which permits complex phrase query syntax eg "(john jon
+    /// jonathan~) peters*".
+    /// <p>
+    /// Performs potentially multiple passes over Query text to parse any nested
+    /// logic in PhraseQueries. - First pass takes any PhraseQuery content between
+    /// quotes and stores for subsequent pass. All other query content is parsed as
+    /// normal - Second pass parses any stored PhraseQuery content, checking all
+    /// embedded clauses are referring to the same field and therefore can be
+    /// rewritten as Span queries. All PhraseQuery clauses are expressed as
+    /// ComplexPhraseQuery objects
+    /// </p>
+    /// <p>
+    /// This could arguably be done in one pass using a new QueryParser but here I am
+    /// working within the constraints of the existing parser as a base class. This
+    /// currently simply feeds all phrase content through an analyzer to select
+    /// phrase terms - any "special" syntax such as * ~ * etc are not given special
+    /// status
+    /// </p>
+    /// </summary>
+    public class ComplexPhraseQueryParser : Classic.QueryParser
+    {
+        private List<ComplexPhraseQuery> complexPhrases = null;
+
+        private bool isPass2ResolvingPhrases;
+
+        /// <summary>
+        /// When <code>inOrder</code> is true, the search terms must
+        /// exists in the documents as the same order as in query.
+        /// Choose between ordered (true) or un-ordered (false) proximity search.
+        /// </summary>
+        public bool InOrder { get; set; }
+
+        private ComplexPhraseQuery currentPhraseQuery = null;
+
+        public ComplexPhraseQueryParser(LuceneVersion matchVersion, string f, Analyzer a)
+            : base(matchVersion, f, a)
+        {
+            // set property defaults
+            this.InOrder = true;
+        }
+
+        protected internal override Query GetFieldQuery(string field, string queryText, int slop)
+        {
+            ComplexPhraseQuery cpq = new ComplexPhraseQuery(field, queryText, slop, InOrder);
+            complexPhrases.Add(cpq); // add to list of phrases to be parsed once
+            // we
+            // are through with this pass
+            return cpq;
+        }
+
+        public override Query Parse(string query)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                MultiTermQuery.RewriteMethod oldMethod = MultiTermRewriteMethod;
+                try
+                {
+                    // Temporarily force BooleanQuery rewrite so that Parser will
+                    // generate visible
+                    // collection of terms which we can convert into SpanQueries.
+                    // ConstantScoreRewrite mode produces an
+                    // opaque ConstantScoreQuery object which cannot be interrogated for
+                    // terms in the same way a BooleanQuery can.
+                    // QueryParser is not guaranteed threadsafe anyway so this temporary
+                    // state change should not
+                    // present an issue
+                    MultiTermRewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
+                    return base.Parse(query);
+                }
+                finally
+                {
+                    MultiTermRewriteMethod = oldMethod;
+                }
+            }
+
+            // First pass - parse the top-level query recording any PhraseQuerys
+            // which will need to be resolved
+            complexPhrases = new List<ComplexPhraseQuery>();
+            Query q = base.Parse(query);
+
+            // Perform second pass, using this QueryParser to parse any nested
+            // PhraseQueries with different
+            // set of syntax restrictions (i.e. all fields must be same)
+            isPass2ResolvingPhrases = true;
+            try
+            {
+                foreach (var currentPhraseQuery in complexPhrases)
+                {
+                    this.currentPhraseQuery = currentPhraseQuery;
+                    // in each phrase, now parse the contents between quotes as a
+                    // separate parse operation
+                    currentPhraseQuery.ParsePhraseElements(this);
+                }
+            }
+            finally
+            {
+                isPass2ResolvingPhrases = false;
+            }
+            return q;
+        }
+
+        // There is No "getTermQuery throws ParseException" method to override so
+        // unfortunately need
+        // to throw a runtime exception here if a term for another field is embedded
+        // in phrase query
+        protected override Query NewTermQuery(Term term)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                try
+                {
+                    CheckPhraseClauseIsForSameField(term.Field);
+                }
+                catch (ParseException pe)
+                {
+                    throw new Exception("Error parsing complex phrase", pe);
+                }
+            }
+            return base.NewTermQuery(term);
+        }
+
+        // Helper method used to report on any clauses that appear in query syntax
+        private void CheckPhraseClauseIsForSameField(string field)
+        {
+            if (!field.Equals(currentPhraseQuery.Field))
+            {
+                throw new ParseException("Cannot have clause for field \"" + field
+                    + "\" nested in phrase " + " for field \"" + currentPhraseQuery.Field
+                    + "\"");
+            }
+        }
+
+        protected internal override Query GetWildcardQuery(string field, string termStr)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                CheckPhraseClauseIsForSameField(field);
+            }
+            return base.GetWildcardQuery(field, termStr);
+        }
+
+        protected internal override Query GetRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                CheckPhraseClauseIsForSameField(field);
+            }
+            return base.GetRangeQuery(field, part1, part2, startInclusive, endInclusive);
+        }
+
+        protected internal override Query NewRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                // Must use old-style RangeQuery in order to produce a BooleanQuery
+                // that can be turned into SpanOr clause
+                TermRangeQuery rangeQuery = TermRangeQuery.NewStringRange(field, part1, part2, startInclusive, endInclusive);
+                rangeQuery.SetRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+                return rangeQuery;
+            }
+            return base.NewRangeQuery(field, part1, part2, startInclusive, endInclusive);
+        }
+
+        protected internal override Query GetFuzzyQuery(string field, string termStr, float minSimilarity)
+        {
+            if (isPass2ResolvingPhrases)
+            {
+                CheckPhraseClauseIsForSameField(field);
+            }
+            return base.GetFuzzyQuery(field, termStr, minSimilarity);
+        }
+
+        /// <summary>
+        /// Used to handle the query content in between quotes and produced Span-based
+        /// interpretations of the clauses.
+        /// </summary>
+        public class ComplexPhraseQuery : Query
+        {
+            private readonly string field;
+            private readonly string phrasedQueryStringContents;
+            private readonly int slopFactor;
+            private readonly bool inOrder;
+            private Query contents;
+
+            public ComplexPhraseQuery(string field, string phrasedQueryStringContents,
+                int slopFactor, bool inOrder)
+            {
+                this.field = field;
+                this.phrasedQueryStringContents = phrasedQueryStringContents;
+                this.slopFactor = slopFactor;
+                this.inOrder = inOrder;
+            }
+
+            public string Field
+            {
+                get { return field; }
+            }
+
+            // Called by ComplexPhraseQueryParser for each phrase after the main
+            // parse
+            // thread is through
+            protected internal void ParsePhraseElements(ComplexPhraseQueryParser qp)
+            {
+                // TODO ensure that field-sensitivity is preserved ie the query
+                // string below is parsed as
+                // field+":("+phrasedQueryStringContents+")"
+                // but this will need code in rewrite to unwrap the first layer of
+                // boolean query
+
+                string oldDefaultParserField = qp.Field;
+                try
+                {
+                    //temporarily set the QueryParser to be parsing the default field for this phrase e.g author:"fred* smith"
+                    qp.field = this.field;
+                    contents = qp.Parse(phrasedQueryStringContents);
+                }
+                finally
+                {
+                    qp.field = oldDefaultParserField;
+                }
+            }
+
+            public override Query Rewrite(IndexReader reader)
+            {
+                // ArrayList spanClauses = new ArrayList();
+                if (contents is TermQuery)
+                {
+                    return contents;
+                }
+                // Build a sequence of Span clauses arranged in a SpanNear - child
+                // clauses can be complex
+                // Booleans e.g. nots and ors etc
+                int numNegatives = 0;
+                if (!(contents is BooleanQuery))
+                {
+                    throw new ArgumentException("Unknown query type \""
+                        + contents.GetType().Name
+                        + "\" found in phrase query string \"" + phrasedQueryStringContents
+                        + "\"");
+                }
+                BooleanQuery bq = (BooleanQuery)contents;
+                BooleanClause[] bclauses = bq.Clauses;
+                SpanQuery[] allSpanClauses = new SpanQuery[bclauses.Length];
+                // For all clauses e.g. one* two~
+                for (int i = 0; i < bclauses.Length; i++)
+                {
+                    // HashSet bclauseterms=new HashSet();
+                    Query qc = bclauses[i].Query;
+                    // Rewrite this clause e.g one* becomes (one OR onerous)
+                    qc = qc.Rewrite(reader);
+                    if (bclauses[i].Occur_.Equals(BooleanClause.Occur.MUST_NOT))
+                    {
+                        numNegatives++;
+                    }
+
+                    if (qc is BooleanQuery)
+                    {
+                        List<SpanQuery> sc = new List<SpanQuery>();
+                        AddComplexPhraseClause(sc, (BooleanQuery)qc);
+                        if (sc.Count > 0)
+                        {
+                            allSpanClauses[i] = sc.ElementAt(0);
+                        }
+                        else
+                        {
+                            // Insert fake term e.g. phrase query was for "Fred Smithe*" and
+                            // there were no "Smithe*" terms - need to
+                            // prevent match on just "Fred".
+                            allSpanClauses[i] = new SpanTermQuery(new Term(field,
+                                "Dummy clause because no terms found - must match nothing"));
+                        }
+                    }
+                    else
+                    {
+                        if (qc is TermQuery)
+                        {
+                            TermQuery tq = (TermQuery)qc;
+                            allSpanClauses[i] = new SpanTermQuery(tq.Term);
+                        }
+                        else
+                        {
+                            throw new ArgumentException("Unknown query type \""
+                                + qc.GetType().Name
+                                + "\" found in phrase query string \""
+                                + phrasedQueryStringContents + "\"");
+                        }
+
+                    }
+                }
+                if (numNegatives == 0)
+                {
+                    // The simple case - no negative elements in phrase
+                    return new SpanNearQuery(allSpanClauses, slopFactor, inOrder);
+                }
+                // Complex case - we have mixed positives and negatives in the
+                // sequence.
+                // Need to return a SpanNotQuery
+                List<SpanQuery> positiveClauses = new List<SpanQuery>();
+                for (int j = 0; j < allSpanClauses.Length; j++)
+                {
+                    if (!bclauses[j].Occur_.Equals(BooleanClause.Occur.MUST_NOT))
+                    {
+                        positiveClauses.Add(allSpanClauses[j]);
+                    }
+                }
+
+                SpanQuery[] includeClauses = positiveClauses
+                    .ToArray();
+
+                SpanQuery include = null;
+                if (includeClauses.Length == 1)
+                {
+                    include = includeClauses[0]; // only one positive clause
+                }
+                else
+                {
+                    // need to increase slop factor based on gaps introduced by
+                    // negatives
+                    include = new SpanNearQuery(includeClauses, slopFactor + numNegatives,
+                        inOrder);
+                }
+                // Use sequence of positive and negative values as the exclude.
+                SpanNearQuery exclude = new SpanNearQuery(allSpanClauses, slopFactor,
+                    inOrder);
+                SpanNotQuery snot = new SpanNotQuery(include, exclude);
+                return snot;
+            }
+
+            private void AddComplexPhraseClause(List<SpanQuery> spanClauses, BooleanQuery qc)
+            {
+                List<SpanQuery> ors = new List<SpanQuery>();
+                List<SpanQuery> nots = new List<SpanQuery>();
+                BooleanClause[] bclauses = qc.Clauses;
+
+                // For all clauses e.g. one* two~
+                for (int i = 0; i < bclauses.Length; i++)
+                {
+                    Query childQuery = bclauses[i].Query;
+
+                    // select the list to which we will add these options
+                    List<SpanQuery> chosenList = ors;
+                    if (bclauses[i].Occur_ == BooleanClause.Occur.MUST_NOT)
+                    {
+                        chosenList = nots;
+                    }
+
+                    if (childQuery is TermQuery)
+                    {
+                        TermQuery tq = (TermQuery)childQuery;
+                        SpanTermQuery stq = new SpanTermQuery(tq.Term);
+                        stq.Boost = tq.Boost;
+                        chosenList.Add(stq);
+                    }
+                    else if (childQuery is BooleanQuery)
+                    {
+                        BooleanQuery cbq = (BooleanQuery)childQuery;
+                        AddComplexPhraseClause(chosenList, cbq);
+                    }
+                    else
+                    {
+                        // LUCENETODO alternatively could call extract terms here?
+                        throw new ArgumentException("Unknown query type:"
+                            + childQuery.GetType().Name);
+                    }
+                }
+                if (ors.Count == 0)
+                {
+                    return;
+                }
+                SpanOrQuery soq = new SpanOrQuery(ors
+                    .ToArray());
+                if (nots.Count == 0)
+                {
+                    spanClauses.Add(soq);
+                }
+                else
+                {
+                    SpanOrQuery snqs = new SpanOrQuery(nots
+                        .ToArray());
+                    SpanNotQuery snq = new SpanNotQuery(soq, snqs);
+                    spanClauses.Add(snq);
+                }
+            }
+
+            public override string ToString(string field)
+            {
+                return "\"" + phrasedQueryStringContents + "\"";
+            }
+
+            public override int GetHashCode()
+            {
+                int prime = 31;
+                int result = base.GetHashCode();
+                result = prime * result + ((field == null) ? 0 : field.GetHashCode());
+                result = prime
+                    * result
+                    + ((phrasedQueryStringContents == null) ? 0
+                        : phrasedQueryStringContents.GetHashCode());
+                result = prime * result + slopFactor;
+                result = prime * result + (inOrder ? 1 : 0);
+                return result;
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (this == obj)
+                    return true;
+                if (obj == null)
+                    return false;
+                if (GetType() != obj.GetType())
+                    return false;
+                if (!base.Equals(obj))
+                {
+                    return false;
+                }
+                ComplexPhraseQuery other = (ComplexPhraseQuery)obj;
+                if (field == null)
+                {
+                    if (other.field != null)
+                        return false;
+                }
+                else if (!field.Equals(other.field))
+                    return false;
+                if (phrasedQueryStringContents == null)
+                {
+                    if (other.phrasedQueryStringContents != null)
+                        return false;
+                }
+                else if (!phrasedQueryStringContents
+                  .Equals(other.phrasedQueryStringContents))
+                    return false;
+                if (slopFactor != other.slopFactor)
+                    return false;
+                return inOrder == other.inOrder;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Ext/ExtendableQueryParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Ext/ExtendableQueryParser.cs b/src/Lucene.Net.QueryParser/Ext/ExtendableQueryParser.cs
new file mode 100644
index 0000000..6418f87
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Ext/ExtendableQueryParser.cs
@@ -0,0 +1,131 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+using System;
+
+namespace Lucene.Net.QueryParser.Ext
+{
+    /*
+     * 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 <see cref="ExtendableQueryParser"/> enables arbitrary query parser extension
+    /// based on a customizable field naming scheme. The lucene query syntax allows
+    /// implicit and explicit field definitions as query prefix followed by a colon
+    /// (':') character. The <see cref="ExtendableQueryParser"/> allows to encode extension
+    /// keys into the field symbol associated with a registered instance of
+    /// <see cref="ParserExtension"/>. A customizable separation character separates the
+    /// extension key from the actual field symbol. The <see cref="ExtendableQueryParser"/>
+    /// splits (<see cref="Extensions.SplitExtensionField(String, String)"/>) the
+    /// extension key from the field symbol and tries to resolve the associated
+    /// <see cref="ParserExtension"/>. If the parser can't resolve the key or the field
+    /// token does not contain a separation character, <see cref="ExtendableQueryParser"/>
+    /// yields the same behavior as its super class <see cref="QueryParser"/>. Otherwise,
+    /// if the key is associated with a <see cref="ParserExtension"/> instance, the parser
+    /// builds an instance of <see cref="ExtensionQuery"/> to be processed by
+    /// <see cref="ParserExtension.Parse(ExtensionQuery)"/>.If a extension field does not
+    /// contain a field part the default field for the query will be used.
+    /// <p>
+    /// To guarantee that an extension field is processed with its associated
+    /// extension, the extension query part must escape any special characters like
+    /// '*' or '['. If the extension query contains any whitespace characters, the
+    /// extension query part must be enclosed in quotes.
+    /// Example ('_' used as separation character):
+    /// <pre>
+    ///   title_customExt:"Apache Lucene\?" OR content_customExt:prefix\*
+    /// </pre>
+    /// 
+    /// Search on the default field:
+    /// <pre>
+    ///   _customExt:"Apache Lucene\?" OR _customExt:prefix\*
+    /// </pre>
+    /// </p>
+    /// <p>
+    /// The <see cref="ExtendableQueryParser"/> itself does not implement the logic how
+    /// field and extension key are separated or ordered. All logic regarding the
+    /// extension key and field symbol parsing is located in <see cref="Extensions"/>.
+    /// Customized extension schemes should be implemented by sub-classing
+    /// <see cref="Extensions"/>.
+    /// </p>
+    /// <p>
+    /// For details about the default encoding scheme see <see cref="Extensions"/>.
+    /// </p>
+    /// 
+    /// <see cref="Extensions"/>
+    /// <see cref="ParserExtension"/>
+    /// <see cref="ExtensionQuery"/>
+    /// </summary>
+    public class ExtendableQueryParser : Classic.QueryParser
+    {
+        private readonly string defaultField;
+        private readonly Extensions extensions;
+
+  
+        /// <summary>
+        ///  Default empty extensions instance
+        /// </summary>
+        private static readonly Extensions DEFAULT_EXTENSION = new Extensions();
+
+        /// <summary>
+        /// Creates a new <see cref="ExtendableQueryParser"/> instance
+        /// </summary>
+        /// <param name="matchVersion">the lucene version to use.</param>
+        /// <param name="f">the default query field</param>
+        /// <param name="a">the analyzer used to find terms in a query string</param>
+        public ExtendableQueryParser(LuceneVersion matchVersion, string f, Analyzer a)
+            : base(matchVersion, f, a)
+        {
+        }
+
+        /// <summary>
+        /// Creates a new <see cref="ExtendableQueryParser"/> instance
+        /// </summary>
+        /// <param name="matchVersion">the lucene version to use.</param>
+        /// <param name="f">the default query field</param>
+        /// <param name="a">the analyzer used to find terms in a query string</param>
+        /// <param name="ext">the query parser extensions</param>
+        public ExtendableQueryParser(LuceneVersion matchVersion, string f, Analyzer a, Extensions ext)
+            : base(matchVersion, f, a)
+        {
+            this.defaultField = f;
+            this.extensions = ext;
+        }
+
+        /// <summary>
+        /// Returns the extension field delimiter character.
+        /// </summary>
+        /// <returns>the extension field delimiter character.</returns>
+        public char ExtensionFieldDelimiter
+        {
+            get { return extensions.ExtensionFieldDelimiter; }
+        }
+
+        protected internal override Query GetFieldQuery(string field, string queryText, bool quoted)
+        {
+            Tuple<string, string> splitExtensionField = this.extensions
+                .SplitExtensionField(defaultField, field);
+            ParserExtension extension = this.extensions
+                .GetExtension(splitExtensionField.Item2);
+            if (extension != null)
+            {
+                return extension.Parse(new ExtensionQuery(this, splitExtensionField.Item1,
+                    queryText));
+            }
+            return base.GetFieldQuery(field, queryText, quoted);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Ext/ExtensionQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Ext/ExtensionQuery.cs b/src/Lucene.Net.QueryParser/Ext/ExtensionQuery.cs
new file mode 100644
index 0000000..610e4ad
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Ext/ExtensionQuery.cs
@@ -0,0 +1,54 @@
+\ufeffnamespace Lucene.Net.QueryParser.Ext
+{
+    /*
+     * 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>
+    /// <see cref="ExtensionQuery"/> holds all query components extracted from the original
+    /// query string like the query field and the extension query string.
+    /// </summary>
+    public class ExtensionQuery
+    {
+        /// <summary>
+        /// Creates a new <see cref="ExtensionQuery"/>
+        /// </summary>
+        /// <param name="topLevelParser"></param>
+        /// <param name="field">the query field</param>
+        /// <param name="rawQueryString">the raw extension query string</param>
+        public ExtensionQuery(Classic.QueryParser topLevelParser, string field, string rawQueryString)
+        {
+            this.Field = field;
+            this.RawQueryString = rawQueryString;
+            this.TopLevelParser = topLevelParser;
+        }
+
+        /// <summary>
+        /// Returns the query field
+        /// </summary>
+        public string Field { get; protected set; }
+
+        /// <summary>
+        /// Returns the raw extension query string
+        /// </summary>
+        public string RawQueryString { get; protected set; }
+
+        /// <summary>
+        /// Returns the top level parser which created this <see cref="ExtensionQuery"/>
+        /// </summary>
+        public Classic.QueryParser TopLevelParser { get; protected set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/679ad24c/src/Lucene.Net.QueryParser/Ext/Extensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Ext/Extensions.cs b/src/Lucene.Net.QueryParser/Ext/Extensions.cs
new file mode 100644
index 0000000..6895268
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Ext/Extensions.cs
@@ -0,0 +1,167 @@
+\ufeffusing Lucene.Net.QueryParser.Classic;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Ext
+{
+    /*
+     * 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.
+     */
+
+    public class Extensions
+    {
+        private readonly IDictionary<string, ParserExtension> extensions = new Dictionary<string, ParserExtension>();
+        private readonly char extensionFieldDelimiter;
+
+        /// <summary>
+        /// The default extension field delimiter character. This constant is set to ':'
+        /// </summary>
+        public static readonly char DEFAULT_EXTENSION_FIELD_DELIMITER = ':';
+
+        /// <summary>
+        /// Creates a new <see cref="Extensions"/> instance with the
+        /// <see cref="#DEFAULT_EXTENSION_FIELD_DELIMITER"/> as a delimiter character.
+        /// </summary>
+        public Extensions()
+            : this(DEFAULT_EXTENSION_FIELD_DELIMITER)
+        {
+        }
+
+        /// <summary>
+        /// Creates a new <see cref="Extensions"/> instance
+        /// </summary>
+        /// <param name="extensionFieldDelimiter">the extensions field delimiter character</param>
+        public Extensions(char extensionFieldDelimiter)
+        {
+            this.extensionFieldDelimiter = extensionFieldDelimiter;
+        }
+
+        /// <summary>
+        /// Adds a new <see cref="ParserExtension"/> instance associated with the given key.
+        /// </summary>
+        /// <param name="key">the parser extension key</param>
+        /// <param name="extension">the parser extension</param>
+        public virtual void Add(string key, ParserExtension extension)
+        {
+            this.extensions[key] = extension;
+        }
+
+        /// <summary>
+        /// Returns the <see cref="ParserExtension"/> instance for the given key or
+        /// <code>null</code> if no extension can be found for the key.
+        /// </summary>
+        /// <param name="key">the extension key</param>
+        /// <returns>the <see cref="ParserExtension"/> instance for the given key or
+        /// <code>null</code> if no extension can be found for the key.</returns>
+        public ParserExtension GetExtension(string key)
+        {
+            if (key == null || !this.extensions.ContainsKey(key)) return null;
+            return this.extensions[key];
+        }
+
+        /// <summary>
+        /// Returns the extension field delimiter
+        /// </summary>
+        public virtual char ExtensionFieldDelimiter
+        {
+            get { return extensionFieldDelimiter; }
+        }
+
+        /// <summary>
+        /// Splits a extension field and returns the field / extension part as a
+        /// <see cref="Tuple{String,String}"/>. This method tries to split on the first occurrence of the
+        /// extension field delimiter, if the delimiter is not present in the string
+        /// the result will contain a <code>null</code> value for the extension key and
+        /// the given field string as the field value. If the given extension field
+        /// string contains no field identifier the result pair will carry the given
+        /// default field as the field value.
+        /// </summary>
+        /// <param name="defaultField">the default query field</param>
+        /// <param name="field">the extension field string</param>
+        /// <returns>a {<see cref="Tuple{String,String}"/> with the field name as the <see cref="Tuple{String,String}.Item1"/> and the
+        /// extension key as the <see cref="Tuple{String,String}.Item2"/></returns>
+        public Tuple<string, string> SplitExtensionField(string defaultField, string field)
+        {
+            int indexOf = field.IndexOf(this.extensionFieldDelimiter);
+            if (indexOf < 0)
+                return new Tuple<string, string>(field, null);
+            string indexField = indexOf == 0 ? defaultField : field.Substring(0, indexOf);
+            string extensionKey = field.Substring(indexOf + 1);
+            return new Tuple<string, string>(indexField, extensionKey);
+        }
+
+        /// <summary>
+        /// Escapes an extension field. The default implementation is equivalent to
+        /// <see cref="QueryParser.Escape(String)"/>.
+        /// </summary>
+        /// <param name="extfield">the extension field identifier</param>
+        /// <returns>the extension field identifier with all special chars escaped with
+        /// a backslash character.</returns>
+        public string EscapeExtensionField(string extfield)
+        {
+            return QueryParserBase.Escape(extfield);
+        }
+
+        /// <summary>
+        /// Builds an extension field string from a given extension key and the default
+        /// query field. The default field and the key are delimited with the extension
+        /// field delimiter character. This method makes no assumption about the order
+        /// of the extension key and the field. By default the extension key is
+        /// appended to the end of the returned string while the field is added to the
+        /// beginning. Special Query characters are escaped in the result.
+        /// <p>
+        /// Note: <see cref="Extensions"/> subclasses must maintain the contract between
+        /// <see cref="M:BuildExtensionField(String)"/> and
+        /// <see cref="M:BuildExtensionField(String, String)"/> where the latter inverts the
+        /// former.
+        /// </p>
+        /// </summary>
+        /// <param name="extensionKey">the extension key</param>
+        /// <returns>escaped extension field identifier</returns>
+        public string BuildExtensionField(string extensionKey)
+        {
+            return BuildExtensionField(extensionKey, "");
+        }
+
+        /// <summary>
+        /// Builds an extension field string from a given extension key and the default
+        /// query field. The default field and the key are delimited with the extension
+        /// field delimiter character. This method makes no assumption about the order
+        /// of the extension key and the field. By default the extension key is
+        /// appended to the end of the returned string while the field is added to the
+        /// beginning. Special Query characters are escaped in the result.
+        /// <p>
+        /// Note: <see cref="Extensions"/> subclasses must maintain the contract between
+        /// <see cref="M:BuildExtensionField(String)"/> and
+        /// <see cref="M:BuildExtensionField(String, String)"/> where the latter inverts the
+        /// former.
+        /// </summary>
+        /// <param name="extensionKey">the extension key</param>
+        /// <param name="field">the field to apply the extension on.</param>
+        /// <returns>escaped extension field identifier</returns>
+        /// <remarks>See <see cref="M:BuildExtensionField(String)"/> to use the default query field</remarks>
+        public string BuildExtensionField(string extensionKey, string field)
+        {
+            StringBuilder builder = new StringBuilder(field);
+            builder.Append(this.extensionFieldDelimiter);
+            builder.Append(extensionKey);
+            return EscapeExtensionField(builder.ToString());
+        }
+
+        // NOTE: Pair<T, T> was eliminated in favor of the built in Tuple<T, T> type.
+    }
+}