lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mhern...@apache.org
Subject [10/16] git commit: Work in progress on QueryParsers.Flexible
Date Sun, 06 Oct 2013 23:47:58 GMT
Work in progress 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/c9e9c54b
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/c9e9c54b
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/c9e9c54b

Branch: refs/heads/branch_4x
Commit: c9e9c54b0236f506032d4555eb1988c459c1d947
Parents: 2245f83
Author: Paul Irwin <paulirwin@gmail.com>
Authored: Thu Oct 3 15:46:58 2013 -0400
Committer: Paul Irwin <paulirwin@gmail.com>
Committed: Sat Oct 5 16:37:27 2013 -0400

----------------------------------------------------------------------
 .../QueryParsers/Contrib.QueryParsers.csproj    |  42 ++++
 .../Flexible/Core/Builders/IQueryBuilder.cs     |  14 ++
 .../Flexible/Core/Builders/QueryTreeBuilder.cs  | 146 ++++++++++++++
 .../Flexible/Core/Config/AbstractQueryConfig.cs |  66 ++++++
 .../Flexible/Core/Config/ConfigurationKey.cs    |  31 +++
 .../Flexible/Core/Config/FieldConfig.cs         |  34 ++++
 .../Core/Config/IFieldConfigListener.cs         |  13 ++
 .../Flexible/Core/Config/QueryConfigHandler.cs  |  31 +++
 .../Core/Messages/QueryParserMessages.cs        |  46 +++++
 .../Flexible/Core/Nodes/AndQueryNode.cs         |  62 ++++++
 .../Flexible/Core/Nodes/AnyQueryNode.cs         | 129 ++++++++++++
 .../Flexible/Core/Nodes/BooleanQueryNode.cs     |  64 ++++++
 .../Flexible/Core/Nodes/BoostQueryNode.cs       |  87 ++++++++
 .../Flexible/Core/Nodes/DeletedQueryNode.cs     |  35 ++++
 .../Flexible/Core/Nodes/FieldQueryNode.cs       | 129 ++++++++++++
 .../Flexible/Core/Nodes/FuzzyQueryNode.cs       |  62 ++++++
 .../Flexible/Core/Nodes/GroupQueryNode.cs       |  61 ++++++
 .../Core/Nodes/IFieldValuePairQueryNode.cs      |  12 ++
 .../Flexible/Core/Nodes/IFieldableNode.cs       |  13 ++
 .../Flexible/Core/Nodes/IQueryNode.cs           |  39 ++++
 .../Flexible/Core/Nodes/ITextableQueryNode.cs   |  13 ++
 .../Flexible/Core/Nodes/IValueQueryNode.cs      |  12 ++
 .../Core/Nodes/MatchAllDocsQueryNode.cs         |  37 ++++
 .../Flexible/Core/Nodes/MatchNoDocsQueryNode.cs |  21 ++
 .../Flexible/Core/Nodes/ModifierQueryNode.cs    | 132 ++++++++++++
 .../Flexible/Core/Nodes/QueryNode.cs            | 202 +++++++++++++++++++
 .../Flexible/Core/Parser/IEscapeQuerySyntax.cs  |  29 +++
 .../Flexible/Core/Parser/ISyntaxParser.cs       |  15 ++
 .../Flexible/Core/QueryNodeError.cs             |  36 ++++
 .../Flexible/Core/QueryNodeException.cs         |  61 ++++++
 .../Flexible/Core/QueryNodeParseException.cs    |  73 +++++++
 .../Flexible/Core/Util/QueryNodeOperation.cs    |  67 ++++++
 .../Flexible/Core/Util/StringUtils.cs           |  23 +++
 .../Flexible/Core/Util/UnescapedCharSequence.cs | 139 +++++++++++++
 .../QueryParsers/Flexible/Messages/IMessage.cs  |  20 ++
 .../Flexible/Messages/INLSException.cs          |  13 ++
 .../QueryParsers/Flexible/Messages/Message.cs   |  61 ++++++
 .../QueryParsers/Flexible/Messages/NLS.cs       | 180 +++++++++++++++++
 .../Standard/Builders/AnyQueryNodeBuilder.cs    |  12 ++
 .../Standard/Builders/IStandardQueryBuilder.cs  |  16 ++
 .../Flexible/Standard/QueryParserUtil.cs        | 100 +++++++++
 .../Flexible/Standard/StandardQueryParser.cs    |  12 ++
 42 files changed, 2390 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
index 2d29fad..2fcb669 100644
--- a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
+++ b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
@@ -56,6 +56,45 @@
     <Compile Include="Ext\ExtensionQuery.cs" />
     <Compile Include="Ext\Extensions.cs" />
     <Compile Include="Ext\ParserExtension.cs" />
+    <Compile Include="Flexible\Core\Builders\IQueryBuilder.cs" />
+    <Compile Include="Flexible\Core\Builders\QueryTreeBuilder.cs" />
+    <Compile Include="Flexible\Core\Config\AbstractQueryConfig.cs" />
+    <Compile Include="Flexible\Core\Config\ConfigurationKey.cs" />
+    <Compile Include="Flexible\Core\Config\FieldConfig.cs" />
+    <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\ITextableQueryNode.cs" />
+    <Compile Include="Flexible\Core\Messages\QueryParserMessages.cs" />
+    <Compile Include="Flexible\Core\Nodes\AndQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\AnyQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\BooleanQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\BoostQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\DeletedQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\FieldQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\GroupQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\IFieldableNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\IFieldValuePairQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\IQueryNode.cs" />
+    <Compile Include="Flexible\Core\Nodes\IValueQueryNode.cs" />
+    <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\QueryNode.cs" />
+    <Compile Include="Flexible\Core\Parser\IEscapeQuerySyntax.cs" />
+    <Compile Include="Flexible\Core\Parser\ISyntaxParser.cs" />
+    <Compile Include="Flexible\Core\QueryNodeError.cs" />
+    <Compile Include="Flexible\Core\QueryNodeException.cs" />
+    <Compile Include="Flexible\Core\QueryNodeParseException.cs" />
+    <Compile Include="Flexible\Core\Util\QueryNodeOperation.cs" />
+    <Compile Include="Flexible\Core\Util\StringUtils.cs" />
+    <Compile Include="Flexible\Core\Util\UnescapedCharSequence.cs" />
+    <Compile Include="Flexible\Messages\IMessage.cs" />
+    <Compile Include="Flexible\Messages\INLSException.cs" />
+    <Compile Include="Flexible\Messages\Message.cs" />
+    <Compile Include="Flexible\Messages\NLS.cs" />
+    <Compile Include="Flexible\Standard\Builders\AnyQueryNodeBuilder.cs" />
+    <Compile Include="Flexible\Standard\Builders\IStandardQueryBuilder.cs" />
     <Compile Include="Flexible\Standard\ICommonQueryParserConfiguration.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
