lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mhern...@apache.org
Subject [10/12] git commit: Finish QueryParsers.Flexible.Core namespace
Date Sun, 06 Oct 2013 23:06:02 GMT
Finish QueryParsers.Flexible.Core namespace


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

Branch: refs/heads/branch_4x
Commit: 1b7a0c34f79ae1882e5c78a2630a93b1cd6d5a73
Parents: acd4121
Author: Paul Irwin <paulirwin@gmail.com>
Authored: Fri Oct 4 13:32:27 2013 -0400
Committer: Paul Irwin <paulirwin@gmail.com>
Committed: Fri Oct 4 13:32:27 2013 -0400

----------------------------------------------------------------------
 .../QueryParsers/Contrib.QueryParsers.csproj    |  16 ++
 .../Flexible/Core/Nodes/FieldQueryNode.cs       |   2 +-
 .../Flexible/Core/Nodes/IRangeQueryNode.cs      |  20 ++
 .../Core/Nodes/NoTokenFoundQueryNode.cs         |  37 ++++
 .../Flexible/Core/Nodes/OpaqueQueryNode.cs      |  56 ++++++
 .../Flexible/Core/Nodes/OrQueryNode.cs          |  58 ++++++
 .../Flexible/Core/Nodes/PathQueryNode.cs        | 125 ++++++++++++
 .../Flexible/Core/Nodes/PhraseSlopQueryNode.cs  |  93 +++++++++
 .../Flexible/Core/Nodes/ProximityQueryNode.cs   | 196 +++++++++++++++++++
 .../Flexible/Core/Nodes/QuotedFieldQueryNode.cs |  43 ++++
 .../Flexible/Core/Nodes/SlopQueryNode.cs        |  93 +++++++++
 .../Core/Nodes/TokenizedPhraseQueryNode.cs      |  92 +++++++++
 .../Flexible/Core/Parser/ISyntaxParser.cs       |   2 +-
 .../Core/Processors/IQueryNodeProcessor.cs      |  17 ++
 .../NoChildOptimizationQueryNodeProcessor.cs    |  52 +++++
 .../Core/Processors/QueryNodeProcessor.cs       | 131 +++++++++++++
 .../Processors/QueryNodeProcessorPipeline.cs    | 180 +++++++++++++++++
 .../RemoveDeletedQueryNodesProcessor.cs         |  82 ++++++++
 .../Flexible/Core/QueryParserHelper.cs          | 107 ++++++++++
 19 files changed, 1400 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
index 2fcb669..59815b4 100644
--- a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
+++ b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
@@ -64,6 +64,7 @@
     <Compile Include="Flexible\Core\Config\IFieldConfigListener.cs" />
     <Compile Include="Flexible\Core\Config\QueryConfigHandler.cs" />
     <Compile Include="Flexible\Core\Nodes\FuzzyQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\IRangeQueryNode.cs" />
     <Compile Include="Flexible\Core\Nodes\ITextableQueryNode.cs" />
     <Compile Include="Flexible\Core\Messages\QueryParserMessages.cs" />
     <Compile Include="Flexible\Core\Nodes\AndQueryNode.cs" />
@@ -80,12 +81,27 @@
     <Compile Include="Flexible\Core\Nodes\MatchAllDocsQueryNode.cs" />
     <Compile Include="Flexible\Core\Nodes\MatchNoDocsQueryNode.cs" />
     <Compile Include="Flexible\Core\Nodes\ModifierQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\NoTokenFoundQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\OpaqueQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\OrQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\PathQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\PhraseSlopQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\ProximityQueryNode.cs" />
     <Compile Include="Flexible\Core\Nodes\QueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\QuotedFieldQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\SlopQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\TokenizedPhraseQueryNode.cs" />
     <Compile Include="Flexible\Core\Parser\IEscapeQuerySyntax.cs" />
     <Compile Include="Flexible\Core\Parser\ISyntaxParser.cs" />
