You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2016/12/06 15:11:46 UTC

[11/58] lucenenet git commit: WIP on QueryParsers.Flexible

WIP on QueryParsers.Flexible


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

Branch: refs/heads/master
Commit: c83be6be537d1f9169f74308d854c11ed6026172
Parents: e8735ed
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Mon Nov 28 22:15:35 2016 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Mon Nov 28 22:15:35 2016 +0700

----------------------------------------------------------------------
 src/Lucene.Net.Core/Document/FieldType.cs       |    2 +-
 src/Lucene.Net.Core/Support/StringSupport.cs    |   10 +
 .../Flexible/Core/Builders/QueryBuilder.cs      |   37 +
 .../Flexible/Core/Builders/QueryTreeBuilder.cs  |  252 +++
 .../Flexible/Core/Config/AbstractQueryConfig.cs |  114 ++
 .../Flexible/Core/Config/ConfigurationKey.cs    |   45 +
 .../Flexible/Core/Config/FieldConfig.cs         |   50 +
 .../Flexible/Core/Config/FieldConfigListener.cs |   24 +
 .../Flexible/Core/Config/QueryConfigHandler.cs  |   69 +
 .../Core/Messages/QueryParserMessages.cs        |   50 +
 .../Flexible/Core/Nodes/AndQueryNode.cs         |   69 +
 .../Flexible/Core/Nodes/AnyQueryNode.cs         |  151 ++
 .../Flexible/Core/Nodes/BooleanQueryNode.cs     |   77 +
 .../Flexible/Core/Nodes/BoostQueryNode.cs       |  113 ++
 .../Flexible/Core/Nodes/DeletedQueryNode.cs     |   43 +
 .../Flexible/Core/Nodes/FieldQueryNode.cs       |  241 +++
 .../Core/Nodes/FieldValuePairQueryNode.cs       |   19 +
 .../Flexible/Core/Nodes/FieldableNode.cs        |   38 +
 .../Flexible/Core/Nodes/FuzzyQueryNode.cs       |  119 ++
 .../Flexible/Core/Nodes/GroupQueryNode.cs       |   73 +
 .../Core/Nodes/MatchAllDocsQueryNode.cs         |   43 +
 .../Flexible/Core/Nodes/MatchNoDocsQueryNode.cs |   25 +
 .../Flexible/Core/Nodes/ModifierQueryNode.cs    |  172 +++
 .../Core/Nodes/NoTokenFoundQueryNode.cs         |   42 +
 .../Flexible/Core/Nodes/OpaqueQueryNode.cs      |   75 +
 .../Flexible/Core/Nodes/OrQueryNode.cs          |   68 +
 .../Flexible/Core/Nodes/PathQueryNode.cs        |  233 +++
 .../Flexible/Core/Nodes/PhraseSlopQueryNode.cs  |  106 ++
 .../Flexible/Core/Nodes/ProximityQueryNode.cs   |  288 ++++
 .../Flexible/Core/Nodes/QueryNode.cs            |   84 +
 .../Flexible/Core/Nodes/QueryNodeImpl.cs        |  292 ++++
 .../Flexible/Core/Nodes/QuotedFieldQueryNode.cs |   77 +
 .../Flexible/Core/Nodes/RangeQueryNode.cs       |   32 +
 .../Flexible/Core/Nodes/SlopQueryNode.cs        |  116 ++
 .../Flexible/Core/Nodes/TextableQueryNode.cs    |   17 +
 .../Core/Nodes/TokenizedPhraseQueryNode.cs      |  103 ++
 .../Flexible/Core/Nodes/ValueQueryNode.cs       |   18 +
 .../Flexible/Core/Parser/EscapeQuerySyntax.cs   |   39 +
 .../Flexible/Core/Parser/SyntaxParser.cs        |   23 +
 .../NoChildOptimizationQueryNodeProcessor.cs    |   73 +
 .../Core/Processors/QueryNodeProcessor.cs       |   61 +
 .../Core/Processors/QueryNodeProcessorImpl.cs   |  202 +++
 .../Processors/QueryNodeProcessorPipeline.cs    |  425 ++++++
 .../RemoveDeletedQueryNodesProcessor.cs         |  102 ++
 .../Flexible/Core/QueryNodeError.cs             |   64 +
 .../Flexible/Core/QueryNodeException.cs         |   75 +
 .../Flexible/Core/QueryNodeParseException.cs    |  117 ++
 .../Flexible/Core/QueryParserHelper.cs          |  260 ++++
 .../Flexible/Core/Util/QueryNodeOperation.cs    |   85 ++
 .../Flexible/Core/Util/StringUtils.cs           |   26 +
 .../Flexible/Core/Util/UnescapedCharSequence.cs |  188 +++
 .../Flexible/Messages/Message.cs                |   21 +
 .../Flexible/Messages/MessageImpl.cs            |   71 +
 .../Flexible/Messages/NLS.cs                    |  292 ++++
 .../Flexible/Messages/NLSException.cs           |   24 +
 .../Precedence/PrecedenceQueryParser.cs         |   41 +
 .../BooleanModifiersQueryNodeProcessor.cs       |  127 ++
 .../PrecedenceQueryNodeProcessorPipeline.cs     |   46 +
 .../Standard/Builders/AnyQueryNodeBuilder.cs    |   80 +
 .../Builders/BooleanQueryNodeBuilder.cs         |  112 ++
 .../Standard/Builders/BoostQueryNodeBuilder.cs  |   51 +
 .../Standard/Builders/DummyQueryNodeBuilder.cs  |   46 +
 .../Standard/Builders/FieldQueryNodeBuilder.cs  |   40 +
 .../Standard/Builders/FuzzyQueryNodeBuilder.cs  |   48 +
 .../Standard/Builders/GroupQueryNodeBuilder.cs  |   42 +
 .../Builders/MatchAllDocsQueryNodeBuilder.cs    |   52 +
 .../Builders/MatchNoDocsQueryNodeBuilder.cs     |   53 +
 .../Builders/ModifierQueryNodeBuilder.cs        |   42 +
 .../Builders/MultiPhraseQueryNodeBuilder.cs     |   83 +
 .../Builders/NumericRangeQueryNodeBuilder.cs    |   91 ++
 .../Standard/Builders/PhraseQueryNodeBuilder.cs |   59 +
 .../Builders/PrefixWildcardQueryNodeBuilder.cs  |   52 +
 .../Standard/Builders/RegexpQueryNodeBuilder.cs |   51 +
 .../Standard/Builders/SlopQueryNodeBuilder.cs   |   55 +
 .../Builders/StandardBooleanQueryNodeBuilder.cs |  112 ++
 .../Standard/Builders/StandardQueryBuilder.cs   |   22 +
 .../Builders/StandardQueryTreeBuilder.cs        |   60 +
 .../Builders/TermRangeQueryNodeBuilder.cs       |   69 +
 .../Builders/WildcardQueryNodeBuilder.cs        |   51 +
 .../Standard/CommonQueryParserConfiguration.cs  |    2 +-
 .../Standard/Config/FieldBoostMapFCListener.cs  |   47 +
 .../Config/FieldDateResolutionFCListener.cs     |   55 +
 .../Flexible/Standard/Config/FuzzyConfig.cs     |   41 +
 .../Standard/Config/NumberDateFormat.cs         |   60 +
 .../Flexible/Standard/Config/NumericConfig.cs   |  155 ++
 .../Config/NumericFieldConfigListener.cs        |   59 +
 .../Config/StandardQueryConfigHandler.cs        |  200 +++
 .../Standard/Nodes/AbstractRangeQueryNode.cs    |  260 ++++
 .../Standard/Nodes/BooleanModifierNode.cs       |   23 +
 .../Standard/Nodes/MultiPhraseQueryNode.cs      |  104 ++
 .../Flexible/Standard/Nodes/NumericQueryNode.cs |  146 ++
 .../Standard/Nodes/NumericRangeQueryNode.cs     |  160 ++
 .../Standard/Nodes/PrefixWildcardQueryNode.cs   |   74 +
 .../Flexible/Standard/Nodes/RegexpQueryNode.cs  |   99 ++
 .../Standard/Nodes/StandardBooleanQueryNode.cs  |   32 +
 .../Standard/Nodes/TermRangeQueryNode.cs        |   33 +
 .../Standard/Nodes/WildcardQueryNode.cs         |   84 +
 .../Flexible/Standard/Parser/CharStream.cs      |  117 ++
 .../Standard/Parser/EscapeQuerySyntaxImpl.cs    |  438 ++++++
 .../Flexible/Standard/Parser/FastCharStream.cs  |  140 ++
 .../Flexible/Standard/Parser/ParseException.cs  |  212 +++
 .../Standard/Parser/StandardSyntaxParser.cs     | 1250 +++++++++++++++
 .../Parser/StandardSyntaxParserConstants.cs     |  129 ++
 .../Parser/StandardSyntaxParserTokenManager.cs  |  959 ++++++++++++
 .../Flexible/Standard/Parser/Token.cs           |  135 ++
 .../Flexible/Standard/Parser/TokenMgrError.cs   |  164 ++
 .../Processors/AllowLeadingWildcardProcessor.cs |  100 ++
 .../Processors/AnalyzerQueryNodeProcessor.cs    |  435 ++++++
 .../BooleanQuery2ModifierNodeProcessor.cs       |  210 +++
 ...SingleChildOptimizationQueryNodeProcessor.cs |   79 +
 .../Processors/BoostQueryNodeProcessor.cs       |   74 +
 .../DefaultPhraseSlopQueryNodeProcessor.cs      |  112 ++
 .../Processors/FuzzyQueryNodeProcessor.cs       |   75 +
 .../Processors/GroupQueryNodeProcessor.cs       |  240 +++
 .../LowercaseExpandedTermsQueryNodeProcessor.cs |   87 ++
 .../MatchAllDocsQueryNodeProcessor.cs           |   62 +
 .../Processors/MultiFieldQueryNodeProcessor.cs  |  130 ++
 .../MultiTermRewriteMethodProcessor.cs          |   64 +
 .../Processors/NumericQueryNodeProcessor.cs     |  150 ++
 .../NumericRangeQueryNodeProcessor.cs           |  164 ++
 .../Processors/OpenRangeQueryNodeProcessor.cs   |   69 +
 .../Processors/PhraseSlopQueryNodeProcessor.cs  |   61 +
 .../RemoveEmptyNonLeafQueryNodeProcessor.cs     |  110 ++
 .../StandardQueryNodeProcessorPipeline.cs       |   54 +
 .../Processors/TermRangeQueryNodeProcessor.cs   |  164 ++
 .../Processors/WildcardQueryNodeProcessor.cs    |  131 ++
 .../Flexible/Standard/QueryParserUtil.cs        |  202 +++
 .../Flexible/Standard/StandardQueryParser.cs    |  651 ++++++++
 .../Lucene.Net.QueryParser.csproj               |  136 ++
 .../Properties/Resources.Designer.cs            |  225 +++
 .../Properties/Resources.resx                   |  177 +++
 .../Core/Builders/TestQueryTreeBuilder.cs       |   60 +
 .../Flexible/Core/Nodes/TestQueryNode.cs        |   60 +
 .../Messages/MessagesTestBundle.Designer.cs     |   63 +
 .../Flexible/Messages/MessagesTestBundle.cs     |   12 +
 .../Messages/MessagesTestBundle.ja-JP.resx      |  126 ++
 .../Flexible/Messages/MessagesTestBundle.resx   |  126 ++
 .../Flexible/Messages/TestNLS.cs                |  121 ++
 .../Precedence/TestPrecedenceQueryParser.cs     |  727 +++++++++
 .../Flexible/Spans/SpanOrQueryNodeBuilder.cs    |   50 +
 .../Flexible/Spans/SpanTermQueryNodeBuilder.cs  |   40 +
 .../Flexible/Spans/SpansQueryConfigHandler.cs   |   33 +
 .../Flexible/Spans/SpansQueryTreeBuilder.cs     |   44 +
 .../Spans/SpansValidatorQueryNodeProcessor.cs   |   55 +
 .../Flexible/Spans/TestSpanQueryParser.cs       |  238 +++
 .../Spans/TestSpanQueryParserSimpleSample.cs    |  113 ++
 .../Flexible/Spans/UniqueFieldAttribute.cs      |   22 +
 .../Flexible/Spans/UniqueFieldAttributeImpl.cs  |   88 ++
 .../Spans/UniqueFieldQueryNodeProcessor.cs      |   68 +
 .../Standard/TestMultiAnalyzerQPHelper.cs       |  267 ++++
 .../Flexible/Standard/TestMultiFieldQPHelper.cs |  409 +++++
 .../Flexible/Standard/TestNumericQueryParser.cs |  523 +++++++
 .../Flexible/Standard/TestQPHelper.cs           | 1443 ++++++++++++++++++
 .../Flexible/Standard/TestStandardQP.cs         |  235 +++
 .../Lucene.Net.Tests.QueryParser.csproj         |   35 +
 155 files changed, 21116 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.Core/Document/FieldType.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Document/FieldType.cs b/src/Lucene.Net.Core/Document/FieldType.cs