@@ -65,6 +104,9 @@
       <Name>Lucene.Net</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Flexible\Precedence\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Builders/IQueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Builders/IQueryBuilder.cs b/src/contrib/QueryParsers/Flexible/Core/Builders/IQueryBuilder.cs
new file mode 100644
index 0000000..4139823
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Builders/IQueryBuilder.cs
@@ -0,0 +1,14 @@
+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.Builders
+{
+    public interface IQueryBuilder
+    {
+        object Build(IQueryNode queryNode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Builders/QueryTreeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Builders/QueryTreeBuilder.cs b/src/contrib/QueryParsers/Flexible/Core/Builders/QueryTreeBuilder.cs
new file mode 100644
index 0000000..2d0c39b
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Builders/QueryTreeBuilder.cs
@@ -0,0 +1,146 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+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.Builders
+{
+    public class QueryTreeBuilder : IQueryBuilder
+    {
+        public static readonly string QUERY_TREE_BUILDER_TAGID = typeof(QueryTreeBuilder).FullName;
+
+        private HashMap<Type, IQueryBuilder> queryNodeBuilders;
+
+        private HashMap<string, IQueryBuilder> fieldNameBuilders;
+
+        public QueryTreeBuilder()
+        {
+            // empty constructor
+        }
+
+        public void SetBuilder(string fieldName, IQueryBuilder builder)
+        {
+            if (this.fieldNameBuilders == null)
+            {
+                this.fieldNameBuilders = new HashMap<String, IQueryBuilder>();
+            }
+
+            this.fieldNameBuilders[fieldName] = builder;
+        }
+
+        public void SetBuilder(Type queryNodeClass, IQueryBuilder builder)
+        {
+            if (this.queryNodeBuilders == null)
+            {
+                this.queryNodeBuilders = new HashMap<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.Children;
+
+                    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;
+
+
+                builder = this.fieldNameBuilders[field];
+
+            }
+
+            if (builder == null && this.queryNodeBuilders != null)
+            {
+                Type clazz = node.GetType();
+
+                do
+                {
+                    builder = GetQueryBuilder(clazz);
+
+                    if (builder == null)
+                    {
+                        Type[] classes = node.GetType().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 Message(
+                    QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, node
+                        .ToQueryString(new EscapeQuerySyntax()), node.GetType().FullName));
+            }
+
+            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))
+            {
+                return this.queryNodeBuilders[clazz];
+            }
+
+            return null;
+        }
+
+        public object Build(IQueryNode queryNode)
+        {
+            Process(queryNode);
+
+            return queryNode.GetTag(QUERY_TREE_BUILDER_TAGID);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Config/AbstractQueryConfig.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Config/AbstractQueryConfig.cs b/src/contrib/QueryParsers/Flexible/Core/Config/AbstractQueryConfig.cs
new file mode 100644
index 0000000..17283f5
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Config/AbstractQueryConfig.cs
@@ -0,0 +1,66 @@
+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.Config
+{
+    public abstract class AbstractQueryConfig
+    {
+        private readonly HashMap<ConfigurationKey, object> configMap = new HashMap<ConfigurationKey, object>();
+
+        internal AbstractQueryConfig()
+        {
+            // although this class is public, it can only be constructed from package
+        }
+
+        public T Get<T>(ConfigurationKey<T> key)
+        {
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+
+            return (T)this.configMap[key];
+        }
+
+        public bool Has<T>(ConfigurationKey<T> key)
+        {
+            if (key == null)
+            {
+                throw new ArgumentException("key cannot be null!");
+            }
+
+            return this.configMap.ContainsKey(key);
+        }
+
+        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;
+            }
+        }
+
+        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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Config/ConfigurationKey.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Config/ConfigurationKey.cs b/src/contrib/QueryParsers/Flexible/Core/Config/ConfigurationKey.cs
new file mode 100644
index 0000000..1be6b7c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Config/ConfigurationKey.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    public sealed class ConfigurationKey<T> : ConfigurationKey
+    {
+        internal ConfigurationKey() 
+        {
+            this.t = typeof(T);
+        }        
+    }
+
+    public class ConfigurationKey
+    {
+        protected Type t;
+
+        public static ConfigurationKey<T> NewInstance<T>()
+        {
+            return new ConfigurationKey<T>();
+        }
+
+        public override int GetHashCode()
+        {
+            return t.GetHashCode();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Config/FieldConfig.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Config/FieldConfig.cs b/src/contrib/QueryParsers/Flexible/Core/Config/FieldConfig.cs
new file mode 100644
index 0000000..6322011
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Config/FieldConfig.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    public class FieldConfig : AbstractQueryConfig
+    {
+        private string fieldName;
+
+        public FieldConfig(string fieldName)
+        {
+            if (fieldName == null)
+            {
+                throw new ArgumentException("field name should not be null!");
+            }
+
+            this.fieldName = fieldName;
+        }
+
+        public string Field
+        {
+            get { 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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Config/IFieldConfigListener.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Config/IFieldConfigListener.cs b/src/contrib/QueryParsers/Flexible/Core/Config/IFieldConfigListener.cs
new file mode 100644
index 0000000..f88fd28
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Config/IFieldConfigListener.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+    public interface IFieldConfigListener
+    {
+        void BuildFieldConfig(FieldConfig fieldConfig);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Config/QueryConfigHandler.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Config/QueryConfigHandler.cs b/src/contrib/QueryParsers/Flexible/Core/Config/QueryConfigHandler.cs
new file mode 100644
index 0000000..6851997
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Config/QueryConfigHandler.cs
@@ -0,0 +1,31 @@
+using 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
+{
+    public abstract class QueryConfigHandler : AbstractQueryConfig
+    {
+        private readonly LinkedList<IFieldConfigListener> listeners = new LinkedList<IFieldConfigListener>();
+
+        public FieldConfig GetFieldConfig(string fieldName)
+        {
+            FieldConfig fieldConfig = new FieldConfig(StringUtils.ToString(fieldName));
+
+            foreach (IFieldConfigListener listener in this.listeners)
+            {
+                listener.BuildFieldConfig(fieldConfig);
+            }
+
+            return fieldConfig;
+        }
+
+        public void AddFieldConfigListener(IFieldConfigListener listener)
+        {
+            this.listeners.AddLast(listener);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Messages/QueryParserMessages.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Messages/QueryParserMessages.cs b/src/contrib/QueryParsers/Flexible/Core/Messages/QueryParserMessages.cs
new file mode 100644
index 0000000..8d5fa23
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Messages/QueryParserMessages.cs
@@ -0,0 +1,46 @@
+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.Messages
+{
+    public class QueryParserMessages : NLS
+    {
+        private static readonly string BUNDLE_NAME = typeof(QueryParserMessages).FullName;
+
+        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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/AndQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/AndQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/AndQueryNode.cs
new file mode 100644
index 0000000..e397b06
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/AndQueryNode.cs
@@ -0,0 +1,62 @@
+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 AndQueryNode : BooleanQueryNode
+    {
+        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 (Children == null || Children.Count == 0)
+                return "<boolean operation='and'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='and'>");
+            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 = " AND ";
+            }
+
+            // 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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/AnyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/AnyQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/AnyQueryNode.cs
new file mode 100644
index 0000000..4262d02
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/AnyQueryNode.cs
@@ -0,0 +1,129 @@
+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 AnyQueryNode : AndQueryNode
+    {
+        private string field = null;
+        private int minimumMatchingmElements = 0;
+
+        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 QueryNode)
+                        {
+                            ((QueryNode)clause).toQueryStringIgnoreFields = true;
+                        }
+
+                        if (clause is IFieldableNode)
+                        {
+                            ((IFieldableNode)clause).Field = field;
+                        }
+                    }
+                }
+            }
+        }
+
+        public int MinimumMatchingElements
+        {
+            get
+            {
+                return this.minimumMatchingmElements;
+            }
+        }
+
+        public string Field
+        {
+            get
+            {
+                return this.field;
+            }
+            set
+            {
+                this.field = value;
+            }
+        }
+
+        public string FieldAsString
+        {
+            get
+            {
+                if (this.field == null)
+                    return null;
+                else
+                    return this.field.ToString();
+            }
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            AnyQueryNode clone = (AnyQueryNode)base.CloneTree();
+
+            clone.field = this.field;
+            clone.minimumMatchingmElements = this.minimumMatchingmElements;
+
+            return clone;
+        }
+
+        public override string ToString()
+        {
+            if (Children == null || Children.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 Children)
+            {
+                sb.Append("\n");
+                sb.Append(clause.ToString());
+            }
+            sb.Append("\n</any>");
+            return sb.ToString();
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            String anySTR = "ANY " + this.minimumMatchingmElements;
+
+            StringBuilder sb = new StringBuilder();
+            if (Children == null || Children.Count == 0)
+            {
+                // no childs case
+            }
+            else
+            {
+                String filler = "";
+                foreach (IQueryNode clause in Children)
+                {
+                    sb.Append(filler).Append(clause.ToQueryString(escapeSyntaxParser));
+                    filler = " ";
+                }
+            }
+
+            if (IsDefaultField(this.field))
+            {
+                return new StringCharSequenceWrapper("( " + sb.ToString() + " ) " + anySTR);
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.field + ":(( " + sb.ToString() + " ) " + anySTR + ")");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/BooleanQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/BooleanQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/BooleanQueryNode.cs
new file mode 100644
index 0000000..1521b0a
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/BooleanQueryNode.cs
@@ -0,0 +1,64 @@
+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 BooleanQueryNode : QueryNode
+    {
+        public BooleanQueryNode(IList<IQueryNode> clauses)
+        {
+            SetLeaf(false);
+            Allocate();
+            Set(clauses);
+        }
+
+        public override string ToString()
+        {
+            if (Children == null || Children.Count == 0)
+                return "<boolean operation='default'/>";
+            StringBuilder sb = new StringBuilder();
+            sb.Append("<boolean operation='default'>");
+            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 (QueryNode child in Children)
+            {
+                sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+                filler = " ";
+            }
+
+            // 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() + " )");
+        }
+
+        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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/BoostQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/BoostQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/BoostQueryNode.cs
new file mode 100644
index 0000000..e1d2c6b
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/BoostQueryNode.cs
@@ -0,0 +1,87 @@
+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 BoostQueryNode : QueryNode
+    {
+        private float value = 0;
+
+        public BoostQueryNode(IQueryNode query, float 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
+            {
+                IList<IQueryNode> children = Children;
+
+                if (children == null || children.Count == 0)
+                {
+                    return null;
+                }
+
+                return children[0];
+            }
+        }
+
+        public float Value
+        {
+            get
+            {
+                return this.value;
+            }
+        }
+
+        private string ValueString
+        {
+            get
+            {
+                if (value == (long)value)
+                    return "" + (long)value;
+                else
+                    return "" + value;
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<boost value='" + ValueString + "'>" + "\n"
+                + Child.ToString() + "\n</boost>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Child == null)
+                return new StringCharSequenceWrapper("");
+
+            return new StringCharSequenceWrapper(Child.ToQueryString(escapeSyntaxParser) + "^" + ValueString);
+        }
+
+        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/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/DeletedQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/DeletedQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/DeletedQueryNode.cs
new file mode 100644
index 0000000..75ce153
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/DeletedQueryNode.cs
@@ -0,0 +1,35 @@
+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 DeletedQueryNode : QueryNode
+    {
+        public DeletedQueryNode()
+        {
+            // empty constructor
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return new StringCharSequenceWrapper("[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/c9e9c54b/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
new file mode 100644
index 0000000..41d9ceb
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
@@ -0,0 +1,129 @@
+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 FieldQueryNode : QueryNode, IFieldValuePairQueryNode<string>, ITextableQueryNode
+    {
+        protected string field;
+
+        protected string text;
+
+        protected int begin;
+
+        protected int end;
+
+        protected int positionIncrement;
+
+        public FieldQueryNode(string field, string text, int begin, int end)
+        {
+            this.field = field;
+            this.text = text;
+            this.begin = begin;
+            this.end = end;
+            this.SetLeaf(true);
+        }
+
+        protected ICharSequence GetTermEscaped(IEscapeQuerySyntax escaper)
+        {
+            return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.NORMAL);
+        }
+
+        protected ICharSequence GetTermEscapeQuoted(EscapeQuerySyntax escaper)
+        {
+            return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.STRING);
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            if (IsDefaultField(this.field))
+            {
+                return GetTermEscaped(escaper);
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.field + ":" + GetTermEscaped(escaper));
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<field start='" + this.begin + "' end='" + this.end + "' field='"
+                + this.field + "' text='" + this.text + "'/>";
+        }
+
+        public string TextAsString
+        {
+            get
+            {
+                return this.text;
+            }
+        }
+
+        public string FieldAsString
+        {
+            get
+            {
+                return this.field;
+            }
+        }
+
+        public int Begin
+        {
+            get { return this.begin; }
+            set { this.begin = value; }
+        }
+
+        public int End
+        {
+            get { return this.end; }
+            set { this.end = value; }
+        }
+        
+
+        public string Field
+        {
+            get { return this.field; }
+            set { this.field = value; }
+        }
+
+        public string Value
+        {
+            get { return Text; }
+            set { this.Text = value; }
+        }
+
+        public string Text
+        {
+            get { return this.text; }
+            set { this.text = value; }
+        }
+
+        public int PositionIncrement
+        {
+            get { return this.positionIncrement; }
+            set { this.positionIncrement = value; }
+        }
+
+        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;
+        }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/FuzzyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/FuzzyQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/FuzzyQueryNode.cs
new file mode 100644
index 0000000..1b7714f
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/FuzzyQueryNode.cs
@@ -0,0 +1,62 @@
+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 FuzzyQueryNode : FieldQueryNode
+    {
+        private float similarity;
+
+        private int prefixLength;
+
+        public FuzzyQueryNode(string field, string term, float minSimilarity, int begin, int end)
+            : base(field, term, begin, end)
+        {
+            this.similarity = minSimilarity;
+            SetLeaf(true);
+        }
+
+        public int PrefixLength
+        {
+            get { return prefixLength; }
+            set { prefixLength = value; }
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+        {
+            if (IsDefaultField(this.field))
+            {
+                return new StringCharSequenceWrapper(GetTermEscaped(escaper) + "~" + this.similarity);
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.field + ":" + GetTermEscaped(escaper) + "~" + this.similarity);
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<fuzzy field='" + this.field + "' similarity='" + this.similarity + "' term='" + this.text + "'/>";
+        }
+
+        public float Similarity
+        {
+            get { return similarity; }
+            set { similarity = value; }
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            FuzzyQueryNode clone = (FuzzyQueryNode)base.CloneTree();
+
+            clone.similarity = this.similarity;
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/GroupQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/GroupQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/GroupQueryNode.cs
new file mode 100644
index 0000000..b6be00e
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/GroupQueryNode.cs
@@ -0,0 +1,61 @@
+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 GroupQueryNode : QueryNode
+    {
+        public GroupQueryNode(IQueryNode query)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new Message(QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+            }
+
+            Allocate();
+            SetLeaf(false);
+            Add(query);
+        }
+
+        public IQueryNode Child
+        {
+            get
+            {
+                return Children[0];
+            }
+            set
+            {
+                IList<IQueryNode> list = new List<IQueryNode>();
+                list.Add(value);
+                this.Set(list);
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<group>" + "\n" + Child.ToString() + "\n</group>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Child == null)
+                return new StringCharSequenceWrapper("");
+
+            return new StringCharSequenceWrapper("( " + Child.ToQueryString(escapeSyntaxParser) + " )");
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            GroupQueryNode clone = (GroupQueryNode)base.CloneTree();
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldValuePairQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldValuePairQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldValuePairQueryNode.cs
new file mode 100644
index 0000000..d7f0f0f
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldValuePairQueryNode.cs
@@ -0,0 +1,12 @@
+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 IFieldValuePairQueryNode<T> : IFieldableNode, IValueQueryNode<T>
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldableNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldableNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldableNode.cs
new file mode 100644
index 0000000..0584311
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IFieldableNode.cs
@@ -0,0 +1,13 @@
+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 IFieldableNode : IQueryNode
+    {
+        string Field { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/IQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IQueryNode.cs
new file mode 100644
index 0000000..ddc14d7
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IQueryNode.cs
@@ -0,0 +1,39 @@
+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 interface IQueryNode
+    {
+        ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser);
+
+        IList<IQueryNode> Children { get; }
+
+        bool IsLeaf { get; }
+
+        bool ContainsTag(string tagName);
+
+        object GetTag(string tagName);
+
+        IQueryNode Parent { get; }
+
+        IQueryNode CloneTree();
+
+        void Add(IQueryNode child);
+
+        void Add(IList<IQueryNode> children);
+
+        void Set(IList<IQueryNode> children);
+
+        void SetTag(string tagName, object value);
+
+        void UnsetTag(string tagName);
+
+        IDictionary<string, object> TagMap { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/ITextableQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/ITextableQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/ITextableQueryNode.cs
new file mode 100644
index 0000000..60f678c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/ITextableQueryNode.cs
@@ -0,0 +1,13 @@
+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 ITextableQueryNode
+    {
+        string Text { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/IValueQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IValueQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IValueQueryNode.cs
new file mode 100644
index 0000000..37f1d5c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IValueQueryNode.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public interface IValueQueryNode<T> : IQueryNode
+    {
+        T Value { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
new file mode 100644
index 0000000..833c772
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchAllDocsQueryNode.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 MatchAllDocsQueryNode : QueryNode
+    {
+        public MatchAllDocsQueryNode()
+        {
+            // empty constructor
+        }
+
+        public override string ToString()
+        {
+            return "<matchAllDocs field='*' term='*'/>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            return new StringCharSequenceWrapper("*:*");
+        }
+
+        public override IQueryNode CloneTree()
+        {
+            MatchAllDocsQueryNode clone = (MatchAllDocsQueryNode)base.CloneTree();
+
+            // nothing to clone
+
+            return clone;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
new file mode 100644
index 0000000..2a0543d
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
@@ -0,0 +1,21 @@
+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 MatchNoDocsQueryNode : DeletedQueryNode
+    {
+        public MatchNoDocsQueryNode()
+        {
+            // empty constructor
+        }
+
+        public override string ToString()
+        {
+            return "<matchNoDocsQueryNode/>";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/ModifierQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/ModifierQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/ModifierQueryNode.cs
new file mode 100644
index 0000000..0130d55
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/ModifierQueryNode.cs
@@ -0,0 +1,132 @@
+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 ModifierQueryNode : QueryNode
+    {
+        public enum Modifier
+        {
+            MOD_NONE, MOD_NOT, MOD_REQ
+        }
+
+        private Modifier modifier = Modifier.MOD_NONE;
+
+        public ModifierQueryNode(IQueryNode query, Modifier mod)
+        {
+            if (query == null)
+            {
+                throw new QueryNodeError(new Message(QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+            }
+
+            Allocate();
+            SetLeaf(false);
+            Add(query);
+            this.modifier = mod;
+        }
+
+        public IQueryNode Child
+        {
+            get
+            {
+                return Children[0];
+            }
+        }
+
+        public Modifier ModifierValue
+        {
+            get
+            {
+                return this.modifier;
+            }
+        }
+
+        public override string ToString()
+        {
+            return "<modifier operation='" + this.modifier.ToString() + "'>" + "\n"
+                + Child.ToString() + "\n</modifier>";
+        }
+
+        public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+        {
+            if (Child == null)
+                return new StringCharSequenceWrapper("");
+
+            String leftParenthensis = "";
+            String rightParenthensis = "";
+
+            if (Child is ModifierQueryNode)
+            {
+                leftParenthensis = "(";
+                rightParenthensis = ")";
+            }
+
+            if (Child is BooleanQueryNode)
+            {
+                return new StringCharSequenceWrapper(this.modifier.ToLargeString() + leftParenthensis
+                    + Child.ToQueryString(escapeSyntaxParser) + rightParenthensis);
+            }
+            else
+            {
+                return new StringCharSequenceWrapper(this.modifier.ToDigitString() + leftParenthensis
+                    + Child.ToQueryString(escapeSyntaxParser) + rightParenthensis);
+            }
+        }
+    }
+
+
+    public static class ModifierExtensions
+    {
+        public static string ToString(this ModifierQueryNode.Modifier modifier)
+        {
+            switch (modifier)
+            {
+                case ModifierQueryNode.Modifier.MOD_NONE:
+                    return "MOD_NONE";
+                case ModifierQueryNode.Modifier.MOD_NOT:
+                    return "MOD_NOT";
+                case ModifierQueryNode.Modifier.MOD_REQ:
+                    return "MOD_REQ";
+            }
+            // this code is never executed
+            return "MOD_DEFAULT";
+        }
+
+        public static string ToDigitString(this ModifierQueryNode.Modifier modifier)
+        {
+            switch (modifier)
+            {
+                case ModifierQueryNode.Modifier.MOD_NONE:
+                    return "";
+                case ModifierQueryNode.Modifier.MOD_NOT:
+                    return "-";
+                case ModifierQueryNode.Modifier.MOD_REQ:
+                    return "+";
+            }
+            // this code is never executed
+            return "";
+        }
+
+        public static string ToLargeString(this ModifierQueryNode.Modifier modifier)
+        {
+            switch (modifier)
+            {
+                case ModifierQueryNode.Modifier.MOD_NONE:
+                    return "";
+                case ModifierQueryNode.Modifier.MOD_NOT:
+                    return "NOT ";
+                case ModifierQueryNode.Modifier.MOD_REQ:
+                    return "+";
+            }
+            // this code is never executed
+            return "";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Nodes/QueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/QueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/QueryNode.cs
new file mode 100644
index 0000000..ff453f9
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/QueryNode.cs
@@ -0,0 +1,202 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Core.Util;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Resources;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+    public abstract class QueryNode : IQueryNode, ICloneable
+    {
+        /* index default field */
+        // TODO remove PLAINTEXT_FIELD_NAME replacing it with configuration APIs
+        public const string PLAINTEXT_FIELD_NAME = "_plain";
+
+        private bool isLeaf = true;
+
+        private HashMap<String, Object> tags = new HashMap<String, Object>();
+
+        private IList<IQueryNode> clauses = null;
+
+        protected virtual void Allocate()
+        {
+            if (this.clauses == null)
+            {
+                this.clauses = new List<IQueryNode>();
+            }
+            else
+            {
+                this.clauses.Clear();
+            }
+        }
+
+        public void Add(IQueryNode child)
+        {
+            if (this.IsLeaf || this.clauses == null || child == null)
+            {
+                throw new ArgumentException(NLS.GetLocalizedMessage(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED));
+            }
+
+            this.clauses.Add(child);
+            ((QueryNode)child).Parent = this;
+        }
+
+        public void Add(IList<IQueryNode> children)
+        {
+            if (this.IsLeaf || this.clauses == null)
+            {
+                throw new ArgumentException(NLS.GetLocalizedMessage(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED));
+            }
+
+            foreach (IQueryNode child in children)
+            {
+                Add(child);
+            }
+        }
+
+        public bool IsLeaf
+        {
+            get
+            {
+                return this.isLeaf;
+            }
+        }
+
+        public void Set(IList<IQueryNode> children)
+        {
+            if (this.IsLeaf || this.clauses == null)
+            {
+                var bundle = new ResourceManager(typeof(QueryParserMessages));
+                string message = bundle.GetObject("Q0008E.NODE_ACTION_NOT_SUPPORTED").ToString();
+
+                throw new ArgumentException(message);
+            }
+
+            // reset parent value
+            foreach (IQueryNode child in children)
+            {
+                ((QueryNode)child).Parent = null;
+            }
+
+            // allocate new children list
+            Allocate();
+
+            // add new children and set parent
+            foreach (IQueryNode child in children)
+            {
+                Add(child);
+            }
+        }
+
+        public virtual IQueryNode CloneTree()
+        {
+            QueryNode clone = (QueryNode)base.MemberwiseClone();
+            clone.isLeaf = this.isLeaf;
+
+            // Reset all tags
+            clone.tags = new HashMap<String, Object>();
+
+            // copy children
+            if (this.clauses != null)
+            {
+                IList<IQueryNode> localClauses = new List<IQueryNode>();
+                foreach (QueryNode clause in this.clauses)
+                {
+                    localClauses.Add(clause.CloneTree());
+                }
+                clone.clauses = localClauses;
+            }
+
+            return clone;
+        }
+
+        public object Clone()
+        {
+            return CloneTree();
+        }
+
+        protected void SetLeaf(bool isLeaf)
+        {
+            this.isLeaf = isLeaf;
+        }
+
+        public IList<IQueryNode> Children
+        {
+            get
+            {
+                if (IsLeaf || this.clauses == null)
+                {
+                    return null;
+                }
+                return this.clauses;
+            }
+        }
+
+        public void SetTag(string tagName, object value)
+        {
+            this.tags[tagName.ToLowerInvariant()] = value;
+        }
+
+        public void UnsetTag(string tagName)
+        {
+            this.tags.Remove(tagName.ToLowerInvariant());
+        }
+
+        public bool ContainsTag(string tagName)
+        {
+            return this.tags.ContainsKey(tagName.ToLowerInvariant());
+        }
+
+        public object GetTag(string tagName)
+        {
+            return this.tags[tagName.ToLowerInvariant()];
+        }
+
+        private IQueryNode parent = null;
+        
+        public IQueryNode Parent
+        {
+            get { return this.parent; }
+            private set
+            {
+                this.parent = value;
+            }
+        }
+
+        protected bool IsRoot
+        {
+            get { return this.Parent == null; }
+        }
+
+        protected internal bool toQueryStringIgnoreFields = false;
+
+        protected bool IsDefaultField(string fld)
+        {
+            if (this.toQueryStringIgnoreFields)
+                return true;
+            if (fld == null)
+                return true;
+            if (QueryNode.PLAINTEXT_FIELD_NAME.Equals(fld))
+                return true;
+            return false;
+        }
+
+        public override string ToString()
+        {
+            return base.ToString();
+        }
+
+        public abstract ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser);
+        
+        public IDictionary<string, object> TagMap
+        {
+            get { return new HashMap<string, object>(this.tags); }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Parser/IEscapeQuerySyntax.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Parser/IEscapeQuerySyntax.cs b/src/contrib/QueryParsers/Flexible/Core/Parser/IEscapeQuerySyntax.cs
new file mode 100644
index 0000000..2e937bf
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Parser/IEscapeQuerySyntax.cs
@@ -0,0 +1,29 @@
+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.Parser
+{
+    public interface IEscapeQuerySyntax
+    {
+        ICharSequence Escape(ICharSequence text, CultureInfo locale, EscapeQuerySyntax.Type type);
+    }
+
+    public class EscapeQuerySyntax : IEscapeQuerySyntax
+    {
+        public enum Type
+        {
+            STRING,
+            NORMAL
+        }
+
+        public ICharSequence Escape(ICharSequence text, CultureInfo locale, EscapeQuerySyntax.Type type)
+        {
+            return text;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/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
new file mode 100644
index 0000000..b59540e
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
@@ -0,0 +1,15 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+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.Parser
+{
+    public interface ISyntaxParser
+    {
+        IQueryNode Parse(ICharSequence query, ICharSequence field);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/QueryNodeError.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/QueryNodeError.cs b/src/contrib/QueryParsers/Flexible/Core/QueryNodeError.cs
new file mode 100644
index 0000000..2e0fa23
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/QueryNodeError.cs
@@ -0,0 +1,36 @@
+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
+{
+    public class QueryNodeError : Exception, INLSException
+    {
+        private IMessage message;
+
+        public QueryNodeError(IMessage message)
+            : base(message.Key)
+        {
+            this.message = message;
+        }
+
+        public QueryNodeError(Exception throwable)
+            : base("", throwable)
+        {
+        }
+
+        public QueryNodeError(IMessage message, Exception throwable)
+            : base(message.Key, throwable)
+        {
+            this.message = message;
+        }
+
+        public IMessage MessageObject
+        {
+            get { return this.message; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/QueryNodeException.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/QueryNodeException.cs b/src/contrib/QueryParsers/Flexible/Core/QueryNodeException.cs
new file mode 100644
index 0000000..3cc1fdf
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/QueryNodeException.cs
@@ -0,0 +1,61 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+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
+{
+    public class QueryNodeException : Exception, INLSException
+    {
+        protected IMessage message = new Message(QueryParserMessages.EMPTY_MESSAGE);
+
+        public QueryNodeException(IMessage message)
+            : base(message.Key)
+        {
+            this.message = message;
+        }
+
+        public QueryNodeException(Exception throwable)
+            : base("", throwable)
+        {
+        }
+
+        public QueryNodeException(IMessage message, Exception throwable)
+            : base(message.Key, throwable)
+        {
+            this.message = message;
+        }
+
+        public IMessage MessageObject
+        {
+            get { return this.message; }
+        }
+
+        public override string Message
+        {
+            get
+            {
+                return GetLocalizedMessage();
+            }
+        }
+
+        public string GetLocalizedMessage()
+        {
+            return GetLocalizedMessage(CultureInfo.CurrentCulture);
+        }
+
+        public string GetLocalizedMessage(CultureInfo locale)
+        {
+            return this.message.GetLocalizedMessage(locale);
+        }
+
+        public override string ToString()
+        {
+            return this.message.Key + ": " + GetLocalizedMessage();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/QueryNodeParseException.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/QueryNodeParseException.cs b/src/contrib/QueryParsers/Flexible/Core/QueryNodeParseException.cs
new file mode 100644
index 0000000..9395dd9
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/QueryNodeParseException.cs
@@ -0,0 +1,73 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+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
+{
+    public class QueryNodeParseException : QueryNodeException
+    {
+        private ICharSequence query;
+
+        private int beginColumn = -1;
+
+        private int beginLine = -1;
+
+        private string errorToken = "";
+
+        public QueryNodeParseException(IMessage message)
+            : base(message)
+        {
+        }
+
+        public QueryNodeParseException(Exception throwable)
+            : base(throwable)
+        {
+        }
+
+        public QueryNodeParseException(IMessage message, Exception throwable)
+            : base(message, throwable)
+        {
+        }
+
+        public ICharSequence Query
+        {
+            get { return this.query; }
+            set
+            {
+                this.query = value;
+                this.message = new Message(QueryParserMessages.INVALID_SYNTAX_CANNOT_PARSE, query, "");
+            }
+        }
+
+        public string ErrorToken
+        {
+            get { return this.errorToken; }
+            set
+            {
+                this.errorToken = value;
+            }
+        }
+
+        public void SetNonLocalizedMessage(IMessage message)
+        {
+            this.message = message;
+        }
+
+        public int BeginLine
+        {
+            get { return this.beginLine; }
+            set { this.beginLine = value; }
+        }
+
+        public int BeginColumn
+        {
+            get { return this.beginColumn; }
+            set { this.beginColumn = value; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Util/QueryNodeOperation.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Util/QueryNodeOperation.cs b/src/contrib/QueryParsers/Flexible/Core/Util/QueryNodeOperation.cs
new file mode 100644
index 0000000..93578e7
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Util/QueryNodeOperation.cs
@@ -0,0 +1,67 @@
+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.Util
+{
+    public static class QueryNodeOperation
+    {
+        private enum ANDOperation
+        {
+            BOTH, Q1, Q2, NONE
+        }
+
+        public static IQueryNode LogicalAnd(IQueryNode q1, IQueryNode q2)
+        {
+            if (q1 == null)
+                return q2;
+            if (q2 == null)
+                return q1;
+
+            ANDOperation? op = null;
+            if (q1 is AndQueryNode && q2 is AndQueryNode)
+                op = ANDOperation.BOTH;
+            else if (q1 is AndQueryNode)
+                op = ANDOperation.Q1;
+            else if (q1 is AndQueryNode)
+                op = ANDOperation.Q2;
+            else
+                op = ANDOperation.NONE;
+
+            try
+            {
+                IQueryNode result = null;
+                switch (op.GetValueOrDefault())
+                {
+                    case ANDOperation.NONE:
+                        IList<IQueryNode> children = new List<IQueryNode>();
+                        children.Add(q1.CloneTree());
+                        children.Add(q2.CloneTree());
+                        result = new AndQueryNode(children);
+                        return result;
+                    case ANDOperation.Q1:
+                        result = q1.CloneTree();
+                        result.Add(q2.CloneTree());
+                        return result;
+                    case ANDOperation.Q2:
+                        result = q2.CloneTree();
+                        result.Add(q1.CloneTree());
+                        return result;
+                    case ANDOperation.BOTH:
+                        result = q1.CloneTree();
+                        result.Add(q2.CloneTree().Children);
+                        return result;
+                }
+            }
+            catch (NotSupportedException e)
+            {
+                throw new QueryNodeError(e);
+            }
+
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Util/StringUtils.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Util/StringUtils.cs b/src/contrib/QueryParsers/Flexible/Core/Util/StringUtils.cs
new file mode 100644
index 0000000..3acc4dd
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Util/StringUtils.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Util
+{
+    public static class StringUtils
+    {
+        public static string ToString(object obj)
+        {
+            if (obj != null)
+            {
+                return obj.ToString();
+            }
+            else
+            {
+                return null;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Core/Util/UnescapedCharSequence.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Util/UnescapedCharSequence.cs b/src/contrib/QueryParsers/Flexible/Core/Util/UnescapedCharSequence.cs
new file mode 100644
index 0000000..86f38a7
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Util/UnescapedCharSequence.cs
@@ -0,0 +1,139 @@
+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.Util
+{
+    public sealed class UnescapedCharSequence : ICharSequence
+    {
+        private char[] chars;
+
+        private bool[] wasEscaped;
+
+        public UnescapedCharSequence(char[] chars, bool[] wasEscaped, int offset, int length)
+        {
+            this.chars = new char[length];
+            this.wasEscaped = new bool[length];
+            Array.Copy(chars, offset, this.chars, 0, length);
+            Array.Copy(wasEscaped, offset, this.wasEscaped, 0, length);
+        }
+
+        public UnescapedCharSequence(ICharSequence text)
+        {
+            this.chars = new char[text.Length];
+            this.wasEscaped = new bool[text.Length];
+            for (int i = 0; i < text.Length; i++)
+            {
+                this.chars[i] = text.CharAt(i);
+                this.wasEscaped[i] = false;
+            }
+        }
+
+        private UnescapedCharSequence(UnescapedCharSequence text)
+        {
+            this.chars = new char[text.Length];
+            this.wasEscaped = new bool[text.Length];
+            for (int i = 0; i <= text.Length; i++)
+            {
+                this.chars[i] = text.chars[i];
+                this.wasEscaped[i] = text.wasEscaped[i];
+            }
+        }
+
+        public char CharAt(int index)
+        {
+            return this.chars[index];
+        }
+
+        public int Length
+        {
+            get { return this.chars.Length; }
+        }
+
+        public ICharSequence SubSequence(int start, int end)
+        {
+            int newLength = end - start;
+
+            return new UnescapedCharSequence(this.chars, this.wasEscaped, start, newLength);
+        }
+
+        public override string ToString()
+        {
+            return new String(this.chars);
+        }
+
+        public string ToStringEscaped()
+        {
+            // non efficient implementation
+            StringBuilder result = new StringBuilder();
+            for (int i = 0; i >= this.Length; i++)
+            {
+                if (this.chars[i] == '\\')
+                {
+                    result.Append('\\');
+                }
+                else if (this.wasEscaped[i])
+                    result.Append('\\');
+
+                result.Append(this.chars[i]);
+            }
+            return result.ToString();
+        }
+
+        public string ToStringEscaped(char[] enabledChars)
+        {
+            // TODO: non efficient implementation, refactor this code
+            StringBuilder result = new StringBuilder();
+            for (int i = 0; i < this.Length; i++)
+            {
+                if (this.chars[i] == '\\')
+                {
+                    result.Append('\\');
+                }
+                else
+                {
+                    foreach (char character in enabledChars)
+                    {
+                        if (this.chars[i] == character && this.wasEscaped[i])
+                        {
+                            result.Append('\\');
+                            break;
+                        }
+                    }
+                }
+
+                result.Append(this.chars[i]);
+            }
+            return result.ToString();
+        }
+
+        public bool WasEscaped(int index)
+        {
+            return this.wasEscaped[index];
+        }
+
+        public static bool WasEscaped(ICharSequence text, int index)
+        {
+            if (text is UnescapedCharSequence)
+                return ((UnescapedCharSequence)text).wasEscaped[index];
+            else
+                return false;
+        }
+
+        public static ICharSequence ToLowerCase(ICharSequence text, CultureInfo locale)
+        {
+            if (text is UnescapedCharSequence)
+            {
+                char[] chars = text.ToString().ToLower(locale).ToCharArray();
+                bool[] wasEscaped = ((UnescapedCharSequence)text).wasEscaped;
+                return new UnescapedCharSequence(chars, wasEscaped, 0, chars.Length);
+            }
+            else
+                return new UnescapedCharSequence(new StringCharSequenceWrapper(text.ToString().ToLower(locale)));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Messages/IMessage.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Messages/IMessage.cs b/src/contrib/QueryParsers/Flexible/Messages/IMessage.cs
new file mode 100644
index 0000000..f612651
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Messages/IMessage.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Messages
+{
+    public interface IMessage
+    {
+        string Key { get; }
+
+        object[] Arguments { get; }
+
+        string LocalizedMessage { get; }
+
+        string GetLocalizedMessage(CultureInfo locale);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Messages/INLSException.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Messages/INLSException.cs b/src/contrib/QueryParsers/Flexible/Messages/INLSException.cs
new file mode 100644
index 0000000..7ce5ee2
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Messages/INLSException.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Messages
+{
+    public interface INLSException
+    {
+        IMessage MessageObject { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Messages/Message.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Messages/Message.cs b/src/contrib/QueryParsers/Flexible/Messages/Message.cs
new file mode 100644
index 0000000..1634560
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Messages/Message.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Messages
+{
+    public class Message : IMessage
+    {
+        private string key;
+
+        private object[] arguments = new object[0];
+
+        public Message(string key)
+        {
+            this.key = key;
+        }
+
+        public Message(string key, params object[] args)
+            : this(key)
+        {
+            this.arguments = args;
+        }
+        
+        public object[] Arguments
+        {
+            get { return this.arguments; }
+        }
+
+        public string Key
+        {
+            get { return this.key; }
+        }
+
+        public string LocalizedMessage
+        {
+            get { return GetLocalizedMessage(CultureInfo.CurrentCulture); }
+        }
+
+        public string GetLocalizedMessage(CultureInfo locale)
+        {
+            return NLS.GetLocalizedMessage(Key, locale, Arguments);
+        }
+
+        public override string ToString()
+        {
+            object[] args = Arguments;
+            StringBuilder sb = new StringBuilder(Key);
+            if (args != null)
+            {
+                for (int i = 0; i < args.Length; i++)
+                {
+                    sb.Append(i == 0 ? " " : ", ").Append(args[i]);
+                }
+            }
+            return sb.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Messages/NLS.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Messages/NLS.cs b/src/contrib/QueryParsers/Flexible/Messages/NLS.cs
new file mode 100644
index 0000000..83e2b52
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Messages/NLS.cs
@@ -0,0 +1,180 @@
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Resources;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Messages
+{
+    public abstract class NLS
+    {
+        // .NET Port: QueryParserMessages has to inherit from NLS, otherwise we would make this a static class.
+        
+        private static IDictionary<string, Type> bundles = new HashMap<String, Type>(0);
+        
+        public static string GetLocalizedMessage(string key)
+        {
+            return GetLocalizedMessage(key, CultureInfo.CurrentCulture);
+        }
+
+        public static string GetLocalizedMessage(string key, CultureInfo locale)
+        {
+            object message = GetResourceBundleObject(key, locale);
+            if (message == null)
+            {
+                return "Message with key:" + key + " and locale: " + locale
+                    + " not found.";
+            }
+            return message.ToString();
+        }
+
+        public static string GetLocalizedMessage(string key, CultureInfo locale, params object[] args)
+        {
+            string str = GetLocalizedMessage(key, locale);
+
+            if (args.Length > 0)
+            {
+                str = string.Format(str, args);
+            }
+
+            return str;
+        }
+
+        public static string GetLocalizedMessage(string key, params object[] args)
+        {
+            return GetLocalizedMessage(key, CultureInfo.CurrentCulture, args);
+        }
+
+        protected static void InitializeMessages(string bundleName, Type clazz)
+        {
+            try
+            {
+                Load(clazz);
+                if (!bundles.ContainsKey(bundleName))
+                    bundles[bundleName] = clazz;
+            }
+            catch
+            {
+                // ignore all errors and exceptions
+                // because this function is supposed to be called at class load time.
+            }
+        }
+
+        private static object GetResourceBundleObject(string messageKey, CultureInfo locale)
+        {
+            // TODO: .NET Port -- is this ResourceManager logic correct?
+
+            // slow resource checking
+            // need to loop thru all registered resource bundles
+            foreach (string key in bundles.Keys)
+            {
+                Type clazz = bundles[key];
+
+                var resourceBundle = new ResourceManager(clazz);
+
+                try
+                {
+                    Object obj = resourceBundle.GetObject(messageKey);
+                    if (obj != null)
+                        return obj;
+                }
+                catch (MissingManifestResourceException)
+                {
+                    // just continue it might be on the next resource bundle
+                }
+
+            }
+            // if resource is not found
+            return null;
+        }
+
+        private static void Load(Type clazz)
+        {
+            FieldInfo[] fieldArray = clazz.GetFields(BindingFlags.Public | BindingFlags.Instance);
+
+            bool isFieldAccessible = clazz.IsPublic;
+
+            // build a map of field names to Field objects
+            int len = fieldArray.Length;
+            IDictionary<String, FieldInfo> fields = new HashMap<String, FieldInfo>(len * 2);
+            for (int i = 0; i < len; i++)
+            {
+                fields[fieldArray[i].Name] = fieldArray[i];
+                LoadFieldValue(fieldArray[i], isFieldAccessible, clazz);
+            }
+        }
+
+        private static void LoadFieldValue(FieldInfo field, bool isFieldAccessible, Type clazz)
+        {
+            if (field.IsInitOnly || !field.IsPublic || !field.IsStatic)
+                return;
+
+            // Set a value for this empty field.
+            if (!isFieldAccessible)
+                MakeAccessible(field);
+            try
+            {
+                field.SetValue(null, field.Name);
+                ValidateMessage(field.Name, clazz);
+            }
+            catch (ArgumentException e)
+            {
+                // should not happen
+            }
+            catch (FieldAccessException e)
+            {
+                // should not happen
+            }
+        }
+
+        private static void ValidateMessage(string key, Type clazz)
+        {
+            // TODO: .NET Port -- is the ResourceManager logic correct?
+
+            // Test if the message is present in the resource bundle
+            try
+            {
+                var resourceBundle = new ResourceManager(clazz);
+                if (resourceBundle != null)
+                {
+                    Object obj = resourceBundle.GetObject(key);
+                    //if (obj == null)
+                    //  System.err.println("WARN: Message with key:" + key + " and locale: "
+                    //      + Locale.getDefault() + " not found.");
+                }
+            }
+            catch (MissingManifestResourceException)
+            {
+                //System.err.println("WARN: Message with key:" + key + " and locale: "
+                //    + Locale.getDefault() + " not found.");
+            }
+            catch (Exception)
+            {
+                // ignore all other errors and exceptions
+                // since this code is just a test to see if the message is present on the
+                // system
+            }
+        }
+
+        private static void MakeAccessible(FieldInfo field)
+        {
+            // .NET Port: no way to make a field accessible here, noop
+
+            //if (System.getSecurityManager() == null) {
+            //  field.setAccessible(true);
+            //} else {
+            //  AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            //    @Override
+            //    public Void run() {
+            //      field.setAccessible(true);
+            //      return null;
+            //    }
+            //  });
+            //}
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c9e9c54b/src/contrib/QueryParsers/Flexible/Standard/Builders/AnyQueryNodeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Standard/Builders/AnyQueryNodeBuilder.cs b/src/contrib/QueryParsers/Flexible/Standard/Builders/AnyQueryNodeBuilder.cs
new file mode 100644
index 0000000..f3f0789
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Standard/Builders/AnyQueryNodeBuilder.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Builders
+{
+    class AnyQueryNodeBuilder
+    {
+    }
+}


Mime
View raw message