+    <Compile Include="Flexible\Core\Processors\IQueryNodeProcessor.cs" />
+    <Compile Include="Flexible\Core\Processors\NoChildOptimizationQueryNodeProcessor.cs" />
+    <Compile Include="Flexible\Core\Processors\QueryNodeProcessor.cs" />
+    <Compile Include="Flexible\Core\Processors\QueryNodeProcessorPipeline.cs" />
+    <Compile Include="Flexible\Core\Processors\RemoveDeletedQueryNodesProcessor.cs" />
     <Compile Include="Flexible\Core\QueryNodeError.cs" />
     <Compile Include="Flexible\Core\QueryNodeException.cs" />
     <Compile Include="Flexible\Core\QueryNodeParseException.cs" />
+    <Compile Include="Flexible\Core\QueryParserHelper.cs" />
     <Compile Include="Flexible\Core\Util\QueryNodeOperation.cs" />
     <Compile Include="Flexible\Core\Util\StringUtils.cs" />
     <Compile Include="Flexible\Core\Util\UnescapedCharSequence.cs" />

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
index 41d9ceb..e05841a 100644
--- a/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
@@ -35,7 +35,7 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
             return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.NORMAL);
         }
 
-        protected ICharSequence GetTermEscapeQuoted(EscapeQuerySyntax escaper)
+        protected ICharSequence GetTermEscapeQuoted(IEscapeQuerySyntax escaper)
         {
             return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.STRING);
         }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