index 75ba177..01c6e94 100644
--- a/src/Lucene.Net.Core/Document/FieldType.cs
+++ b/src/Lucene.Net.Core/Document/FieldType.cs
@@ -32,7 +32,7 @@ namespace Lucene.Net.Documents
         /// Data type of the numeric value
         /// @since 3.2
         /// </summary>
-        public enum NumericType
+        public enum NumericType // LUCENENET TODO: Move outside of FieldType class
         {
             /// <summary>
             /// 32-bit integer numeric type </summary>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.Core/Support/StringSupport.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/StringSupport.cs b/src/Lucene.Net.Core/Support/StringSupport.cs
index fc16452..b504fef 100644
--- a/src/Lucene.Net.Core/Support/StringSupport.cs
+++ b/src/Lucene.Net.Core/Support/StringSupport.cs
@@ -54,5 +54,15 @@ namespace Lucene.Net.Support
         {
             return Character.OffsetByCodePoints(seq, index, codePointOffset);
         }
+
+
+        /// <summary>
+        /// Convenience method to wrap a string in a <see cref="StringCharSequenceWrapper"/>
+        /// so a string can be used as <see cref="ICharSequence"/> in .NET.
+        /// </summary>
+        public static ICharSequence ToCharSequence(this string str)
+        {
+            return new StringCharSequenceWrapper(str);
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
new file mode 100644
index 0000000..4a572aa
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
@@ -0,0 +1,37 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Builders
+{
+    /*
+     * 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>
+    /// This interface is used by implementors classes that builds some kind of
+    /// object from a query tree.
+    /// 
+    /// <seealso cref="QueryTreeBuilder"/>
+    /// </summary>
+    public interface IQueryBuilder// <TQuery> // LUCENENET specific - made generic so we don't need to deal with cast
+    {
+        /// <summary>
+        /// Builds some kind of object from a query tree.
+        /// </summary>
+        /// <param name="queryNode">the query tree root node</param>
+        /// <returns>some object generated from the query tree</returns>
+        object Build(IQueryNode queryNode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
new file mode 100644
index 0000000..41304c3
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
@@ -0,0 +1,252 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Standard.Parser;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Builders
+{
+    /*
+     * 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>
+    /// This class should be used when there is a builder for each type of node.
+    /// 
+    /// <para>
+    /// The type of node may be defined in 2 different ways: - by the field name,
+    /// when the node implements the <see cref="IFieldableNode"/> interface - by its class,
+    /// it keeps checking the class and all the interfaces and classes this class
+    /// implements/extends until it finds a builder for that class/interface
+    /// </para>
+    /// <para>
+    /// This class always check if there is a builder for the field name before it
+    /// checks for the node class. So, field name builders have precedence over class
+    /// builders.
+    /// </para>
+    /// <para>
+    /// When a builder is found for a node, it's called and the node is passed to the
+    /// builder. If the returned built object is not <c>null</c>, it's tagged
+    /// on the node using the tag <see cref="QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID"/>.
+    /// </para>
+    /// <para>
+    /// The children are usually built before the parent node. However, if a builder
+    /// associated to a node is an instance of <see cref="QueryTreeBuilder"/>, the node is
+    /// delegated to this builder and it's responsible to build the node and its
+    /// children.
+    /// </para>
+    /// <seealso cref="IQueryBuilder"/>
+    /// </summary>
+    public class QueryTreeBuilder : IQueryBuilder
+    {
+        /**
+   * This tag is used to tag the nodes in a query tree with the built objects
+   * produced from their own associated builder.
+   */
+        public static readonly string QUERY_TREE_BUILDER_TAGID = typeof(QueryTreeBuilder).Name;
+
+        private IDictionary<Type, IQueryBuilder> queryNodeBuilders;
+
+        private IDictionary<string, IQueryBuilder> fieldNameBuilders;
+
+        /**
+         * {@link QueryTreeBuilder} constructor.
+         */
+        public QueryTreeBuilder()
+        {
+            // empty constructor
+        }
+
+        /**
+         * Associates a field name with a builder.
+         * 
+         * @param fieldName the field name
+         * @param builder the builder to be associated
+         */
+        public void SetBuilder(string fieldName, IQueryBuilder builder)
+        {
+
+            if (this.fieldNameBuilders == null)
+            {
+                this.fieldNameBuilders = new Dictionary<string, IQueryBuilder>();
+            }
+
+            this.fieldNameBuilders[fieldName] = builder;
+        }
+
+        /**
+         * Associates a class with a builder
+         * 
+         * @param queryNodeClass the class
+         * @param builder the builder to be associated
+         */
+        public void SetBuilder(Type queryNodeClass,
+            IQueryBuilder builder)
+        {
+
+            if (this.queryNodeBuilders == null)
+            {
+                this.queryNodeBuilders = new Dictionary<Type, IQueryBuilder>();
+            }
+
+            this.queryNodeBuilders[queryNodeClass] = builder;
+
+        }
+
+        private void Process(IQueryNode node)
+        {
+
+            if (node != null)
+            {
+                IQueryBuilder builder = GetBuilder(node);
+
+                if (!(builder is QueryTreeBuilder))
+                {
+                    IList<IQueryNode> children = node.GetChildren();
+
+                    if (children != null)
+                    {
+
+                        foreach (IQueryNode child in children)
+                        {
+                            Process(child);
+                        }
+
+                    }
+
+                }
+
+                ProcessNode(node, builder);
+
+            }
+
+        }
+
+        private IQueryBuilder GetBuilder(IQueryNode node)
+        {
+            IQueryBuilder builder = null;
+
+            if (this.fieldNameBuilders != null && node is IFieldableNode)
+            {
+                string field = ((IFieldableNode)node).Field;
+
+                //if (field != null)
+                //{
+                //    field = field.ToString();
+                //}
+
+                //builder = this.fieldNameBuilders[field];
+                this.fieldNameBuilders.TryGetValue(field, out builder);
+
+            }
+
+            if (builder == null && this.queryNodeBuilders != null)
+            {
+
+                Type clazz = node.GetType();
+
+                do
+                {
+                    builder = GetQueryBuilder(clazz);
+
+                    if (builder == null)
+                    {
+                        Type[] classes = clazz.GetInterfaces();
+
+                        foreach (Type actualClass in classes)
+                        {
+                            builder = GetQueryBuilder(actualClass);
+
+                            if (builder != null)
+                            {
+                                break;
+                            }
+
+                        }
+
+                    }
+
+                } while (builder == null && (clazz = clazz.BaseType) != null);
+
+            }
+
+            return builder;
+
+        }
+
+        private void ProcessNode(IQueryNode node, IQueryBuilder builder)
+        {
+
+            if (builder == null)
+            {
+
+                throw new QueryNodeException(new MessageImpl(
+                    QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, node
+                        .ToQueryString(new EscapeQuerySyntaxImpl()), node.GetType()
+                        .Name));
+
+            }
+
+            object obj = builder.Build(node);
+
+            if (obj != null)
+            {
+                node.SetTag(QUERY_TREE_BUILDER_TAGID, obj);
+            }
+
+        }
+
+        private IQueryBuilder GetQueryBuilder(Type clazz)
+        {
+
+            if (typeof(IQueryNode).IsAssignableFrom(clazz))
+            {
+                IQueryBuilder result;
+                this.queryNodeBuilders.TryGetValue(clazz, out result);
+                return result;
+                //return this.queryNodeBuilders.get(clazz);
+            }
+
+            return null;
+
+        }
+
+        /**
+         * Builds some kind of object from a query tree. Each node in the query tree
+         * is built using an specific builder associated to it.
+         * 
+         * @param queryNode the query tree root node
+         * 
+         * @return the built object
+         * 
+         * @throws QueryNodeException if some node builder throws a
+         *         {@link QueryNodeException} or if there is a node which had no
+         *         builder associated to it
+         */
+
+        public virtual object Build(IQueryNode queryNode)
+        {
+            Process(queryNode);
+
+            return queryNode.GetTag(QUERY_TREE_BUILDER_TAGID);
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
new file mode 100644
index 0000000..41bc528
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
@@ -0,0 +1,114 @@
+\ufeffusing 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.Config
+{
+    /// <summary>
+    /// This class is the base of {@link QueryConfigHandler} and {@link FieldConfig}.
+    /// It has operations to set, unset and get configuration values.
+    /// <para>
+    /// Each configuration is is a key->value pair. The key should be an unique
+    /// {@link ConfigurationKey} instance and it also holds the value's type.
+    /// </para>
+    /// <seealso cref="ConfigurationKey"/>
+    /// </summary>
+    public abstract class AbstractQueryConfig
+    {
+        private readonly IDictionary<ConfigurationKey, object> configMap = new Dictionary<ConfigurationKey, object>();
+
+        internal AbstractQueryConfig()
+        {
+            // although this class is public, it can only be constructed from package
+        }
+
+        /**
+         * Returns the value held by the given key.
+         * 
+         * @param <T> the value's type
+         * 
+         * @param key the key, cannot be <code>null</code>
+         * 
+         * @return the value held by the given key
+         */
+        public T Get<T>(ConfigurationKey<T> key)
+        {
+
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+            object result;
+            this.configMap.TryGetValue(key, out result);
+            return result == null ? default(T) : (T)result;
+            //return (T)this.configMap.get(key);
+
+        }
+
+        /**
+         * Returns true if there is a value set with the given key, otherwise false.
+         * 
+         * @param <T> the value's type
+         * @param key the key, cannot be <code>null</code>
+         * @return true if there is a value set with the given key, otherwise false
+         */
+        public bool has<T>(ConfigurationKey<T> key)
+        {
+
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+
+            return this.configMap.ContainsKey(key);
+
+        }
+
+        /**
+         * Sets a key and its value.
+         * 
+         * @param <T> the value's type
+         * @param key the key, cannot be <code>null</code>
+         * @param value value to set
+         */
+        public void Set<T>(ConfigurationKey<T> key, T value)
+        {
+
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+
+            if (value == null)
+            {
+                Unset(key);
+
+            }
+            else
+            {
+                this.configMap[key] = value;
+            }
+
+        }
+
+        /**
+         * Unsets the given key and its value.
+         * 
+         * @param <T> the value's type
+         * @param key the key
+         * @return true if the key and value was set and removed, otherwise false
+         */
+        public bool Unset<T>(ConfigurationKey<T> key)
+        {
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+
+            return this.configMap.Remove(key);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
new file mode 100644
index 0000000..5a18314
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
@@ -0,0 +1,45 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    /// <summary>
+    /// An instance of this class represents a key that is used to retrieve a value
+    /// from {@link AbstractQueryConfig}. It also holds the value's type, which is
+    /// defined in the generic argument.
+    /// </summary>
+    /// <seealso cref="AbstractQueryConfig"/>
+    /// <typeparam name="T"></typeparam>
+    public sealed class ConfigurationKey<T> : ConfigurationKey
+    {
+        internal ConfigurationKey() { }
+
+        /**
+         * Creates a new instance.
+         * 
+         * @param <T> the value's type
+         * 
+         * @return a new instance
+         */
+        //public static ConfigurationKey<T> NewInstance()
+        //{
+        //    return new ConfigurationKey<T>();
+        //}
+    }
+
+    /// <summary>
+    /// LUCENENET specific class used to access the NewInstance
+    /// static method without referring to the ConfigurationKey{T}'s
+    /// generic closing type.
+    /// </summary>
+    public abstract class ConfigurationKey
+    {
+        public static ConfigurationKey<T> NewInstance<T>()
+        {
+            return new ConfigurationKey<T>();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
new file mode 100644
index 0000000..1633f53
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
@@ -0,0 +1,50 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    /// <summary>
+    /// This class represents a field configuration.
+    /// </summary>
+    public class FieldConfig : AbstractQueryConfig
+    {
+        private string fieldName;
+
+        /**
+         * Constructs a {@link FieldConfig}
+         * 
+         * @param fieldName the field name, it cannot be null
+         * @throws IllegalArgumentException if the field name is null
+         */
+        public FieldConfig(string fieldName)
+        {
+
+            if (fieldName == null)
+            {
+                throw new ArgumentException("field name should not be null!");
+            }
+
+            this.fieldName = fieldName;
+
+        }
+
+        /**
+         * Returns the field name this configuration represents.
+         * 
+         * @return the field name
+         */
+        public string GetField()
+        {
+            return this.fieldName;
+        }
+
+        public override string ToString()
+        {
+            return "<fieldconfig name=\"" + this.fieldName + "\" configurations=\""
+                + base.ToString() + "\"/>";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
new file mode 100644
index 0000000..4a0972d
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
@@ -0,0 +1,24 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    /// <summary>
+    /// This interface should be implemented by classes that wants to listen for
+    /// field configuration requests. The implementation receives a
+    /// {@link FieldConfig} object and may add/change its configuration.
+    /// </summary>
+    /// <seealso cref="FieldConfig"/>
+    /// <seealso cref="QueryConfigHandler"/>
+    public interface IFieldConfigListener
+    {
+        /// <summary>
+        /// This method is called ever time a field configuration is requested.
+        /// </summary>
+        /// <param name="fieldConfig">the field configuration requested, should never be null</param>
+        void BuildFieldConfig(FieldConfig fieldConfig);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
new file mode 100644
index 0000000..ac55d91
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
@@ -0,0 +1,69 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    /// <summary>
+    /// This class can be used to hold any query configuration and no field
+    /// configuration. For field configuration, it creates an empty
+    /// {@link FieldConfig} object and delegate it to field config listeners, 
+    /// these are responsible for setting up all the field configuration.
+    /// <para>
+    /// {@link QueryConfigHandler} should be extended by classes that intends to
+    /// provide configuration to {@link QueryNodeProcessor} objects.
+    /// </para>
+    /// <para>
+    /// The class that extends {@link QueryConfigHandler} should also provide
+    /// {@link FieldConfig} objects for each collection field.
+    /// </para>
+    /// </summary>
+    /// <seealso cref="FieldConfig"/>
+    /// <seealso cref="IFieldConfigListener"/>
+    /// <seealso cref="QueryConfigHandler"/>
+    public abstract class QueryConfigHandler : AbstractQueryConfig
+    {
+        private readonly LinkedList<IFieldConfigListener> listeners = new LinkedList<IFieldConfigListener>();
+
+        /**
+         * Returns an implementation of
+         * {@link FieldConfig} for a specific field name. If the implemented
+         * {@link QueryConfigHandler} does not know a specific field name, it may
+         * return <code>null</code>, indicating there is no configuration for that
+         * field.
+         * 
+         * @param fieldName
+         *          the field name
+         * @return a {@link FieldConfig} object containing the field name
+         *         configuration or <code>null</code>, if the implemented
+         *         {@link QueryConfigHandler} has no configuration for that field
+         */
+        public virtual FieldConfig GetFieldConfig(string fieldName)
+        {
+            FieldConfig fieldConfig = new FieldConfig(StringUtils.ToString(fieldName));
+
+            foreach (IFieldConfigListener listener in this.listeners)
+            {
+                listener.BuildFieldConfig(fieldConfig);
+            }
+
+            return fieldConfig;
+
+        }
+
+        /**
+         * Adds a listener. The added listeners are called in the order they are
+         * added.
+         * 
+         * @param listener
+         *          the listener to be added
+         */
+        public virtual void AddFieldConfigListener(IFieldConfigListener listener)
+        {
+            this.listeners.AddLast(listener);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
new file mode 100644
index 0000000..7378f45
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
@@ -0,0 +1,50 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Messages
+{
+    /// <summary>
+    /// Flexible Query Parser message bundle class
+    /// </summary>
+    public class QueryParserMessages : NLS
+    {
+        private static readonly string BUNDLE_NAME = typeof(QueryParserMessages).Name;
+
+        private QueryParserMessages()
+        {
+            // Do not instantiate
+        }
+
+        static QueryParserMessages()
+        {
+            // register all string ids with NLS class and initialize static string
+            // values
+            NLS.InitializeMessages(BUNDLE_NAME, typeof(QueryParserMessages));
+        }
+
+        // static string must match the strings in the property files.
+        public static string INVALID_SYNTAX;
+        public static string INVALID_SYNTAX_CANNOT_PARSE;
+        public static string INVALID_SYNTAX_FUZZY_LIMITS;
+        public static string INVALID_SYNTAX_FUZZY_EDITS;
+        public static string INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION;
+        public static string INVALID_SYNTAX_ESCAPE_CHARACTER;
+        public static string INVALID_SYNTAX_ESCAPE_NONE_HEX_UNICODE;
+        public static string NODE_ACTION_NOT_SUPPORTED;
+        public static string PARAMETER_VALUE_NOT_SUPPORTED;
+        public static string LUCENE_QUERY_CONVERSION_ERROR;
+        public static string EMPTY_MESSAGE;
+        public static string WILDCARD_NOT_SUPPORTED;
+        public static string TOO_MANY_BOOLEAN_CLAUSES;
+        public static string LEADING_WILDCARD_NOT_ALLOWED;
+        public static string COULD_NOT_PARSE_NUMBER;
+        public static string NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY;
+        public static string UNSUPPORTED_NUMERIC_DATA_TYPE;
+        public static string NUMERIC_CANNOT_BE_EMPTY;
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
new file mode 100644
index 0000000..fa2b365
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
@@ -0,0 +1,69 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link AndQueryNode} represents an AND boolean operation performed on a
+    /// list of nodes.
+    /// </summary>
+    public class AndQueryNode : BooleanQueryNode
+    {
+        /**
+   * @param clauses
+   *          - the query nodes to be and'ed
+   */
+        public AndQueryNode(IList<IQueryNode> clauses)
+            : base(clauses)
+        {
+            if ((clauses == null) || (clauses.Count == 0))
+            {
+                throw new ArgumentException(
+                    "AND query must have at least one clause");
+            }
+        }
+
+
+        public override string ToString()
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "<boolean operation='and'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='and'>");
+            foreach (IQueryNode child in GetChildren())
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+
+            }
+            sb.Append("\n</boolean>");
+            return sb.ToString();
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "";
+
+            StringBuilder sb = new StringBuilder();
+            string filler = "";
+            foreach (IQueryNode child in GetChildren())
+            {
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                filler = " AND ";
+            }
+
+            // in case is root or the parent is a group node avoid parenthesis
+            if ((GetParent() != null && GetParent() is GroupQueryNode)
+        || IsRoot())
+                return sb.ToString();
+            else
+                return "( " + sb.ToString() + " )";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
new file mode 100644
index 0000000..da91a96
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
@@ -0,0 +1,151 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link AnyQueryNode} represents an ANY operator performed on a list of
+    /// nodes.
+    /// </summary>
+    public class AnyQueryNode : AndQueryNode
+    {
+        private string field = null;
+        private int minimumMatchingmElements = 0;
+
+        /**
+         * @param clauses
+         *          - the query nodes to be or'ed
+         */
+        public AnyQueryNode(IList<IQueryNode> clauses, string field,
+            int minimumMatchingElements)
+            : base(clauses)
+        {
+            this.field = field;
+            this.minimumMatchingmElements = minimumMatchingElements;
+
+            if (clauses != null)
+            {
+
+                foreach (IQueryNode clause in clauses)
+                {
+
+                    if (clause is FieldQueryNode)
+                    {
+
+                        if (clause is QueryNodeImpl)
+                        {
+                            ((QueryNodeImpl)clause).toQueryStringIgnoreFields = true;
+                        }
+
+                        if (clause is IFieldableNode)
+                        {
+                            ((IFieldableNode)clause).Field = field;
+                        }
+
+                    }
+                }
+
+            }
+
+        }
+
+        public int GetMinimumMatchingElements()
+        {
+            return this.minimumMatchingmElements;
+        }
+
+        /**
+         * returns null if the field was not specified
+         * 
+         * @return the field
+         */
+        public string GetField()
+        {
+            return this.field;
+        }
+
+        /**
+         * returns - null if the field was not specified
+         * 
+         * @return the field as a String
+         */
+        public string GetFieldAsString()
+        {
+            if (this.field == null)
+                return null;
+            else
+                return this.field.ToString();
+        }
+
+        /**
+         * @param field
+         *          - the field to set
+         */
+        public void setField(string field)
+        {
+            this.field = field;
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            AnyQueryNode clone = (AnyQueryNode)base.CloneTree();
+
+            clone.field = this.field;
+            clone.minimumMatchingmElements = this.minimumMatchingmElements;
+
+            return clone;
+        }
+
+
+        public override string ToString()
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "<any field='" + this.field + "'  matchelements="
+                    + this.minimumMatchingmElements + "/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<any field='" + this.field + "'  matchelements="
+                + this.minimumMatchingmElements + ">");
+            foreach (IQueryNode clause in GetChildren())
+            {
+                sb.Append("\n");
+                sb.Append(clause.ToString());
+            }
+            sb.Append("\n</any>");
+            return sb.ToString();
+        }
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            string anySTR = "ANY " + this.minimumMatchingmElements;
+
+            StringBuilder sb = new StringBuilder();
+            if (GetChildren() == null || GetChildren().Count == 0)
+            {
+                // no childs case
+            }
+            else
+            {
+                string filler = "";
+                foreach (IQueryNode clause in GetChildren())
+                {
+                    sb.Append(filler).Append(clause.ToQueryString(escapeSyntaxParser));
+                    filler = " ";
+                }
+            }
+
+            if (IsDefaultField(this.field))
+            {
+                return "( " + sb.ToString() + " ) " + anySTR;
+            }
+            else
+            {
+                return this.field + ":(( " + sb.ToString() + " ) " + anySTR + ")";
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
new file mode 100644
index 0000000..de68cbd
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
@@ -0,0 +1,77 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link BooleanQueryNode} represents a list of elements which do not have an
+    /// explicit boolean operator defined between them. It can be used to express a
+    /// boolean query that intends to use the default boolean operator.
+    /// </summary>
+    public class BooleanQueryNode : QueryNodeImpl
+    {
+        /**
+   * @param clauses
+   *          - the query nodes to be and'ed
+   */
+        public BooleanQueryNode(IList<IQueryNode> clauses)
+        {
+            SetLeaf(false);
+            Allocate();
+            Set(clauses);
+        }
+
+
+        public override string ToString()
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "<boolean operation='default'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='default'>");
+            foreach (IQueryNode child in GetChildren())
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+            }
+            sb.Append("\n</boolean>");
+            return sb.ToString();
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "";
+
+            StringBuilder sb = new StringBuilder();
+            string filler = "";
+            foreach (IQueryNode child in GetChildren())
+            {
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                filler = " ";
+            }
+
+            // in case is root or the parent is a group node avoid parenthesis
+            if ((GetParent() != null && GetParent() is GroupQueryNode)
+                || IsRoot())
+                return sb.ToString();
+            else
+                return "( " + sb.ToString() + " )";
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            BooleanQueryNode clone = (BooleanQueryNode)base.CloneTree();
+
+            // nothing to do here
+
+            return clone;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
new file mode 100644
index 0000000..0b27d31
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
@@ -0,0 +1,113 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link BoostQueryNode} boosts the QueryNode tree which is under this node.
+    /// So, it must only and always have one child.
+    /// 
+    /// The boost value may vary from 0.0 to 1.0.
+    /// </summary>
+    public class BoostQueryNode : QueryNodeImpl
+    {
+        private float value = 0;
+
+        /**
+         * Constructs a boost node
+         * 
+         * @param query
+         *          the query to be boosted
+         * @param value
+         *          the boost value, it may vary from 0.0 to 1.0
+         */
+        public BoostQueryNode(IQueryNode query, float value)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new MessageImpl(
+                    QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+            }
+
+            this.value = value;
+            SetLeaf(false);
+            Allocate();
+            Add(query);
+        }
+
+        /**
+         * Returns the single child which this node boosts.
+         * 
+         * @return the single child which this node boosts
+         */
+        public IQueryNode GetChild()
+        {
+            IList<IQueryNode> children = GetChildren();
+
+            if (children == null || children.Count == 0)
+            {
+                return null;
+            }
+
+            return children[0];
+
+        }
+
+        /**
+         * Returns the boost value. It may vary from 0.0 to 1.0.
+         * 
+         * @return the boost value
+         */
+        public float GetValue()
+        {
+            return this.value;
+        }
+
+        /**
+         * Returns the boost value parsed to a string.
+         * 
+         * @return the parsed value
+         */
+        private string GetValueString()
+        {
+            float f = this.value;
+            if (f == (long)f)
+                return "" + (long)f;
+            else
+                return "" + f;
+
+        }
+
+
+        public override string ToString()
+        {
+            return "<boost value='" + GetValueString() + "'>" + "\n"
+                + GetChild().ToString() + "\n</boost>";
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChild() == null)
+                return "";
+            return GetChild().ToQueryString(escapeSyntaxParser) + "^"
+                + GetValueString();
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            BoostQueryNode clone = (BoostQueryNode)base.CloneTree();
+
+            clone.value = this.value;
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
new file mode 100644
index 0000000..84694cb
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
@@ -0,0 +1,43 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link DeletedQueryNode} represents a node that was deleted from the query
+    /// node tree. It can be removed from the tree using the
+    /// {@link RemoveDeletedQueryNodesProcessor} processor.
+    /// </summary>
+    public class DeletedQueryNode : QueryNodeImpl
+    {
+        public DeletedQueryNode()
+        {
+            // empty constructor
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            return "[DELETEDCHILD]";
+        }
+
+
+        public override string ToString()
+        {
+            return "<deleted/>";
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            DeletedQueryNode clone = (DeletedQueryNode)base.CloneTree();
+
+            return clone;
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
new file mode 100644
index 0000000..cad1c8a
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
@@ -0,0 +1,241 @@
+\ufeffusing 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
+{
+    /// <summary>
+    /// A {@link FieldQueryNode} represents a element that contains field/text tuple
+    /// </summary>
+    public class FieldQueryNode : QueryNodeImpl, IFieldValuePairQueryNode<string>, ITextableQueryNode
+    {
+        /**
+   * The term's field
+   */
+        protected string field;
+
+        /**
+         * The term's text.
+         */
+        protected ICharSequence text;
+
+        /**
+         * The term's begin position.
+         */
+        protected int begin;
+
+        /**
+         * The term's end position.
+         */
+        protected int end;
+
+        /**
+         * The term's position increment.
+         */
+        protected int positionIncrement;
+
+        /**
+         * @param field
+         *          - field name
+         * @param text
+         *          - value
+         * @param begin
+         *          - position in the query string
+         * @param end
+         *          - position in the query string
+         */
+         // LUCENENET specific overload for passing text as string
+        public FieldQueryNode(string field, string text, int begin,
+            int end)
+            : this(field, new StringCharSequenceWrapper(text), begin, end)
+        {
+        }
+
+        /**
+         * @param field
+         *          - field name
+         * @param text
+         *          - value
+         * @param begin
+         *          - position in the query string
+         * @param end
+         *          - position in the query string
+         */
+        public FieldQueryNode(string field, ICharSequence text, int begin,
+            int end)
+        {
+            this.field = field;
+            this.text = text;
+            this.begin = begin;
+            this.end = end;
+            this.SetLeaf(true);
+
+        }
+
+        protected string GetTermEscaped(IEscapeQuerySyntax escaper)
+        {
+            return escaper.Escape(this.text, CultureInfo.InvariantCulture /*Locale.getDefault()*/, EscapeQuerySyntax.Type.NORMAL).ToString();
+        }
+
+        protected string GetTermEscapeQuoted(IEscapeQuerySyntax escaper)
+        {
+            return escaper.Escape(this.text, CultureInfo.InvariantCulture /*Locale.getDefault()*/, EscapeQuerySyntax.Type.STRING).ToString();
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            if (IsDefaultField(this.field))
+            {
+                return GetTermEscaped(escaper);
+            }
+            else
+            {
+                return this.field + ":" + GetTermEscaped(escaper);
+            }
+        }
+
+
+        public override string ToString()
+        {
+            return "<field start='" + this.begin + "' end='" + this.end + "' field='"
+                + this.field + "' text='" + this.text + "'/>";
+        }
+
+        /**
+         * @return the term
+         */
+        public string GetTextAsString()
+        {
+            if (this.text == null)
+                return null;
+            else
+                return this.text.ToString();
+        }
+
+        /**
+         * returns null if the field was not specified in the query string
+         * 
+         * @return the field
+         */
+        public string GetFieldAsString()
+        {
+            if (this.field == null)
+                return null;
+            else
+                return this.field.ToString();
+        }
+
+        public int GetBegin()
+        {
+            return this.begin;
+        }
+
+        public void SetBegin(int begin)
+        {
+            this.begin = begin;
+        }
+
+        public int GetEnd()
+        {
+            return this.end;
+        }
+
+        public void setEnd(int end)
+        {
+            this.end = end;
+        }
+
+        public virtual string Field
+        {
+            get { return this.field; }
+            set { this.field = value; }
+        }
+
+        //      @Override
+        //public CharSequence getField()
+        //      {
+        //          return this.field;
+        //      }
+
+        //      @Override
+        //public void setField(CharSequence field)
+        //      {
+        //          this.field = field;
+        //      }
+
+        public int GetPositionIncrement()
+        {
+            return this.positionIncrement;
+        }
+
+        public void SetPositionIncrement(int pi)
+        {
+            this.positionIncrement = pi;
+        }
+
+        public virtual ICharSequence Text
+        {
+            get { return this.text; }
+            set { this.text = value; }
+        }
+
+        ///**
+        // * Returns the term.
+        // * 
+        // * @return The "original" form of the term.
+        // */
+
+        //public override string GetText()
+        //{
+        //    return this.text;
+        //}
+
+        ///**
+        // * @param text
+        // *          the text to set
+        // */
+
+        //public override void SetText(string text)
+        //{
+        //    this.text = text;
+        //}
+
+
+        public override IQueryNode CloneTree()
+        {
+            FieldQueryNode fqn = (FieldQueryNode)base.CloneTree();
+            fqn.begin = this.begin;
+            fqn.end = this.end;
+            fqn.field = this.field;
+            fqn.text = this.text;
+            fqn.positionIncrement = this.positionIncrement;
+            fqn.toQueryStringIgnoreFields = this.toQueryStringIgnoreFields;
+
+            return fqn;
+
+        }
+
+        public virtual string Value
+        {
+            get { return Text.ToString(); }
+            set { Text = new StringCharSequenceWrapper(value); }
+        }
+
+        //public override string GetValue()
+        //{
+        //    return GetText();
+        //}
+
+
+        //public override void SetValue(string value)
+        //{
+        //    SetText(value);
+        //}
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
new file mode 100644
index 0000000..d6d4e32
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
@@ -0,0 +1,19 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// This interface should be implemented by {@link QueryNode} that holds a field
+    /// and an arbitrary value.
+    /// </summary>
+    /// <seealso cref="IFieldableNode"/>
+    /// <seealso cref="IValueQueryNode{T}"/>
+    /// <typeparam name="T"></typeparam>
+    public interface IFieldValuePairQueryNode<T> : IFieldableNode, IValueQueryNode<T>
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
new file mode 100644
index 0000000..e9b6439
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
@@ -0,0 +1,38 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A query node implements {@link FieldableNode} interface to indicate that its
+    /// children and itself are associated to a specific field.
+    /// 
+    /// If it has any children which also implements this interface, it must ensure
+    /// the children are associated to the same field.
+    /// </summary>
+    public interface IFieldableNode : IQueryNode
+    {
+        /// <summary>
+        /// Gets or Sets the field associated to the node and every node under it.
+        /// </summary>
+        string Field { get; set; }
+
+        //     /**
+        //* Returns the field associated to the node and every node under it.
+        //* 
+        //* @return the field name
+        //*/
+        //     string GetField(); 
+
+        //     /**
+        //      * Associates the node to a field.
+        //      * 
+        //      * @param fieldName
+        //      *          the field name
+        //      */
+        //     void SetField(string fieldName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
new file mode 100644
index 0000000..8f64793
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
@@ -0,0 +1,119 @@
+\ufeffusing 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
+{
+    /// <summary>
+    /// A {@link FuzzyQueryNode} represents a element that contains
+    /// field/text/similarity tuple
+    /// </summary>
+    public class FuzzyQueryNode : FieldQueryNode
+    {
+        private float similarity;
+
+        private int prefixLength;
+
+        /**
+         * @param field
+         *          Name of the field query will use.
+         * @param termStr
+         *          Term token to use for building term for the query
+         */
+        /**
+         * @param field
+         *          - Field name
+         * @param term
+         *          - Value
+         * @param minSimilarity
+         *          - similarity value
+         * @param begin
+         *          - position in the query string
+         * @param end
+         *          - position in the query string
+         */
+         // LUCENENET specific overload for string term
+        public FuzzyQueryNode(string field, string term,
+            float minSimilarity, int begin, int end)
+            : this(field, term.ToCharSequence(), minSimilarity, begin, end)
+        {
+        }
+
+        /**
+         * @param field
+         *          - Field name
+         * @param term
+         *          - Value
+         * @param minSimilarity
+         *          - similarity value
+         * @param begin
+         *          - position in the query string
+         * @param end
+         *          - position in the query string
+         */
+        public FuzzyQueryNode(string field, ICharSequence term,
+            float minSimilarity, int begin, int end)
+            : base(field, term, begin, end)
+        {
+            this.similarity = minSimilarity;
+            SetLeaf(true);
+        }
+
+        public void SetPrefixLength(int prefixLength)
+        {
+            this.prefixLength = prefixLength;
+        }
+
+        public int GetPrefixLength()
+        {
+            return this.prefixLength;
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            if (IsDefaultField(this.field))
+            {
+                return GetTermEscaped(escaper) + "~" + this.similarity;
+            }
+            else
+            {
+                return this.field + ":" + GetTermEscaped(escaper) + "~" + this.similarity;
+            }
+        }
+
+
+        public override string ToString()
+        {
+            return "<fuzzy field='" + this.field + "' similarity='" + this.similarity
+                + "' term='" + this.text + "'/>";
+        }
+
+        public void SetSimilarity(float similarity)
+        {
+            this.similarity = similarity;
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            FuzzyQueryNode clone = (FuzzyQueryNode)base.CloneTree();
+
+            clone.similarity = this.similarity;
+
+            return clone;
+        }
+
+        /**
+         * @return the similarity
+         */
+        public float GetSimilarity()
+        {
+            return this.similarity;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
new file mode 100644
index 0000000..246b30c
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
@@ -0,0 +1,73 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link GroupQueryNode} represents a location where the original user typed
+    /// real parenthesis on the query string. This class is useful for queries like:
+    /// a) a AND b OR c b) ( a AND b) OR c
+    /// 
+    /// Parenthesis might be used to define the boolean operation precedence.
+    /// </summary>
+    public class GroupQueryNode : QueryNodeImpl
+    {
+        /**
+   * This QueryNode is used to identify parenthesis on the original query string
+   */
+        public GroupQueryNode(IQueryNode query)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new MessageImpl(
+                    QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+            }
+
+            Allocate();
+            SetLeaf(false);
+            Add(query);
+        }
+
+        public IQueryNode GetChild()
+        {
+            return GetChildren()[0];
+        }
+
+
+        public override string ToString()
+        {
+            return "<group>" + "\n" + GetChild().ToString() + "\n</group>";
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChild() == null)
+                return "";
+
+            return "( " + GetChild().ToQueryString(escapeSyntaxParser) + " )";
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            GroupQueryNode clone = (GroupQueryNode)base.CloneTree();
+
+            return clone;
+        }
+
+        public void setChild(IQueryNode child)
+        {
+            List<IQueryNode> list = new List<IQueryNode>();
+            list.Add(child);
+            this.Set(list);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
new file mode 100644
index 0000000..0a0ffa8
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
@@ -0,0 +1,43 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link MatchAllDocsQueryNode} indicates that a query node tree or subtree
+    /// will match all documents if executed in the index.
+    /// </summary>
+    public class MatchAllDocsQueryNode : QueryNodeImpl
+    {
+        public MatchAllDocsQueryNode()
+        {
+            // empty constructor
+        }
+
+
+        public override string ToString()
+        {
+            return "<matchAllDocs field='*' term='*'/>";
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return "*:*";
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            MatchAllDocsQueryNode clone = (MatchAllDocsQueryNode)base.CloneTree();
+
+            // nothing to clone
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
new file mode 100644
index 0000000..e8cfadd
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
@@ -0,0 +1,25 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link MatchNoDocsQueryNode} indicates that a query node tree or subtree
+    /// will not match any documents if executed in the index.
+    /// </summary>
+    public class MatchNoDocsQueryNode : DeletedQueryNode
+    {
+        public MatchNoDocsQueryNode()
+        {
+            // empty constructor
+        }
+
+        public override string ToString()
+        {
+            return "<matchNoDocsQueryNode/>";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
new file mode 100644
index 0000000..900f117
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
@@ -0,0 +1,172 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link ModifierQueryNode} indicates the modifier value (+,-,?,NONE) for
+    /// each term on the query string. For example "+t1 -t2 t3" will have a tree of:
+    /// <blockquote>
+    /// &lt;BooleanQueryNode&gt; &lt;ModifierQueryNode modifier="MOD_REQ"&gt; &lt;t1/&gt;
+    /// &lt;/ModifierQueryNode&gt; &lt;ModifierQueryNode modifier="MOD_NOT"&gt; &lt;t2/&gt;
+    /// &lt;/ModifierQueryNode&gt; &lt;t3/&gt; &lt;/BooleanQueryNode&gt;
+    /// </blockquote>
+    /// </summary>
+    public class ModifierQueryNode : QueryNodeImpl
+    {
+        
+        // LUCENENET NOTE: Modifier enum moved outside of this class
+
+
+
+        private Modifier modifier = Modifier.MOD_NONE;
+
+        /**
+         * Used to store the modifier value on the original query string
+         * 
+         * @param query
+         *          - QueryNode subtree
+         * @param mod
+         *          - Modifier Value
+         */
+        public ModifierQueryNode(IQueryNode query, Modifier mod)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new MessageImpl(
+                    QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+            }
+
+            Allocate();
+            SetLeaf(false);
+            Add(query);
+            this.modifier = mod;
+        }
+
+        public IQueryNode GetChild()
+        {
+            return GetChildren()[0];
+        }
+
+        public Modifier GetModifier()
+        {
+            return this.modifier;
+        }
+
+
+        public override string ToString()
+        {
+            return "<modifier operation='" + this.modifier.ToString() + "'>" + "\n"
+                + GetChild().ToString() + "\n</modifier>";
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChild() == null)
+                return "";
+
+            String leftParenthensis = "";
+            String rightParenthensis = "";
+
+            if (GetChild() != null && GetChild() is ModifierQueryNode)
+            {
+                leftParenthensis = "(";
+                rightParenthensis = ")";
+            }
+
+            if (GetChild() is BooleanQueryNode)
+            {
+                return this.modifier.ToLargeString() + leftParenthensis
+                    + GetChild().ToQueryString(escapeSyntaxParser) + rightParenthensis;
+            }
+            else
+            {
+                return this.modifier.ToDigitString() + leftParenthensis
+                    + GetChild().ToQueryString(escapeSyntaxParser) + rightParenthensis;
+            }
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            ModifierQueryNode clone = (ModifierQueryNode)base.CloneTree();
+
+            clone.modifier = this.modifier;
+
+            return clone;
+        }
+
+        public void setChild(IQueryNode child)
+        {
+            List<IQueryNode> list = new List<IQueryNode>();
+            list.Add(child);
+            this.Set(list);
+        }
+    }
+
+    /**
+   * Modifier type: such as required (REQ), prohibited (NOT)
+   */
+    public enum Modifier
+    {
+        MOD_NONE,
+        MOD_NOT,
+        MOD_REQ
+    }
+
+    public static class ModifierExtensions
+    {
+        // LUCENENET TODO: Work out how to override ToString() (or test this) so this string can be made
+        //public static string ToString()
+        //{
+        //    switch (this)
+        //    {
+        //        case MOD_NONE:
+        //            return "MOD_NONE";
+        //        case MOD_NOT:
+        //            return "MOD_NOT";
+        //        case MOD_REQ:
+        //            return "MOD_REQ";
+        //    }
+        //    // this code is never executed
+        //    return "MOD_DEFAULT";
+        //}
+
+        public static string ToDigitString(this Modifier modifier)
+        {
+            switch (modifier)
+            {
+                case Modifier.MOD_NONE:
+                    return "";
+                case Modifier.MOD_NOT:
+                    return "-";
+                case Modifier.MOD_REQ:
+                    return "+";
+            }
+            // this code is never executed
+            return "";
+        }
+
+        public static string ToLargeString(this Modifier modifier)
+        {
+            switch (modifier)
+            {
+                case Modifier.MOD_NONE:
+                    return "";
+                case Modifier.MOD_NOT:
+                    return "NOT ";
+                case Modifier.MOD_REQ:
+                    return "+";
+            }
+            // this code is never executed
+            return "";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
new file mode 100644
index 0000000..d321df8
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
@@ -0,0 +1,42 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link NoTokenFoundQueryNode} is used if a term is convert into no tokens
+    /// by the tokenizer/lemmatizer/analyzer (null).
+    /// </summary>
+    public class NoTokenFoundQueryNode : DeletedQueryNode
+    {
+        //public NoTokenFoundQueryNode()
+        //{
+        //}
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            return "[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/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
new file mode 100644
index 0000000..fcae411
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
@@ -0,0 +1,75 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link OpaqueQueryNode} is used for specify values that are not supposed to
+    /// be parsed by the parser. For example: and XPATH query in the middle of a
+    /// query string a b @xpath:'/bookstore/book[1]/title' c d
+    /// </summary>
+    public class OpaqueQueryNode : QueryNodeImpl
+    {
+        private string schema = null;
+
+        private string value = null;
+
+        /**
+         * @param schema
+         *          - schema identifier
+         * @param value
+         *          - value that was not parsed
+         */
+        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 string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return "@" + this.schema + ":'" + this.value + "'";
+        }
+
+
+        public override IQueryNode CloneTree()
+        {
+            OpaqueQueryNode clone = (OpaqueQueryNode)base.CloneTree();
+
+            clone.schema = this.schema;
+            clone.value = this.value;
+
+            return clone;
+        }
+
+        /**
+         * @return the schema
+         */
+        public string GetSchema()
+        {
+            return this.schema;
+        }
+
+        /**
+         * @return the value
+         */
+        public string GetValue()
+        {
+            return this.value;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
new file mode 100644
index 0000000..edd3577
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
@@ -0,0 +1,68 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    /// <summary>
+    /// A {@link OrQueryNode} represents an OR boolean operation performed on a list
+    /// of nodes.
+    /// </summary>
+    public class OrQueryNode : BooleanQueryNode
+    {
+        /**
+   * @param clauses
+   *          - the query nodes to be or'ed
+   */
+        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 (GetChildren() == null || GetChildren().Count == 0)
+                return "<boolean operation='or'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='or'>");
+            foreach (IQueryNode child in GetChildren())
+            {
+                sb.Append("\n");
+                sb.Append(child.ToString());
+
+            }
+            sb.Append("\n</boolean>");
+            return sb.ToString();
+        }
+
+
+        public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (GetChildren() == null || GetChildren().Count == 0)
+                return "";
+
+            StringBuilder sb = new StringBuilder();
+            string filler = "";
+            for (IEnumerator<IQueryNode> it = GetChildren().GetEnumerator(); it.MoveNext();)
+            {
+                sb.Append(filler).Append(it.Current.ToQueryString(escapeSyntaxParser));
+                filler = " OR ";
+            }
+
+            // in case is root or the parent is a group node avoid parenthesis
+            if ((GetParent() != null && GetParent() is GroupQueryNode)
+                || IsRoot())
+                return sb.ToString();
+            else
+                return "( " + sb.ToString() + " )";
+        }
+    }
+}