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 2017/02/26 23:36:51 UTC

[03/72] [abbrv] [partial] lucenenet git commit: Lucene.Net.Tests: Removed \core directory and put its contents in root directory

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs b/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
new file mode 100644
index 0000000..5aeaf7c
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiTermConstantScore.cs
@@ -0,0 +1,563 @@
+using System;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+    using NUnit.Framework;
+    using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
+    using DefaultSimilarity = Lucene.Net.Search.Similarities.DefaultSimilarity;
+    using Directory = Lucene.Net.Store.Directory;
+    using Document = Documents.Document;
+    using Field = Field;
+    using FieldType = FieldType;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+
+    /*
+         * 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.
+         */
+
+    using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+    using MockTokenizer = Lucene.Net.Analysis.MockTokenizer;
+    using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+    using Term = Lucene.Net.Index.Term;
+    using TextField = TextField;
+
+    [TestFixture]
+    public class TestMultiTermConstantScore : BaseTestRangeFilter
+    {
+        /// <summary>
+        /// threshold for comparing floats </summary>
+        public const float SCORE_COMP_THRESH = 1e-6f;
+
+        internal static Directory Small;
+        internal static IndexReader Reader;
+
+        public static void AssertEquals(string m, int e, int a)
+        {
+            Assert.AreEqual(e, a, m);
+        }
+
+        /// <summary>
+        /// LUCENENET specific
+        /// Is non-static because NewIndexWriterConfig is no longer static.
+        /// </summary>
+        [OneTimeSetUp]
+        public void BeforeClass()
+        {
+            string[] data = new string[] { "A 1 2 3 4 5 6", "Z       4 5 6", null, "B   2   4 5 6", "Y     3   5 6", null, "C     3     6", "X       4 5 6" };
+
+            Small = NewDirectory();
+            RandomIndexWriter writer = new RandomIndexWriter(Random(), Small, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random(), MockTokenizer.WHITESPACE, false)).SetMergePolicy(NewLogMergePolicy()));
+
+            FieldType customType = new FieldType(TextField.TYPE_STORED);
+            customType.IsTokenized = false;
+            for (int i = 0; i < data.Length; i++)
+            {
+                Document doc = new Document();
+                doc.Add(NewField("id", Convert.ToString(i), customType)); // Field.Keyword("id",String.valueOf(i)));
+                doc.Add(NewField("all", "all", customType)); // Field.Keyword("all","all"));
+                if (null != data[i])
+                {
+                    doc.Add(NewTextField("data", data[i], Field.Store.YES)); // Field.Text("data",data[i]));
+                }
+                writer.AddDocument(doc);
+            }
+
+            Reader = writer.Reader;
+            writer.Dispose();
+        }
+
+        [OneTimeTearDown]
+        public static void AfterClass()
+        {
+            Reader.Dispose();
+            Small.Dispose();
+            Reader = null;
+            Small = null;
+        }
+
+        /// <summary>
+        /// macro for readability </summary>
+        public static Query Csrq(string f, string l, string h, bool il, bool ih)
+        {
+            TermRangeQuery query = TermRangeQuery.NewStringRange(f, l, h, il, ih);
+            query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+            if (VERBOSE)
+            {
+                Console.WriteLine("TEST: query=" + query);
+            }
+            return query;
+        }
+
+        public static Query Csrq(string f, string l, string h, bool il, bool ih, MultiTermQuery.RewriteMethod method)
+        {
+            TermRangeQuery query = TermRangeQuery.NewStringRange(f, l, h, il, ih);
+            query.MultiTermRewriteMethod = (method);
+            if (VERBOSE)
+            {
+                Console.WriteLine("TEST: query=" + query + " method=" + method);
+            }
+            return query;
+        }
+
+        /// <summary>
+        /// macro for readability </summary>
+        public static Query Cspq(Term prefix)
+        {
+            PrefixQuery query = new PrefixQuery(prefix);
+            query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+            return query;
+        }
+
+        /// <summary>
+        /// macro for readability </summary>
+        public static Query Cswcq(Term wild)
+        {
+            WildcardQuery query = new WildcardQuery(wild);
+            query.MultiTermRewriteMethod = (MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+            return query;
+        }
+
+        [Test]
+        public virtual void TestBasics()
+        {
+            QueryUtils.Check(Csrq("data", "1", "6", T, T));
+            QueryUtils.Check(Csrq("data", "A", "Z", T, T));
+            QueryUtils.CheckUnequal(Csrq("data", "1", "6", T, T), Csrq("data", "A", "Z", T, T));
+
+            QueryUtils.Check(Cspq(new Term("data", "p*u?")));
+            QueryUtils.CheckUnequal(Cspq(new Term("data", "pre*")), Cspq(new Term("data", "pres*")));
+
+            QueryUtils.Check(Cswcq(new Term("data", "p")));
+            QueryUtils.CheckUnequal(Cswcq(new Term("data", "pre*n?t")), Cswcq(new Term("data", "pr*t?j")));
+        }
+
+        [Test]
+        public virtual void TestEqualScores()
+        {
+            // NOTE: uses index build in *this* setUp
+
+            IndexSearcher search = NewSearcher(Reader);
+
+            ScoreDoc[] result;
+
+            // some hits match more terms then others, score should be the same
+
+            result = search.Search(Csrq("data", "1", "6", T, T), null, 1000).ScoreDocs;
+            int numHits = result.Length;
+            AssertEquals("wrong number of results", 6, numHits);
+            float score = result[0].Score;
+            for (int i = 1; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+
+            result = search.Search(Csrq("data", "1", "6", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE), null, 1000).ScoreDocs;
+            numHits = result.Length;
+            AssertEquals("wrong number of results", 6, numHits);
+            for (int i = 0; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+
+            result = search.Search(Csrq("data", "1", "6", T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, 1000).ScoreDocs;
+            numHits = result.Length;
+            AssertEquals("wrong number of results", 6, numHits);
+            for (int i = 0; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+        }
+
+        [Test]
+        public virtual void TestEqualScoresWhenNoHits() // Test for LUCENE-5245: Empty MTQ rewrites should have a consistent norm, so always need to return a CSQ!
+        {
+            // NOTE: uses index build in *this* setUp
+
+            IndexSearcher search = NewSearcher(Reader);
+
+            ScoreDoc[] result;
+
+            TermQuery dummyTerm = new TermQuery(new Term("data", "1"));
+
+            BooleanQuery bq = new BooleanQuery();
+            bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+            bq.Add(Csrq("data", "#", "#", T, T), Occur.SHOULD); // hits no docs
+            result = search.Search(bq, null, 1000).ScoreDocs;
+            int numHits = result.Length;
+            AssertEquals("wrong number of results", 1, numHits);
+            float score = result[0].Score;
+            for (int i = 1; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+
+            bq = new BooleanQuery();
+            bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+            bq.Add(Csrq("data", "#", "#", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE), Occur.SHOULD); // hits no docs
+            result = search.Search(bq, null, 1000).ScoreDocs;
+            numHits = result.Length;
+            AssertEquals("wrong number of results", 1, numHits);
+            for (int i = 0; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+
+            bq = new BooleanQuery();
+            bq.Add(dummyTerm, Occur.SHOULD); // hits one doc
+            bq.Add(Csrq("data", "#", "#", T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), Occur.SHOULD); // hits no docs
+            result = search.Search(bq, null, 1000).ScoreDocs;
+            numHits = result.Length;
+            AssertEquals("wrong number of results", 1, numHits);
+            for (int i = 0; i < numHits; i++)
+            {
+                Assert.AreEqual(score, result[i].Score, SCORE_COMP_THRESH, "score for " + i + " was not the same");
+            }
+        }
+
+        [Test]
+        public virtual void TestBoost()
+        {
+            // NOTE: uses index build in *this* setUp
+
+            IndexSearcher search = NewSearcher(Reader);
+
+            // test for correct application of query normalization
+            // must use a non score normalizing method for this.
+
+            search.Similarity = new DefaultSimilarity();
+            Query q = Csrq("data", "1", "6", T, T);
+            q.Boost = 100;
+            search.Search(q, null, new CollectorAnonymousInnerClassHelper(this));
+
+            //
+            // Ensure that boosting works to score one clause of a query higher
+            // than another.
+            //
+            Query q1 = Csrq("data", "A", "A", T, T); // matches document #0
+            q1.Boost = .1f;
+            Query q2 = Csrq("data", "Z", "Z", T, T); // matches document #1
+            BooleanQuery bq = new BooleanQuery(true);
+            bq.Add(q1, Occur.SHOULD);
+            bq.Add(q2, Occur.SHOULD);
+
+            ScoreDoc[] hits = search.Search(bq, null, 1000).ScoreDocs;
+            Assert.AreEqual(1, hits[0].Doc);
+            Assert.AreEqual(0, hits[1].Doc);
+            Assert.IsTrue(hits[0].Score > hits[1].Score);
+
+            q1 = Csrq("data", "A", "A", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); // matches document #0
+            q1.Boost = .1f;
+            q2 = Csrq("data", "Z", "Z", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE); // matches document #1
+            bq = new BooleanQuery(true);
+            bq.Add(q1, Occur.SHOULD);
+            bq.Add(q2, Occur.SHOULD);
+
+            hits = search.Search(bq, null, 1000).ScoreDocs;
+            Assert.AreEqual(1, hits[0].Doc);
+            Assert.AreEqual(0, hits[1].Doc);
+            Assert.IsTrue(hits[0].Score > hits[1].Score);
+
+            q1 = Csrq("data", "A", "A", T, T); // matches document #0
+            q1.Boost = 10f;
+            q2 = Csrq("data", "Z", "Z", T, T); // matches document #1
+            bq = new BooleanQuery(true);
+            bq.Add(q1, Occur.SHOULD);
+            bq.Add(q2, Occur.SHOULD);
+
+            hits = search.Search(bq, null, 1000).ScoreDocs;
+            Assert.AreEqual(0, hits[0].Doc);
+            Assert.AreEqual(1, hits[1].Doc);
+            Assert.IsTrue(hits[0].Score > hits[1].Score);
+        }
+
+        private class CollectorAnonymousInnerClassHelper : ICollector
+        {
+            private readonly TestMultiTermConstantScore OuterInstance;
+
+            public CollectorAnonymousInnerClassHelper(TestMultiTermConstantScore outerInstance)
+            {
+                this.OuterInstance = outerInstance;
+                @base = 0;
+            }
+
+            private int @base;
+            private Scorer scorer;
+
+            public virtual void SetScorer(Scorer scorer)
+            {
+                this.scorer = scorer;
+            }
+
+            public virtual void Collect(int doc)
+            {
+                Assert.AreEqual(1.0f, scorer.GetScore(), SCORE_COMP_THRESH, "score for doc " + (doc + @base) + " was not correct");
+            }
+
+            public virtual void SetNextReader(AtomicReaderContext context)
+            {
+                @base = context.DocBase;
+            }
+
+            public virtual bool AcceptsDocsOutOfOrder
+            {
+                get { return true; }
+            }
+        }
+
+        [Test]
+        public virtual void TestBooleanOrderUnAffected()
+        {
+            // NOTE: uses index build in *this* setUp
+
+            IndexSearcher search = NewSearcher(Reader);
+
+            // first do a regular TermRangeQuery which uses term expansion so
+            // docs with more terms in range get higher scores
+
+            Query rq = TermRangeQuery.NewStringRange("data", "1", "4", T, T);
+
+            ScoreDoc[] expected = search.Search(rq, null, 1000).ScoreDocs;
+            int numHits = expected.Length;
+
+            // now do a boolean where which also contains a
+            // ConstantScoreRangeQuery and make sure hte order is the same
+
+            BooleanQuery q = new BooleanQuery();
+            q.Add(rq, Occur.MUST); // T, F);
+            q.Add(Csrq("data", "1", "6", T, T), Occur.MUST); // T, F);
+
+            ScoreDoc[] actual = search.Search(q, null, 1000).ScoreDocs;
+
+            AssertEquals("wrong numebr of hits", numHits, actual.Length);
+            for (int i = 0; i < numHits; i++)
+            {
+                AssertEquals("mismatch in docid for hit#" + i, expected[i].Doc, actual[i].Doc);
+            }
+        }
+
+        [Test]
+        public virtual void TestRangeQueryId()
+        {
+            // NOTE: uses index build in *super* setUp
+
+            IndexReader reader = SignedIndexReader;
+            IndexSearcher search = NewSearcher(reader);
+
+            if (VERBOSE)
+            {
+                Console.WriteLine("TEST: reader=" + reader);
+            }
+
+            int medId = ((MaxId - MinId) / 2);
+
+            string minIP = Pad(MinId);
+            string maxIP = Pad(MaxId);
+            string medIP = Pad(medId);
+
+            int numDocs = reader.NumDocs;
+
+            AssertEquals("num of docs", numDocs, 1 + MaxId - MinId);
+
+            ScoreDoc[] result;
+
+            // test id, bounded on both ends
+
+            result = search.Search(Csrq("id", minIP, maxIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("find all", numDocs, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("find all", numDocs, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("all but last", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, T, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("all but last", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("all but first", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, F, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("all but first", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("all but ends", numDocs - 2, result.Length);
+
+            result = search.Search(Csrq("id", minIP, maxIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("all but ends", numDocs - 2, result.Length);
+
+            result = search.Search(Csrq("id", medIP, maxIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("med and up", 1 + MaxId - medId, result.Length);
+
+            result = search.Search(Csrq("id", medIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("med and up", 1 + MaxId - medId, result.Length);
+
+            result = search.Search(Csrq("id", minIP, medIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("up to med", 1 + medId - MinId, result.Length);
+
+            result = search.Search(Csrq("id", minIP, medIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("up to med", 1 + medId - MinId, result.Length);
+
+            // unbounded id
+
+            result = search.Search(Csrq("id", minIP, null, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("min and up", numDocs, result.Length);
+
+            result = search.Search(Csrq("id", null, maxIP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("max and down", numDocs, result.Length);
+
+            result = search.Search(Csrq("id", minIP, null, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("not min, but up", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", null, maxIP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("not max, but down", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("id", medIP, maxIP, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("med and up, not max", MaxId - medId, result.Length);
+
+            result = search.Search(Csrq("id", minIP, medIP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("not min, up to med", medId - MinId, result.Length);
+
+            // very small sets
+
+            result = search.Search(Csrq("id", minIP, minIP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", minIP, minIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", medIP, medIP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("med,med,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", medIP, medIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("med,med,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, maxIP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, maxIP, F, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("id", minIP, minIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", minIP, minIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", null, minIP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("nul,min,F,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", null, minIP, F, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("nul,min,F,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, maxIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, maxIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, null, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("max,nul,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", maxIP, null, T, F, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("max,nul,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", medIP, medIP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("med,med,T,T", 1, result.Length);
+
+            result = search.Search(Csrq("id", medIP, medIP, T, T, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT), null, numDocs).ScoreDocs;
+            AssertEquals("med,med,T,T", 1, result.Length);
+        }
+
+        [Test]
+        public virtual void TestRangeQueryRand()
+        {
+            // NOTE: uses index build in *super* setUp
+
+            IndexReader reader = SignedIndexReader;
+            IndexSearcher search = NewSearcher(reader);
+
+            string minRP = Pad(SignedIndexDir.MinR);
+            string maxRP = Pad(SignedIndexDir.MaxR);
+
+            int numDocs = reader.NumDocs;
+
+            AssertEquals("num of docs", numDocs, 1 + MaxId - MinId);
+
+            ScoreDoc[] result;
+
+            // test extremes, bounded on both ends
+
+            result = search.Search(Csrq("rand", minRP, maxRP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("find all", numDocs, result.Length);
+
+            result = search.Search(Csrq("rand", minRP, maxRP, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("all but biggest", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("rand", minRP, maxRP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("all but smallest", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("rand", minRP, maxRP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("all but extremes", numDocs - 2, result.Length);
+
+            // unbounded
+
+            result = search.Search(Csrq("rand", minRP, null, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("smallest and up", numDocs, result.Length);
+
+            result = search.Search(Csrq("rand", null, maxRP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("biggest and down", numDocs, result.Length);
+
+            result = search.Search(Csrq("rand", minRP, null, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("not smallest, but up", numDocs - 1, result.Length);
+
+            result = search.Search(Csrq("rand", null, maxRP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("not biggest, but down", numDocs - 1, result.Length);
+
+            // very small sets
+
+            result = search.Search(Csrq("rand", minRP, minRP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,F,F", 0, result.Length);
+            result = search.Search(Csrq("rand", maxRP, maxRP, F, F), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,F,F", 0, result.Length);
+
+            result = search.Search(Csrq("rand", minRP, minRP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("min,min,T,T", 1, result.Length);
+            result = search.Search(Csrq("rand", null, minRP, F, T), null, numDocs).ScoreDocs;
+            AssertEquals("nul,min,F,T", 1, result.Length);
+
+            result = search.Search(Csrq("rand", maxRP, maxRP, T, T), null, numDocs).ScoreDocs;
+            AssertEquals("max,max,T,T", 1, result.Length);
+            result = search.Search(Csrq("rand", maxRP, null, T, F), null, numDocs).ScoreDocs;
+            AssertEquals("max,nul,T,T", 1, result.Length);
+        }
+
+
+        #region SorterTestBase
+        // LUCENENET NOTE: Tests in a base class are not pulled into the correct
+        // context in Visual Studio. This fixes that with the minimum amount of code necessary
+        // to run them in the correct context without duplicating all of the tests.
+
+        [Test]
+        public override void TestPad()
+        {
+            base.TestPad();
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs b/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
new file mode 100644
index 0000000..0d7afc5
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiTermQueryRewrites.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Diagnostics;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+    using NUnit.Framework;
+    using System.Runtime.CompilerServices;
+    using Util;
+    using AttributeSource = Lucene.Net.Util.AttributeSource;
+    using BytesRef = Lucene.Net.Util.BytesRef;
+    using Directory = Lucene.Net.Store.Directory;
+    using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+    using Document = Documents.Document;
+    using Field = Field;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+    /*
+         * 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.
+         */
+
+    using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+    using MultiReader = Lucene.Net.Index.MultiReader;
+    using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+    using Term = Lucene.Net.Index.Term;
+    using Terms = Lucene.Net.Index.Terms;
+    using TermsEnum = Lucene.Net.Index.TermsEnum;
+
+    [TestFixture]
+    public class TestMultiTermQueryRewrites : LuceneTestCase
+    {
+        internal static Directory Dir, Sdir1, Sdir2;
+        internal static IndexReader Reader, MultiReader, MultiReaderDupls;
+        internal static IndexSearcher Searcher, MultiSearcher, MultiSearcherDupls;
+
+        /// <summary>
+        /// LUCENENET specific
+        /// Is non-static because Similarity and TimeZone are not static.
+        /// </summary>
+        [OneTimeSetUp]
+        public void BeforeClass()
+        {
+            Dir = NewDirectory();
+            Sdir1 = NewDirectory();
+            Sdir2 = NewDirectory();
+            RandomIndexWriter writer = new RandomIndexWriter(Random(), Dir, new MockAnalyzer(Random()), Similarity, TimeZone);
+            RandomIndexWriter swriter1 = new RandomIndexWriter(Random(), Sdir1, new MockAnalyzer(Random()), Similarity, TimeZone);
+            RandomIndexWriter swriter2 = new RandomIndexWriter(Random(), Sdir2, new MockAnalyzer(Random()), Similarity, TimeZone);
+
+            for (int i = 0; i < 10; i++)
+            {
+                Document doc = new Document();
+                doc.Add(NewStringField("data", Convert.ToString(i), Field.Store.NO));
+                writer.AddDocument(doc);
+                ((i % 2 == 0) ? swriter1 : swriter2).AddDocument(doc);
+            }
+            writer.ForceMerge(1);
+            swriter1.ForceMerge(1);
+            swriter2.ForceMerge(1);
+            writer.Dispose();
+            swriter1.Dispose();
+            swriter2.Dispose();
+
+            Reader = DirectoryReader.Open(Dir);
+            Searcher = NewSearcher(Reader);
+
+            MultiReader = new MultiReader(new IndexReader[] { DirectoryReader.Open(Sdir1), DirectoryReader.Open(Sdir2) }, true);
+            MultiSearcher = NewSearcher(MultiReader);
+
+            MultiReaderDupls = new MultiReader(new IndexReader[] { DirectoryReader.Open(Sdir1), DirectoryReader.Open(Dir) }, true);
+            MultiSearcherDupls = NewSearcher(MultiReaderDupls);
+        }
+
+        [OneTimeTearDown]
+        public static void AfterClass()
+        {
+            Reader.Dispose();
+            MultiReader.Dispose();
+            MultiReaderDupls.Dispose();
+            Dir.Dispose();
+            Sdir1.Dispose();
+            Sdir2.Dispose();
+            Reader = MultiReader = MultiReaderDupls = null;
+            Searcher = MultiSearcher = MultiSearcherDupls = null;
+            Dir = Sdir1 = Sdir2 = null;
+        }
+
+        private Query ExtractInnerQuery(Query q)
+        {
+            if (q is ConstantScoreQuery)
+            {
+                // wrapped as ConstantScoreQuery
+                q = ((ConstantScoreQuery)q).Query;
+            }
+            return q;
+        }
+
+        private Term ExtractTerm(Query q)
+        {
+            q = ExtractInnerQuery(q);
+            return ((TermQuery)q).Term;
+        }
+
+        private void CheckBooleanQueryOrder(Query q)
+        {
+            q = ExtractInnerQuery(q);
+            BooleanQuery bq = (BooleanQuery)q;
+            Term last = null, act;
+            foreach (BooleanClause clause in bq.Clauses)
+            {
+                act = ExtractTerm(clause.Query);
+                if (last != null)
+                {
+                    Assert.IsTrue(last.CompareTo(act) < 0, "sort order of terms in BQ violated");
+                }
+                last = act;
+            }
+        }
+
+        private void CheckDuplicateTerms(MultiTermQuery.RewriteMethod method)
+        {
+            MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+            mtq.MultiTermRewriteMethod = (method);
+            Query q1 = Searcher.Rewrite(mtq);
+            Query q2 = MultiSearcher.Rewrite(mtq);
+            Query q3 = MultiSearcherDupls.Rewrite(mtq);
+            if (VERBOSE)
+            {
+                Console.WriteLine();
+                Console.WriteLine("single segment: " + q1);
+                Console.WriteLine("multi segment: " + q2);
+                Console.WriteLine("multi segment with duplicates: " + q3);
+            }
+            Assert.IsTrue(q1.Equals(q2), "The multi-segment case must produce same rewritten query");
+            Assert.IsTrue(q1.Equals(q3), "The multi-segment case with duplicates must produce same rewritten query");
+            CheckBooleanQueryOrder(q1);
+            CheckBooleanQueryOrder(q2);
+            CheckBooleanQueryOrder(q3);
+        }
+
+        [Test]
+        public virtual void TestRewritesWithDuplicateTerms()
+        {
+            CheckDuplicateTerms(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+
+            CheckDuplicateTerms(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE);
+
+            // use a large PQ here to only test duplicate terms and dont mix up when all scores are equal
+            CheckDuplicateTerms(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+            CheckDuplicateTerms(new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(1024));
+
+            // Test auto rewrite (but only boolean mode), so we set the limits to large values to always get a BQ
+            MultiTermQuery.ConstantScoreAutoRewrite rewrite = new MultiTermQuery.ConstantScoreAutoRewrite();
+            rewrite.TermCountCutoff = int.MaxValue;
+            rewrite.DocCountPercent = 100.0;
+            CheckDuplicateTerms(rewrite);
+        }
+
+        private void CheckBooleanQueryBoosts(BooleanQuery bq)
+        {
+            foreach (BooleanClause clause in bq.Clauses)
+            {
+                TermQuery mtq = (TermQuery)clause.Query;
+                Assert.AreEqual(Convert.ToSingle(mtq.Term.Text()), mtq.Boost, 0, "Parallel sorting of boosts in rewrite mode broken");
+            }
+        }
+
+        private void CheckBoosts(MultiTermQuery.RewriteMethod method)
+        {
+            MultiTermQuery mtq = new MultiTermQueryAnonymousInnerClassHelper(this);
+            mtq.MultiTermRewriteMethod = (method);
+            Query q1 = Searcher.Rewrite(mtq);
+            Query q2 = MultiSearcher.Rewrite(mtq);
+            Query q3 = MultiSearcherDupls.Rewrite(mtq);
+            if (VERBOSE)
+            {
+                Console.WriteLine();
+                Console.WriteLine("single segment: " + q1);
+                Console.WriteLine("multi segment: " + q2);
+                Console.WriteLine("multi segment with duplicates: " + q3);
+            }
+            Assert.IsTrue(q1.Equals(q2), "The multi-segment case must produce same rewritten query");
+            Assert.IsTrue(q1.Equals(q3), "The multi-segment case with duplicates must produce same rewritten query");
+            CheckBooleanQueryBoosts((BooleanQuery)q1);
+            CheckBooleanQueryBoosts((BooleanQuery)q2);
+            CheckBooleanQueryBoosts((BooleanQuery)q3);
+        }
+
+        private class MultiTermQueryAnonymousInnerClassHelper : MultiTermQuery
+        {
+            private readonly TestMultiTermQueryRewrites OuterInstance;
+
+            public MultiTermQueryAnonymousInnerClassHelper(TestMultiTermQueryRewrites outerInstance)
+                : base("data")
+            {
+                this.OuterInstance = outerInstance;
+            }
+
+            protected override TermsEnum GetTermsEnum(Terms terms, AttributeSource atts)
+            {
+                return new TermRangeTermsEnumAnonymousInnerClassHelper(this, terms.GetIterator(null), new BytesRef("2"), new BytesRef("7"));
+            }
+
+            private class TermRangeTermsEnumAnonymousInnerClassHelper : TermRangeTermsEnum
+            {
+                private readonly MultiTermQueryAnonymousInnerClassHelper OuterInstance;
+
+                public TermRangeTermsEnumAnonymousInnerClassHelper(MultiTermQueryAnonymousInnerClassHelper outerInstance, TermsEnum iterator, BytesRef bref1, BytesRef bref2)
+                    : base(iterator, bref1, bref2, true, true)
+                {
+                    this.OuterInstance = outerInstance;
+                    boostAtt = Attributes.AddAttribute<IBoostAttribute>();
+                }
+
+                internal readonly IBoostAttribute boostAtt;
+
+                protected override AcceptStatus Accept(BytesRef term)
+                {
+                    boostAtt.Boost = Convert.ToSingle(term.Utf8ToString());
+                    return base.Accept(term);
+                }
+            }
+
+            public override string ToString(string field)
+            {
+                return "dummy";
+            }
+        }
+
+        [Test]
+        public virtual void TestBoosts()
+        {
+            CheckBoosts(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+
+            // use a large PQ here to only test boosts and dont mix up when all scores are equal
+            CheckBoosts(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+        }
+
+        private void CheckMaxClauseLimitation(MultiTermQuery.RewriteMethod method, [CallerMemberName] string memberName = "")
+        {
+            int savedMaxClauseCount = BooleanQuery.MaxClauseCount;
+            BooleanQuery.MaxClauseCount = 3;
+
+            MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+            mtq.MultiTermRewriteMethod = (method);
+            try
+            {
+                MultiSearcherDupls.Rewrite(mtq);
+                Assert.Fail("Should throw BooleanQuery.TooManyClauses");
+            }
+            catch (BooleanQuery.TooManyClauses e)
+            {
+                //  Maybe remove this assert in later versions, when internal API changes:
+                Assert.AreEqual("CheckMaxClauseCount", new StackTrace(e, false).GetFrames()[0].GetMethod().Name); //, "Should throw BooleanQuery.TooManyClauses with a stacktrace containing checkMaxClauseCount()");
+            }
+            finally
+            {
+                BooleanQuery.MaxClauseCount = savedMaxClauseCount;
+            }
+        }
+
+        private void CheckNoMaxClauseLimitation(MultiTermQuery.RewriteMethod method)
+        {
+            int savedMaxClauseCount = BooleanQuery.MaxClauseCount;
+            BooleanQuery.MaxClauseCount = 3;
+
+            MultiTermQuery mtq = TermRangeQuery.NewStringRange("data", "2", "7", true, true);
+            mtq.MultiTermRewriteMethod = (method);
+            try
+            {
+                MultiSearcherDupls.Rewrite(mtq);
+            }
+            finally
+            {
+                BooleanQuery.MaxClauseCount = savedMaxClauseCount;
+            }
+        }
+
+        [Test]
+        public virtual void TestMaxClauseLimitations()
+        {
+            CheckMaxClauseLimitation(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
+            CheckMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE);
+
+            CheckNoMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
+            CheckNoMaxClauseLimitation(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
+            CheckNoMaxClauseLimitation(new MultiTermQuery.TopTermsScoringBooleanQueryRewrite(1024));
+            CheckNoMaxClauseLimitation(new MultiTermQuery.TopTermsBoostOnlyBooleanQueryRewrite(1024));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
new file mode 100644
index 0000000..89607cf
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
@@ -0,0 +1,244 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Support;
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+
+namespace Lucene.Net.Search
+{
+    
+    using NUnit.Framework;
+    using System.IO;
+    using Directory = Lucene.Net.Store.Directory;
+    using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+    using English = Lucene.Net.Util.English;
+    using Fields = Lucene.Net.Index.Fields;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+    using IndexWriter = Lucene.Net.Index.IndexWriter;
+    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+    /*
+         * 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.
+         */
+
+    using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+    using Terms = Lucene.Net.Index.Terms;
+    using TermsEnum = Lucene.Net.Index.TermsEnum;
+
+    [TestFixture]
+    public class TestMultiThreadTermVectors : LuceneTestCase
+    {
+        private Directory Directory;
+        public int NumDocs = 100;
+        public int NumThreads = 3;
+
+        [SetUp]
+        public override void SetUp()
+        {
+            base.SetUp();
+            Directory = NewDirectory();
+            IndexWriter writer = new IndexWriter(Directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMergePolicy(NewLogMergePolicy()));
+            //writer.setNoCFSRatio(0.0);
+            //writer.infoStream = System.out;
+            FieldType customType = new FieldType(TextField.TYPE_STORED);
+            customType.IsTokenized = false;
+            customType.StoreTermVectors = true;
+            for (int i = 0; i < NumDocs; i++)
+            {
+                Documents.Document doc = new Documents.Document();
+                Field fld = NewField("field", English.IntToEnglish(i), customType);
+                doc.Add(fld);
+                writer.AddDocument(doc);
+            }
+            writer.Dispose();
+        }
+
+        [TearDown]
+        public override void TearDown()
+        {
+            Directory.Dispose();
+            base.TearDown();
+        }
+
+        [Test]
+        public virtual void Test()
+        {
+            IndexReader reader = null;
+
+            try
+            {
+                reader = DirectoryReader.Open(Directory);
+                for (int i = 1; i <= NumThreads; i++)
+                {
+                    TestTermPositionVectors(reader, i);
+                }
+            }
+            catch (IOException ioe)
+            {
+                Assert.Fail(ioe.Message);
+            }
+            finally
+            {
+                if (reader != null)
+                {
+                    try
+                    {
+                        /// <summary>
+                        /// close the opened reader </summary>
+                        reader.Dispose();
+                    }
+                    catch (IOException ioe)
+                    {
+                        Console.WriteLine(ioe.ToString());
+                        Console.Write(ioe.StackTrace);
+                    }
+                }
+            }
+        }
+
+        public virtual void TestTermPositionVectors(IndexReader reader, int threadCount)
+        {
+            MultiThreadTermVectorsReader[] mtr = new MultiThreadTermVectorsReader[threadCount];
+            for (int i = 0; i < threadCount; i++)
+            {
+                mtr[i] = new MultiThreadTermVectorsReader();
+                mtr[i].Init(reader);
+            }
+
+            // run until all threads finished
+            int threadsAlive = mtr.Length;
+            while (threadsAlive > 0)
+            {
+                //System.out.println("Threads alive");
+                Thread.Sleep(10);
+                threadsAlive = mtr.Length;
+                for (int i = 0; i < mtr.Length; i++)
+                {
+                    if (mtr[i].Alive == true)
+                    {
+                        break;
+                    }
+
+                    threadsAlive--;
+                }
+            }
+
+            long totalTime = 0L;
+            for (int i = 0; i < mtr.Length; i++)
+            {
+                totalTime += mtr[i].TimeElapsed;
+                mtr[i] = null;
+            }
+
+            //System.out.println("threadcount: " + mtr.Length + " average term vector time: " + totalTime/mtr.Length);
+        }
+    }
+
+    internal class MultiThreadTermVectorsReader : IThreadRunnable
+    {
+        private IndexReader Reader = null;
+        private ThreadClass t = null;
+
+        private readonly int RunsToDo = 100;
+        internal long TimeElapsed = 0;
+
+        public virtual void Init(IndexReader reader)
+        {
+            this.Reader = reader;
+            TimeElapsed = 0;
+            t = new ThreadClass(new System.Threading.ThreadStart(this.Run));
+            t.Start();
+        }
+
+        public virtual bool Alive
+        {
+            get
+            {
+                if (t == null)
+                {
+                    return false;
+                }
+
+                return t.IsAlive;
+            }
+        }
+
+        [Test]
+        public void Run()
+        {
+            try
+            {
+                // run the test 100 times
+                for (int i = 0; i < RunsToDo; i++)
+                {
+                    TestTermVectors();
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.ToString());
+                Console.Write(e.StackTrace);
+            }
+            return;
+        }
+
+        private void TestTermVectors()
+        {
+            // check:
+            int numDocs = Reader.NumDocs;
+            long start = 0L;
+            for (int docId = 0; docId < numDocs; docId++)
+            {
+                start = Environment.TickCount;
+                Fields vectors = Reader.GetTermVectors(docId);
+                TimeElapsed += Environment.TickCount - start;
+
+                // verify vectors result
+                VerifyVectors(vectors, docId);
+
+                start = Environment.TickCount;
+                Terms vector = Reader.GetTermVectors(docId).GetTerms("field");
+                TimeElapsed += Environment.TickCount - start;
+
+                VerifyVector(vector.GetIterator(null), docId);
+            }
+        }
+
+        private void VerifyVectors(Fields vectors, int num)
+        {
+            foreach (string field in vectors)
+            {
+                Terms terms = vectors.GetTerms(field);
+                Debug.Assert(terms != null);
+                VerifyVector(terms.GetIterator(null), num);
+            }
+        }
+
+        private void VerifyVector(TermsEnum vector, int num)
+        {
+            StringBuilder temp = new StringBuilder();
+            while (vector.Next() != null)
+            {
+                temp.Append(vector.Term.Utf8ToString());
+            }
+            if (!English.IntToEnglish(num).Trim().Equals(temp.ToString().Trim()))
+            {
+                Console.WriteLine("wrong term result");
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs b/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
new file mode 100644
index 0000000..5c66182
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestMultiValuedNumericRangeQuery.cs
@@ -0,0 +1,88 @@
+using System.Globalization;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+    using NUnit.Framework;
+    using Directory = Lucene.Net.Store.Directory;
+    using Document = Documents.Document;
+    using Field = Field;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+    using Int32Field = Int32Field;
+    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+    /*
+         * 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.
+         */
+
+    using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+    using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+    using TestUtil = Lucene.Net.Util.TestUtil;
+
+    [TestFixture]
+    public class TestMultiValuedNumericRangeQuery : LuceneTestCase
+    {
+        /// <summary>
+        /// Tests NumericRangeQuery on a multi-valued field (multiple numeric values per document).
+        /// this test ensures, that a classical TermRangeQuery returns exactly the same document numbers as
+        /// NumericRangeQuery (see SOLR-1322 for discussion) and the multiple precision terms per numeric value
+        /// do not interfere with multiple numeric values.
+        /// </summary>
+        [Test]
+        public virtual void TestMultiValuedNRQ()
+        {
+            Directory directory = NewDirectory();
+            RandomIndexWriter writer = new RandomIndexWriter(Random(), directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMaxBufferedDocs(TestUtil.NextInt(Random(), 50, 1000)));
+            const string format = "D11";
+
+            int num = AtLeast(500);
+            for (int l = 0; l < num; l++)
+            {
+                Document doc = new Document();
+                for (int m = 0, c = Random().Next(10); m <= c; m++)
+                {
+                    int value = Random().Next(int.MaxValue);
+                    doc.Add(NewStringField("asc", value.ToString(format), Field.Store.NO));
+                    doc.Add(new Int32Field("trie", value, Field.Store.NO));
+                }
+                writer.AddDocument(doc);
+            }
+            IndexReader reader = writer.Reader;
+            writer.Dispose();
+
+            IndexSearcher searcher = NewSearcher(reader);
+            num = AtLeast(50);
+            for (int i = 0; i < num; i++)
+            {
+                int lower = Random().Next(int.MaxValue);
+                int upper = Random().Next(int.MaxValue);
+                if (lower > upper)
+                {
+                    int a = lower;
+                    lower = upper;
+                    upper = a;
+                }
+                TermRangeQuery cq = TermRangeQuery.NewStringRange("asc", lower.ToString(format), upper.ToString(format), true, true);
+                NumericRangeQuery<int> tq = NumericRangeQuery.NewInt32Range("trie", lower, upper, true, true);
+                TopDocs trTopDocs = searcher.Search(cq, 1);
+                TopDocs nrTopDocs = searcher.Search(tq, 1);
+                Assert.AreEqual(trTopDocs.TotalHits, nrTopDocs.TotalHits, "Returned count for NumericRangeQuery and TermRangeQuery must be equal");
+            }
+            reader.Dispose();
+            directory.Dispose();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs b/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
new file mode 100644
index 0000000..c445929
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestNGramPhraseQuery.cs
@@ -0,0 +1,113 @@
+namespace Lucene.Net.Search
+{
+    using NUnit.Framework;
+    using Directory = Lucene.Net.Store.Directory;
+
+    /*
+         * 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.
+         */
+
+    using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+    using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+    using Term = Lucene.Net.Index.Term;
+
+    [TestFixture]
+    public class TestNGramPhraseQuery : LuceneTestCase
+    {
+        private static IndexReader Reader;
+        private static Directory Directory;
+
+        /// <summary>
+        /// LUCENENET specific
+        /// Is non-static because Similarity and TimeZone are not static.
+        /// </summary>
+        [OneTimeSetUp]
+        public void BeforeClass()
+        {
+            Directory = NewDirectory();
+            RandomIndexWriter writer = new RandomIndexWriter(Random(), Directory, Similarity, TimeZone);
+            writer.Dispose();
+            Reader = DirectoryReader.Open(Directory);
+        }
+
+        [OneTimeTearDown]
+        public static void AfterClass()
+        {
+            Reader.Dispose();
+            Reader = null;
+            Directory.Dispose();
+            Directory = null;
+        }
+
+        [Test]
+        public virtual void TestRewrite()
+        {
+            // bi-gram test ABC => AB/BC => AB/BC
+            PhraseQuery pq1 = new NGramPhraseQuery(2);
+            pq1.Add(new Term("f", "AB"));
+            pq1.Add(new Term("f", "BC"));
+
+            Query q = pq1.Rewrite(Reader);
+            Assert.IsTrue(q is NGramPhraseQuery);
+            Assert.AreSame(pq1, q);
+            pq1 = (NGramPhraseQuery)q;
+            Assert.AreEqual(new Term[] { new Term("f", "AB"), new Term("f", "BC") }, pq1.GetTerms());
+            Assert.AreEqual(new int[] { 0, 1 }, pq1.GetPositions());
+
+            // bi-gram test ABCD => AB/BC/CD => AB//CD
+            PhraseQuery pq2 = new NGramPhraseQuery(2);
+            pq2.Add(new Term("f", "AB"));
+            pq2.Add(new Term("f", "BC"));
+            pq2.Add(new Term("f", "CD"));
+
+            q = pq2.Rewrite(Reader);
+            Assert.IsTrue(q is PhraseQuery);
+            Assert.AreNotSame(pq2, q);
+            pq2 = (PhraseQuery)q;
+            Assert.AreEqual(new Term[] { new Term("f", "AB"), new Term("f", "CD") }, pq2.GetTerms());
+            Assert.AreEqual(new int[] { 0, 2 }, pq2.GetPositions());
+
+            // tri-gram test ABCDEFGH => ABC/BCD/CDE/DEF/EFG/FGH => ABC///DEF//FGH
+            PhraseQuery pq3 = new NGramPhraseQuery(3);
+            pq3.Add(new Term("f", "ABC"));
+            pq3.Add(new Term("f", "BCD"));
+            pq3.Add(new Term("f", "CDE"));
+            pq3.Add(new Term("f", "DEF"));
+            pq3.Add(new Term("f", "EFG"));
+            pq3.Add(new Term("f", "FGH"));
+
+            q = pq3.Rewrite(Reader);
+            Assert.IsTrue(q is PhraseQuery);
+            Assert.AreNotSame(pq3, q);
+            pq3 = (PhraseQuery)q;
+            Assert.AreEqual(new Term[] { new Term("f", "ABC"), new Term("f", "DEF"), new Term("f", "FGH") }, pq3.GetTerms());
+            Assert.AreEqual(new int[] { 0, 3, 5 }, pq3.GetPositions());
+
+            // LUCENE-4970: boosting test
+            PhraseQuery pq4 = new NGramPhraseQuery(2);
+            pq4.Add(new Term("f", "AB"));
+            pq4.Add(new Term("f", "BC"));
+            pq4.Add(new Term("f", "CD"));
+            pq4.Boost = 100.0F;
+
+            q = pq4.Rewrite(Reader);
+            Assert.AreNotSame(pq4, q);
+            Assert.AreEqual(pq4.Boost, q.Boost, 0.1f);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Search/TestNot.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Search/TestNot.cs b/src/Lucene.Net.Tests/Search/TestNot.cs
new file mode 100644
index 0000000..99611aa
--- /dev/null
+++ b/src/Lucene.Net.Tests/Search/TestNot.cs
@@ -0,0 +1,65 @@
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Search
+{
+    using NUnit.Framework;
+    using Directory = Lucene.Net.Store.Directory;
+    using Document = Documents.Document;
+
+    /*
+         * 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.
+         */
+
+    using Field = Field;
+    using IndexReader = Lucene.Net.Index.IndexReader;
+    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+    using RandomIndexWriter = Lucene.Net.Index.RandomIndexWriter;
+    using Term = Lucene.Net.Index.Term;
+
+    /// <summary>
+    /// Similarity unit test.
+    ///
+    ///
+    /// </summary>
+    [TestFixture]
+    public class TestNot : LuceneTestCase
+    {
+        [Test]
+        public virtual void TestNot_Mem()
+        {
+            Directory store = NewDirectory();
+            RandomIndexWriter writer = new RandomIndexWriter(Random(), store, Similarity, TimeZone);
+
+            Document d1 = new Document();
+            d1.Add(NewTextField("field", "a b", Field.Store.YES));
+
+            writer.AddDocument(d1);
+            IndexReader reader = writer.Reader;
+
+            IndexSearcher searcher = NewSearcher(reader);
+
+            BooleanQuery query = new BooleanQuery();
+            query.Add(new TermQuery(new Term("field", "a")), Occur.SHOULD);
+            query.Add(new TermQuery(new Term("field", "b")), Occur.MUST_NOT);
+
+            ScoreDoc[] hits = searcher.Search(query, null, 1000).ScoreDocs;
+            Assert.AreEqual(0, hits.Length);
+            writer.Dispose();
+            reader.Dispose();
+            store.Dispose();
+        }
+    }
+}
\ No newline at end of file