new file mode 100644
index 0000000..c9042a5
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public interface IRangeQueryNode<T> : IFieldableNode
+        where T : IFieldValuePairQueryNode<T>
+    {
+        T LowerBound { get; }
+
+        T UpperBound { get; }
+
+        bool IsLowerInclusive { get; }
+
+        bool IsUpperInclusive { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
new file mode 100644
index 0000000..f145843
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
@@ -0,0 +1,37 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class NoTokenFoundQueryNode : DeletedQueryNode
+    {
+        public NoTokenFoundQueryNode()
+            : base()
+        {
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return new StringCharSequenceWrapper("[NTF]");
+        }
+
+        public override string ToString()
+        {
+            return "<notokenfound/>";
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            NoTokenFoundQueryNode clone = (NoTokenFoundQueryNode)base.CloneTree();
+
+            // nothing to do here
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
new file mode 100644
index 0000000..68e8ca7
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
@@ -0,0 +1,56 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class OpaqueQueryNode : QueryNode
+    {
+        private string schema = null;
+
+        private string value = null;
+
+        public OpaqueQueryNode(string schema, string value)
+        {
+            this.SetLeaf(true);
+
+            this.schema = schema;
+            this.value = value;
+        }
+
+        public override string ToString()
+        {
+            return "<opaque schema='" + this.schema + "' value='" + this.value + "'/>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return new StringCharSequenceWrapper("@" + this.schema + ":'" + this.value + "'");
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            OpaqueQueryNode clone = (OpaqueQueryNode)base.CloneTree();
+
+            // .NET Port: shouldn't this have already been done by MemberwiseClone()?
+            clone.schema = this.schema;
+            clone.value = this.value;
+
+            return clone;
+        }
+
+        public string Schema
+        {
+            get { return schema; }
+        }
+
+        public string Value
+        {
+            get { return value; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
new file mode 100644
index 0000000..943b3f0
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
@@ -0,0 +1,58 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class OrQueryNode : BooleanQueryNode
+    {
+        public OrQueryNode(IList<IQueryNode> clauses)
+            : base(clauses)
+        {
+            if ((clauses == null) || (clauses.Count == 0))
+            {
+                throw new ArgumentException("OR query must have at least one clause");
+            }
+        }
+
+        public override string ToString()
+        {
+            if (Children == null || Children.Count == 0)
+                return "<boolean operation='or'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='or'>");
+            foreach (IQueryNode child in Children)
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+
+            }
+            sb.Append("\n</boolean>");
+            return sb.ToString();
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Children == null || Children.Count == 0)
+                return new StringCharSequenceWrapper("");
+
+            StringBuilder sb = new StringBuilder();
+            String filler = "";
+            foreach (IQueryNode child in Children)
+            {
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                filler = " OR ";
+            }
+
+            // in case is root or the parent is a group node avoid parenthesis
+            if ((Parent != null && Parent is GroupQueryNode) || IsRoot)
+                return new StringCharSequenceWrapper(sb.ToString());
+            else
+                return new StringCharSequenceWrapper("( " + sb.ToString() + " )");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
new file mode 100644
index 0000000..c8d55de
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
@@ -0,0 +1,125 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class PathQueryNode : QueryNode
+    {
+        public class QueryText : ICloneable
+        {
+            string value = null;
+            int begin;
+            int end;
+
+            public QueryText(string value, int begin, int end)
+            {
+                this.value = value;
+                this.begin = begin;
+                this.end = end;
+            }
+
+            public string Value
+            {
+                get { return value; }
+            }
+
+            public int Begin
+            {
+                get { return begin; }
+            }
+
+            public int End
+            {
+                get { return end; }
+            }
+
+            public override string ToString()
+            {
+                return value + ", " + begin + ", " + end;
+            }
+
+            public object Clone()
+            {
+                return this.MemberwiseClone();
+            }
+        }
+
+        private IList<QueryText> values = null;
+
+        public PathQueryNode(IList<QueryText> pathElements)
+        {
+            this.values = pathElements;
+            if (pathElements.Count <= 1)
+            {
+                // this should not happen
+                throw new ArgumentException("PathQuerynode requires more 2 or more path elements.");
+            }
+        }
+
+        public IList<QueryText> PathElements
+        {
+            get { return values; }
+            set { this.values = value; }
+        }
+
+        public QueryText GetPathElement(int index)
+        {
+            return values[index];
+        }
+
+        public string FirstPathElement
+        {
+            get { return values[0].Value; }
+        }
+
+        public IList<QueryText> GetPathElements(int startIndex)
+        {
+            IList<PathQueryNode.QueryText> rValues = new List<PathQueryNode.QueryText>();
+            for (int i = startIndex; i < this.values.Count; i++)
+            {
+                try
+                {
+                    rValues.Add((QueryText)this.values[i].Clone());
+                }
+                catch (NotSupportedException)
+                {
+                    // this will not happen
+                }
+            }
+            return rValues;
+        }
+
+        private string PathString
+        {
+            get
+            {
+                StringBuilder path = new StringBuilder();
+
+                foreach (QueryText pathelement in values)
+                {
+                    path.Append("/").Append(pathelement.Value);
+                }
+                return path.ToString();
+            }
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            StringBuilder path = new StringBuilder();
+            path.Append("/").Append(FirstPathElement);
+
+            foreach (QueryText pathelement in GetPathElements(1))
+            {
+                ICharSequence value = escaper.Escape(new StringCharSequenceWrapper(pathelement.Value), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.STRING);
+                path.Append("/\"").Append(value).Append("\"");
+            }
+            return new StringCharSequenceWrapper(path.ToString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
new file mode 100644
index 0000000..0ea1974
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
@@ -0,0 +1,93 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class PhraseSlopQueryNode : QueryNode, IFieldableNode
+    {
+        private int value = 0;
+
+        public PhraseSlopQueryNode(IQueryNode query, int value)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new Message(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+            }
+
+            this.value = value;
+            SetLeaf(false);
+            Allocate();
+            Add(query);
+        }
+
+        public IQueryNode Child
+        {
+            get { return Children[0]; }
+        }
+
+        public int Value
+        {
+            get { return value; }
+        }
+
+        private string ValueString
+        {
+            get
+            {
+                // .NET Port: java code here was doing some seemingly unnecessary checks
+                // that seemed like cruft left over from float code
+                return value.ToString();
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<phraseslop value='" + ValueString + "'>" + "\n" + Child.ToString() + "\n</phraseslop>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Child == null)
+                return new StringCharSequenceWrapper("");
+            return new StringCharSequenceWrapper(Child.ToQueryString(escapeSyntaxParser) + "~" + ValueString);
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            PhraseSlopQueryNode clone = (PhraseSlopQueryNode)base.CloneTree();
+
+            clone.value = this.value;
+
+            return clone;
+        }
+
+        public string Field
+        {
+            get
+            {
+                IQueryNode child = Child;
+
+                if (child is IFieldableNode)
+                    return ((IFieldableNode)child).Field;
+
+                return null;
+            }
+            set
+            {
+                IQueryNode child = Child;
+
+                if (child is IFieldableNode)
+                {
+                    ((IFieldableNode)child).Field = value;
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
new file mode 100644
index 0000000..7fadda6
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
@@ -0,0 +1,196 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class ProximityQueryNode : BooleanQueryNode
+    {
+        public enum Type
+        {
+            PARAGRAPH,
+            SENTENCE,
+            NUMBER
+        }
+
+        // .NET Port: This is necessary as enums are value types in .NET and can't have override/abstract methods
+        public static string TypeToQueryString(Type t)
+        {
+            switch (t)
+            {
+                case Type.PARAGRAPH:
+                    return "WITHIN PARAGRAPH";
+                case Type.SENTENCE:
+                    return "WITHIN SENTENCE";
+                case Type.NUMBER:
+                    return "WITHIN";
+                default:
+                    throw new InvalidOperationException("Not supported");
+            }
+        }
+
+        public class ProximityType
+        {
+            internal int pDistance = 0;
+
+            internal Type? pType = null;
+
+            public ProximityType(Type type)
+                : this(type, 0)
+            {
+            }
+
+            public ProximityType(Type type, int distance)
+            {
+                this.pType = type;
+                this.pDistance = distance;
+            }
+        }
+
+        private Type proximityType = Type.SENTENCE;
+        private int distance = -1;
+        private bool inorder = false;
+        private string field = null;
+
+        public ProximityQueryNode(IList<IQueryNode> clauses, string field, Type type, int distance, bool inorder)
+            : base(clauses)
+        {
+            SetLeaf(false);
+            this.proximityType = type;
+            this.inorder = inorder;
+            this.field = field;
+            if (type == Type.NUMBER)
+            {
+                if (distance <= 0)
+                {
+                    throw new QueryNodeError(new Message(QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "distance", distance));
+
+                }
+                else
+                {
+                    this.distance = distance;
+                }
+
+            }
+            ClearFields(clauses, field);
+        }
+
+        public ProximityQueryNode(IList<IQueryNode> clauses, string field, Type type, bool inorder)
+            : this(clauses, field, type, -1, inorder)
+        {
+        }
+
+        private static void ClearFields(IList<IQueryNode> nodes, string field)
+        {
+            if (nodes == null || nodes.Count == 0)
+                return;
+
+            foreach (IQueryNode clause in nodes)
+            {
+                if (clause is FieldQueryNode)
+                {
+                    ((FieldQueryNode)clause).toQueryStringIgnoreFields = true;
+                    ((FieldQueryNode)clause).Field = field;
+                }
+            }
+        }
+
+        public Type ProximityTypeValue
+        {
+            get
+            {
+                return this.proximityType;
+            }
+        }
+
+        public override string ToString()
+        {
+            String distanceSTR = ((this.distance == -1) ? ("")
+                : (" distance='" + this.distance) + "'");
+
+            if (Children == null || Children.Count == 0)
+                return "<proximity field='" + this.field + "' inorder='" + this.inorder
+                    + "' type='" + this.proximityType.ToString() + "'" + distanceSTR
+                    + "/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<proximity field='" + this.field + "' inorder='" + this.inorder
+                + "' type='" + this.proximityType.ToString() + "'" + distanceSTR + ">");
+            foreach (IQueryNode child in Children)
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+            }
+            sb.Append("\n</proximity>");
+            return sb.ToString();
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            String withinSTR = TypeToQueryString(this.proximityType)
+                + ((this.distance == -1) ? ("") : (" " + this.distance))
+                + ((this.inorder) ? (" INORDER") : (""));
+
+            StringBuilder sb = new StringBuilder();
+            if (Children == null || Children.Count == 0)
+            {
+                // no children case
+            }
+            else
+            {
+                String filler = "";
+                foreach (IQueryNode child in Children)
+                {
+                    sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                    filler = " ";
+                }
+            }
+
+            if (IsDefaultField(this.field))
+            {
+                return new StringCharSequenceWrapper("( " + sb.ToString() + " ) " + withinSTR);
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.field + ":(( " + sb.ToString() + " ) " + withinSTR + ")");
+            }
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            ProximityQueryNode clone = (ProximityQueryNode)base.CloneTree();
+
+            clone.proximityType = this.proximityType;
+            clone.distance = this.distance;
+            clone.field = this.field;
+
+            return clone;
+        }
+
+        public int Distance
+        {
+            get { return this.distance; }
+        }
+
+        public string Field
+        {
+            get { return this.field; }
+            set { this.field = value; }
+        }
+
+        public string FieldAsString
+        {
+            get { return this.field; }
+        }
+
+        public bool IsInOrder
+        {
+            get { return this.inorder; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
new file mode 100644
index 0000000..2af7e36
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
@@ -0,0 +1,43 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class QuotedFieldQueryNode : FieldQueryNode
+    {
+        public QuotedFieldQueryNode(string field, string text, int begin, int end)
+            : base(field, text, begin, end)
+        {
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            if (IsDefaultField(this.field))
+            {
+                return new StringCharSequenceWrapper("\"" + GetTermEscapeQuoted(escaper) + "\"");
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.field + ":" + "\"" + GetTermEscapeQuoted(escaper) + "\"");
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<quotedfield start='" + this.begin + "' end='" + this.end
+                + "' field='" + this.field + "' term='" + this.text + "'/>";
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            QuotedFieldQueryNode clone = (QuotedFieldQueryNode)base.CloneTree();
+            // nothing to do here
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
new file mode 100644
index 0000000..b2ce8f2
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
@@ -0,0 +1,93 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class SlopQueryNode : QueryNode, IFieldableNode
+    {
+        private int value = 0;
+
+        public SlopQueryNode(IQueryNode query, int value)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new Message(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+            }
+
+            this.value = value;
+            SetLeaf(false);
+            Allocate();
+            Add(query);
+        }
+
+        public IQueryNode Child
+        {
+            get
+            {
+                return Children[0];
+            }
+        }
+
+        public int Value
+        {
+            get { return value; }
+        }
+
+        public string ValueString
+        {
+            get { return value.ToString(); }
+        }
+
+        public override string ToString()
+        {
+            return "<slop value='" + ValueString + "'>" + "\n" + Child.ToString() + "\n</slop>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Child == null)
+                return new StringCharSequenceWrapper("");
+            return new StringCharSequenceWrapper(Child.ToQueryString(escapeSyntaxParser) + "~" + ValueString);
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            SlopQueryNode clone = (SlopQueryNode)base.CloneTree();
+
+            clone.value = this.value;
+
+            return clone;
+        }
+
+        public string Field
+        {
+            get
+            {
+                IQueryNode child = Child;
+
+                if (child is IFieldableNode)
+                {
+                    return ((IFieldableNode)child).Field;
+                }
+
+                return null;
+            }
+            set
+            {
+                IQueryNode child = Child;
+
+                if (child is IFieldableNode)
+                {
+                    ((IFieldableNode)child).Field = value;
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
new file mode 100644
index 0000000..d42443e
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
@@ -0,0 +1,92 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public class TokenizedPhraseQueryNode : QueryNode, IFieldableNode
+    {
+        public TokenizedPhraseQueryNode()
+        {
+            SetLeaf(false);
+            Allocate();
+        }
+
+        public override string ToString()
+        {
+            if (Children == null || Children.Count == 0)
+                return "<tokenizedphrase/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<tokenizedtphrase>");
+            foreach (IQueryNode child in Children)
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+            }
+            sb.Append("\n</tokenizedphrase>");
+            return sb.ToString();
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Children == null || Children.Count == 0)
+                return new StringCharSequenceWrapper("");
+
+            StringBuilder sb = new StringBuilder();
+            String filler = "";
+            foreach (IQueryNode child in Children)
+            {
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                filler = ",";
+            }
+
+            return new StringCharSequenceWrapper("[TP[" + sb.ToString() + "]]");
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            TokenizedPhraseQueryNode clone = (TokenizedPhraseQueryNode)base.CloneTree();
+
+            // nothing to do
+
+            return clone;
+        }
+
+        public string Field
+        {
+            get
+            {
+                IList<IQueryNode> children = Children;
+
+                if (children == null || children.Count == 0)
+                {
+                    return null;
+
+                }
+                else
+                {
+                    return ((IFieldableNode)children[0]).Field;
+                }
+            }
+            set
+            {
+                IList<IQueryNode> children = Children;
+
+                if (children != null)
+                {
+                    foreach (IQueryNode child in Children)
+                    {
+                        if (child is IFieldableNode)
+                        {
+                            ((IFieldableNode)child).Field = value;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs b/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
index b59540e..4a56a44 100644
--- a/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
+++ b/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
@@ -10,6 +10,6 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Parser
 {
     public interface ISyntaxParser
     {
-        IQueryNode Parse(ICharSequence query, ICharSequence field);
+        IQueryNode Parse(string query, string field);
     }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
new file mode 100644
index 0000000..c2cd9a4
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
@@ -0,0 +1,17 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
+{
+    public interface IQueryNodeProcessor
+    {
+        IQueryNode Process(IQueryNode queryTree);
+
+        QueryConfigHandler QueryConfigHandler { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
new file mode 100644
index 0000000..3390b2c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
@@ -0,0 +1,52 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
+{
+    public class NoChildOptimizationQueryNodeProcessor : QueryNodeProcessor
+    {
+        public NoChildOptimizationQueryNodeProcessor()
+        {
+            // empty constructor
+        }
+
+        protected override IQueryNode PostProcessNode(IQueryNode node)
+        {
+            if (node is BooleanQueryNode || node is BoostQueryNode
+                || node is TokenizedPhraseQueryNode
+                || node is ModifierQueryNode)
+            {
+                IList<IQueryNode> children = node.Children;
+
+                if (children != null && children.Count > 0)
+                {
+                    foreach (IQueryNode child in children)
+                    {
+                        if (!(child is DeletedQueryNode))
+                        {
+                            return node;
+                        }
+                    }
+                }
+
+                return new MatchNoDocsQueryNode();
+            }
+
+            return node;
+        }
+
+        protected override IQueryNode PreProcessNode(IQueryNode node)
+        {
+            return node;
+        }
+
+        protected override IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children)
+        {
+            return children;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
new file mode 100644
index 0000000..98def49
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
@@ -0,0 +1,131 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
+{
+    public abstract class QueryNodeProcessor : IQueryNodeProcessor
+    {
+        private List<ChildrenList> childrenListPool = new List<ChildrenList>();
+
+        private QueryConfigHandler queryConfig;
+
+        public QueryNodeProcessor()
+        {
+            // empty constructor
+        }
+
+        public QueryNodeProcessor(QueryConfigHandler queryConfigHandler)
+        {
+            this.queryConfig = queryConfigHandler;
+        }
+
+        public virtual IQueryNode Process(IQueryNode queryTree)
+        {
+            return ProcessIteration(queryTree);
+        }
+
+        private IQueryNode ProcessIteration(IQueryNode queryTree)
+        {
+            queryTree = PreProcessNode(queryTree);
+
+            ProcessChildren(queryTree);
+
+            queryTree = PostProcessNode(queryTree);
+
+            return queryTree;
+        }
+
+        protected void ProcessChildren(IQueryNode queryTree)
+        {
+            IList<IQueryNode> children = queryTree.Children;
+            ChildrenList newChildren;
+
+            if (children != null && children.Count > 0)
+            {
+                newChildren = AllocateChildrenList();
+
+                try
+                {
+                    IQueryNode child;
+
+                    // .NET Port: can't modify range variable, changed to for loop
+                    for (int i = 0; i < children.Count; i++)
+                    {
+                        child = children[i];
+
+                        child = ProcessIteration(child);
+
+                        if (child == null)
+                        {
+                            throw new NullReferenceException();
+                        }
+
+                        newChildren.Add(child);
+                    }
+
+                    IList<IQueryNode> orderedChildrenList = SetChildrenOrder(newChildren);
+
+                    queryTree.Set(orderedChildrenList);
+                }
+                finally
+                {
+                    newChildren.beingUsed = false;
+                }
+            }
+        }
+
+        private ChildrenList AllocateChildrenList()
+        {
+            ChildrenList list = null;
+
+            foreach (ChildrenList auxList in this.childrenListPool)
+            {
+                if (!auxList.beingUsed)
+                {
+                    list = auxList;
+                    list.Clear();
+
+                    break;
+                }
+            }
+
+            if (list == null)
+            {
+                list = new ChildrenList();
+                this.childrenListPool.Add(list);
+            }
+
+            list.beingUsed = true;
+
+            return list;
+        }
+
+        public QueryConfigHandler QueryConfigHandler
+        {
+            get
+            {
+                return this.queryConfig;
+            }
+            set
+            {
+                this.queryConfig = value;
+            }
+        }
+
+        protected abstract IQueryNode PreProcessNode(IQueryNode node);
+
+        protected abstract IQueryNode PostProcessNode(IQueryNode node);
+
+        protected abstract IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children);
+
+        private class ChildrenList : List<IQueryNode>
+        {
+            internal bool beingUsed;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
new file mode 100644
index 0000000..d674ce9
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
@@ -0,0 +1,180 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
+{
+    public class QueryNodeProcessorPipeline : IQueryNodeProcessor, IList<IQueryNodeProcessor>
+    {
+        private List<IQueryNodeProcessor> processors = new List<IQueryNodeProcessor>();
+
+        private QueryConfigHandler queryConfig;
+
+        public QueryNodeProcessorPipeline()
+        {
+            // empty constructor
+        }
+
+        public QueryNodeProcessorPipeline(QueryConfigHandler queryConfigHandler)
+        {
+            this.queryConfig = queryConfigHandler;
+        }
+
+        public QueryConfigHandler QueryConfigHandler
+        {
+            get
+            {
+                return this.queryConfig;
+            }
+            set
+            {
+                this.queryConfig = value;
+
+                foreach (IQueryNodeProcessor processor in this.processors)
+                {
+                    processor.QueryConfigHandler = this.queryConfig;
+                }
+            }
+        }
+
+        public IQueryNode Process(IQueryNode queryTree)
+        {
+            foreach (IQueryNodeProcessor processor in this.processors)
+            {
+                queryTree = processor.Process(queryTree);
+            }
+
+            return queryTree;
+        }
+
+        public void Add(IQueryNodeProcessor processor)
+        {
+            this.processors.Add(processor);
+
+            processor.QueryConfigHandler = this.queryConfig;
+        }
+
+        public void Insert(int index, IQueryNodeProcessor processor)
+        {
+            this.processors.Insert(index, processor);
+            processor.QueryConfigHandler = this.queryConfig;
+        }
+
+        public bool AddAll(ICollection<IQueryNodeProcessor> c)
+        {
+            this.processors.AddRange(c);
+
+            foreach (IQueryNodeProcessor processor in c)
+            {
+                processor.QueryConfigHandler = this.queryConfig;
+            }
+
+            return c.Count > 0;
+        }
+
+        public bool AddAll(int index, ICollection<IQueryNodeProcessor> c)
+        {
+            this.processors.InsertRange(index, c);
+
+            foreach (IQueryNodeProcessor processor in c)
+            {
+                processor.QueryConfigHandler = this.queryConfig;
+            }
+
+            return c.Count > 0;
+        }
+
+        public void Clear()
+        {
+            this.processors.Clear();
+        }
+
+        public bool Contains(IQueryNodeProcessor item)
+        {
+            return this.processors.Contains(item);
+        }
+
+        public bool ContainsAll(ICollection<IQueryNodeProcessor> c)
+        {
+            foreach (var processor in c)
+            {
+                if (!this.processors.Contains(processor))
+                    return false;
+            }
+
+            return true;
+        }
+        
+        public IQueryNodeProcessor this[int index]
+        {
+            get
+            {
+                return this.processors[index];
+            }
+            set
+            {
+                IQueryNodeProcessor oldProcessor = (this.processors.Count > index) ? this.processors[index] : value;
+                this.processors[index] = value;
+
+                if (oldProcessor != value)
+                {
+                    value.QueryConfigHandler = this.queryConfig;
+                }
+            }
+        }
+
+        public int IndexOf(IQueryNodeProcessor item)
+        {
+            return this.processors.IndexOf(item);
+        }
+
+        public bool IsEmpty
+        {
+            get { return this.processors.Count == 0; }
+        }
+        
+        public IEnumerator<IQueryNodeProcessor> GetEnumerator()
+        {
+            return this.processors.GetEnumerator();
+        }
+
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        public int LastIndexOf(IQueryNodeProcessor o)
+        {
+            return this.processors.LastIndexOf(o);
+        }
+
+        public bool Remove(IQueryNodeProcessor item)
+        {
+            return this.processors.Remove(item);
+        }
+
+        public void RemoveAt(int index)
+        {
+            this.processors.RemoveAt(index);
+        }
+
+        public int Count
+        {
+            get { return this.processors.Count; }
+        }
+
+        public bool IsReadOnly
+        {
+            get { return false; }
+        }
+
+        public void CopyTo(IQueryNodeProcessor[] array, int arrayIndex)
+        {
+            ((IList<IQueryNodeProcessor>)this.processors).CopyTo(array, arrayIndex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
new file mode 100644
index 0000000..106f075
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
@@ -0,0 +1,82 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Processors
+{
+    public class RemoveDeletedQueryNodesProcessor : QueryNodeProcessor
+    {
+        public RemoveDeletedQueryNodesProcessor()
+        {
+            // empty constructor
+        }
+
+        public override IQueryNode Process(IQueryNode queryTree)
+        {
+            queryTree = base.Process(queryTree);
+
+            if (queryTree is DeletedQueryNode
+                && !(queryTree is MatchNoDocsQueryNode))
+            {
+                return new MatchNoDocsQueryNode();
+            }
+
+            return queryTree;
+        }
+
+        protected override IQueryNode PostProcessNode(IQueryNode node)
+        {
+            if (!node.IsLeaf)
+            {
+                IList<IQueryNode> children = node.Children;
+                bool removeBoolean = false;
+
+                if (children == null || children.Count == 0)
+                {
+                    removeBoolean = true;
+                }
+                else
+                {
+                    removeBoolean = true;
+
+                    foreach (IQueryNode child in children)
+                    {
+                        if (!(child is DeletedQueryNode))
+                        {
+                            removeBoolean = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (removeBoolean)
+                {
+                    return new DeletedQueryNode();
+                }
+            }
+
+            return node;
+        }
+
+        protected override IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children)
+        {
+            for (int i = 0; i < children.Count; i++)
+            {
+                if (children[i] is DeletedQueryNode)
+                {
+                    children.RemoveAt(i--);
+                }
+            }
+
+            return children;
+        }
+
+        protected override IQueryNode PreProcessNode(IQueryNode node)
+        {
+            return node;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1b7a0c34/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs b/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
new file mode 100644
index 0000000..97fdd7c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
@@ -0,0 +1,107 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Builders;
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Core.Processors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core
+{
+    public class QueryParserHelper
+    {
+        private IQueryNodeProcessor processor;
+
+        private ISyntaxParser syntaxParser;
+
+        private IQueryBuilder builder;
+
+        private QueryConfigHandler config;
+
+        public QueryParserHelper(QueryConfigHandler queryConfigHandler, ISyntaxParser syntaxParser, IQueryNodeProcessor processor, IQueryBuilder builder)
+        {
+            this.syntaxParser = syntaxParser;
+            this.config = queryConfigHandler;
+            this.processor = processor;
+            this.builder = builder;
+
+            if (processor != null)
+            {
+                processor.QueryConfigHandler = queryConfigHandler;
+            }
+        }
+
+        public IQueryNodeProcessor QueryNodeProcessor
+        {
+            get
+            {
+                return processor;
+            }
+            set
+            {
+                this.processor = value;
+                this.processor.QueryConfigHandler = QueryConfigHandler;
+            }
+        }
+
+        public ISyntaxParser SyntaxParser
+        {
+            get { return syntaxParser; }
+            set
+            {
+                if (value == null)
+                {
+                    throw new ArgumentException("textParser should not be null!");
+                }
+
+                this.syntaxParser = value;
+            }
+        }
+
+        public IQueryBuilder QueryBuilder
+        {
+            get { return builder; }
+            set
+            {
+                if (value == null)
+                {
+                    throw new ArgumentException("queryBuilder should not be null!");
+                }
+
+                this.builder = value;
+            }
+        }
+
+        public QueryConfigHandler QueryConfigHandler
+        {
+            get { return config; }
+            set
+            {
+                this.config = value;
+                IQueryNodeProcessor processor = QueryNodeProcessor;
+
+                if (processor != null)
+                {
+                    processor.QueryConfigHandler = config;
+                }
+            }
+        }
+
+        public object Parse(string query, string defaultField)
+        {
+            IQueryNode queryTree = SyntaxParser.Parse(query, defaultField);
+
+            IQueryNodeProcessor processor = QueryNodeProcessor;
+
+            if (processor != null)
+            {
+                queryTree = processor.Process(queryTree);
+            }
+
+            return QueryBuilder.Build(queryTree);
+        }
+    }
+}


Mime
View raw message