You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by mh...@apache.org on 2013/09/24 20:32:41 UTC

[05/50] [abbrv] git commit: Port: more util unit tests

Port: more util unit tests


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

Branch: refs/heads/branch_4x
Commit: 06f5d4b8bc7a979b87831ba843bd936bc5d27055
Parents: d3c00f5
Author: James Blair <jm...@gmail.com>
Authored: Thu Jul 11 16:33:12 2013 -0400
Committer: James Blair <jm...@gmail.com>
Committed: Thu Jul 11 16:33:12 2013 -0400

----------------------------------------------------------------------
 test/core/Support/RandomExtensions.cs      |    9 +-
 test/core/Util/TestDoubleBarrelLRUCache.cs |   12 +-
 test/core/Util/TestIOUtils.cs              |  104 +++
 test/core/Util/TestIntsRef.cs              |   33 +
 test/core/Util/TestMaxFailureRule.cs       |   98 +++
 test/core/Util/TestNamedSPILoader.cs       |   32 +
 test/core/Util/TestNumericUtils.cs         | 1040 ++++++++++++-----------
 test/core/Util/TestOpenBitSet.cs           |  273 +++---
 test/core/Util/TestPagedBytes.cs           |  131 +++
 9 files changed, 1137 insertions(+), 595 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Support/RandomExtensions.cs
----------------------------------------------------------------------
diff --git a/test/core/Support/RandomExtensions.cs b/test/core/Support/RandomExtensions.cs
index 49625e5..8ec476d 100644
--- a/test/core/Support/RandomExtensions.cs
+++ b/test/core/Support/RandomExtensions.cs
@@ -23,14 +23,7 @@ namespace Lucene.Net.Test.Support
 
         public static bool NextBool(this Random random)
         {
-            var randInt = random.Next();
-            var adjusted = randInt - (int.MaxValue/2);
-            if (adjusted == 0)
-            {
-                BoolTieBreak = !BoolTieBreak;
-                return BoolTieBreak;
-            }
-            return adjusted > 0 ? true : false;
+            return random.NextDouble() > 0.5;
         }
 
         public static void NextBytes(this Random random, sbyte[] bytes)

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestDoubleBarrelLRUCache.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestDoubleBarrelLRUCache.cs b/test/core/Util/TestDoubleBarrelLRUCache.cs
index fabe4ab..d7d4408 100644
--- a/test/core/Util/TestDoubleBarrelLRUCache.cs
+++ b/test/core/Util/TestDoubleBarrelLRUCache.cs
@@ -21,7 +21,7 @@ namespace Lucene.Net.Test.Util
             // access every 2nd item in cache
             for (var i = 0; i < n; i += 2)
             {
-                assertNotNull(cache[new CloneableInteger(i)]);
+                Assert.NotNull(cache[new CloneableInteger(i)]);
             }
 
             // add n/2 elements to cache, the ones that weren't
@@ -34,7 +34,7 @@ namespace Lucene.Net.Test.Util
             // access every 4th item in cache
             for (var i = 0; i < n; i += 4)
             {
-                assertNotNull(cache[new CloneableInteger(i)]);
+                Assert.NotNull(cache[new CloneableInteger(i)]);
             }
 
             // add 3/4n elements to cache, the ones that weren't
@@ -47,12 +47,12 @@ namespace Lucene.Net.Test.Util
             // access every 4th item in cache
             for (var i = 0; i < n; i += 4)
             {
-                assertNotNull(cache[new CloneableInteger(i)]);
+                Assert.NotNull(cache[new CloneableInteger(i)]);
             }
         }
 
         [Test]
-        public void TestLRUCache()
+        public virtual void TestLRUCache()
         {
             var n = 100;
             TestCache(new DoubleBarrelLRUCache<CloneableInteger, object>(n), n);
@@ -121,14 +121,14 @@ namespace Lucene.Net.Test.Util
         }
 
         long totMiss, totHit;
-        void AddResults(long miss, long hit)
+        internal virtual void AddResults(long miss, long hit)
         {
             totMiss += miss;
             totHit += hit;
         }
 
         [Test]
-        public void TestThreadCorrectness()
+        public virtual void TestThreadCorrectness()
         {
             var NUM_THREADS = 4;
             var CACHE_SIZE = 512;

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestIOUtils.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestIOUtils.cs b/test/core/Util/TestIOUtils.cs
new file mode 100644
index 0000000..0a6a56e
--- /dev/null
+++ b/test/core/Util/TestIOUtils.cs
@@ -0,0 +1,104 @@
+using System;
+using System.IO;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestIOUtils : LuceneTestCase
+    {
+        internal sealed class BrokenCloseable : IDisposable
+        {
+            internal readonly int i;
+
+            public BrokenCloseable(int i)
+            {
+                this.i = i;
+            }
+
+            public void Dispose()
+            {
+                throw new IOException("TEST-IO-EXCEPTION-" + i);
+            }
+        }
+
+        internal sealed class TestException : Exception
+        {
+            public TestException()
+                : base("BASE-EXCEPTION") { }
+        }
+
+        [Test]
+        public virtual void TestSuppressedExceptions()
+        {
+            if (!Constants.JRE_IS_MINIMUM_JAVA7)
+            {
+                Console.Error.WriteLine("WARNING: TestIOUtils.TestSuppressedExceptions: Full test coverage only with Java 7, as suppressed exception recording is not supported before.");
+            }
+
+            // test with prior exception
+            try
+            {
+                var t = new TestException();
+                IOUtils.CloseWhileHandlingException(t, new BrokenCloseable(1), new BrokenCloseable(2));
+            }
+            catch (TestException e1)
+            {
+                assertEquals("BASE-EXCEPTION", e1.Message);
+                var sw = new StringWriter();
+                //PrintWriter pw = new PrintWriter(sw);
+                sw.Write(e1.StackTrace);
+                //e1.PrintStackTrace(pw);
+                //pw.Flush();
+                var trace = sw.ToString();
+                if (VERBOSE)
+                {
+                    Console.WriteLine("TestIOUtils.testSuppressedExceptions: Thrown Exception stack trace:");
+                    Console.WriteLine(trace);
+                }
+                if (Constants.JRE_IS_MINIMUM_JAVA7)
+                {
+                    assertTrue("Stack trace does not contain first suppressed Exception: " + trace,
+                      trace.Contains("java.io.IOException: TEST-IO-EXCEPTION-1"));
+                    assertTrue("Stack trace does not contain second suppressed Exception: " + trace,
+                      trace.Contains("java.io.IOException: TEST-IO-EXCEPTION-2"));
+                }
+            }
+            catch (IOException e2)
+            {
+                Fail("IOException should not be thrown here");
+            }
+
+            // test without prior exception
+            try
+            {
+                IOUtils.CloseWhileHandlingException((TestException)null, new BrokenCloseable(1), new BrokenCloseable(2));
+            }
+            catch (TestException e1)
+            {
+                Fail("TestException should not be thrown here");
+            }
+            catch (IOException e2)
+            {
+                assertEquals("TEST-IO-EXCEPTION-1", e2.Message);
+                var sw = new StringWriter();
+                //PrintWriter pw = new PrintWriter(sw);
+                sw.Write(e2.StackTrace);
+                //e2.printStackTrace(pw);
+                //pw.Flush();
+                var trace = sw.ToString();
+                if (VERBOSE)
+                {
+                    Console.WriteLine("TestIOUtils.testSuppressedExceptions: Thrown Exception stack trace:");
+                    Console.WriteLine(trace);
+                }
+                if (Constants.JRE_IS_MINIMUM_JAVA7)
+                {
+                    assertTrue("Stack trace does not contain suppressed Exception: " + trace,
+                      trace.Contains("java.io.IOException: TEST-IO-EXCEPTION-2"));
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestIntsRef.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestIntsRef.cs b/test/core/Util/TestIntsRef.cs
new file mode 100644
index 0000000..3d12c9d
--- /dev/null
+++ b/test/core/Util/TestIntsRef.cs
@@ -0,0 +1,33 @@
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestIntsRef : LuceneTestCase
+    {
+        [Test]
+        public virtual void TestEmpty()
+        {
+            var i = new IntsRef();
+            Assert.Equals(IntsRef.EMPTY_INTS, i.ints);
+            Assert.Equals(0, i.offset);
+            Assert.Equals(0, i.length);
+        }
+
+        [Test]
+        public virtual void TestFromInts()
+        {
+            var ints = new int[] { 1, 2, 3, 4 };
+            var i = new IntsRef(ints, 0, 4);
+            Assert.Equals(ints, i.ints);
+            Assert.Equals(0, i.offset);
+            Assert.Equals(4, i.length);
+
+            var i2 = new IntsRef(ints, 1, 3);
+            Assert.Equals(new IntsRef(new int[] { 2, 3, 4 }, 0, 3), i2);
+
+            Assert.IsFalse(i.Equals(i2));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestMaxFailureRule.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestMaxFailureRule.cs b/test/core/Util/TestMaxFailureRule.cs
new file mode 100644
index 0000000..effae23
--- /dev/null
+++ b/test/core/Util/TestMaxFailureRule.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Text;
+using Lucene.Net.Store;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestMaxFailureRule : WithNestedTests
+    {
+        public SystemPropertiesRestoreRule restoreSysProps = new SystemPropertiesRestoreRule();
+
+        public TestMaxFailureRule() : base(true) { }
+
+        public class Nested : WithNestedTests.AbstractNestedTest
+        {
+            public const int TOTAL_ITERS = 500;
+            public const int DESIRED_FAILURES = TOTAL_ITERS / 10;
+            private int numFails = 0;
+            private int numIters = 0;
+
+            [Repeat(TOTAL_ITERS)]
+            [Test]
+            public void testFailSometimes()
+            {
+                numIters++;
+                bool fail = new Random().Next(5) == 0;
+                if (fail) numFails++;
+                // some seeds are really lucky ... so cheat.
+                if (numFails < DESIRED_FAILURES &&
+                    DESIRED_FAILURES <= TOTAL_ITERS - numIters)
+                {
+                    fail = true;
+                }
+                Assert.IsFalse(fail);
+            }
+        }
+
+        private sealed class AnonymousRunListener : RunListener
+        {
+            internal char lastTest;
+
+            public override void TestStarted(Description description)
+            {
+                lastTest = 'S'; // success.
+            }
+
+            public override void TestAssumptionFailure(MockRAMDirectory.Failure failure)
+            {
+                lastTest = 'A'; // assumption failure.
+            }
+
+            public override void TestFailure(MockRAMDirectory.Failure failure)
+            {
+                lastTest = 'F'; // failure
+            }
+
+            public override void TestFinished(Description description)
+            {
+                results.append(lastTest);
+            }
+        }
+
+        [Test]
+        public virtual void TestMaxFailures()
+        {
+            int maxFailures = LuceneTestCase.IgnoreAfterMaxFailures.maxFailures;
+            int failuresSoFar = LuceneTestCase.IgnoreAfterMaxFailures.failuresSoFar;
+            System.clearProperty(SysGlobals.SYSPROP_ITERATIONS());
+            try
+            {
+                LuceneTestCase.IgnoreAfterMaxFailures.maxFailures = 2;
+                LuceneTestCase.IgnoreAfterMaxFailures.failuresSoFar = 0;
+
+                JUnitCore core = new JUnitCore();
+                var results = new StringBuilder();
+                core.AddListener(new AnonymousRunListener());
+
+                Result result = core.Run(typeof(Nested)); // was Nested.class
+                Assert.Equals(500, result.RunCount);
+                Assert.Equals(0, result.IgnoreCount);
+                Assert.Equals(2, result.FailureCount);
+
+                // Make sure we had exactly two failures followed by assumption-failures
+                // resulting from ignored tests.
+                Assert.IsTrue(results.ToString(),
+                    results.ToString().Matches("(S*F){2}A+"));
+
+            }
+            finally
+            {
+                LuceneTestCase.IgnoreAfterMaxFailures.maxFailures = maxFailures;
+                LuceneTestCase.IgnoreAfterMaxFailures.failuresSoFar = failuresSoFar;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestNamedSPILoader.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestNamedSPILoader.cs b/test/core/Util/TestNamedSPILoader.cs
new file mode 100644
index 0000000..896102f
--- /dev/null
+++ b/test/core/Util/TestNamedSPILoader.cs
@@ -0,0 +1,32 @@
+using System;
+using Lucene.Net.Codecs;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestNamedSPILoader : LuceneTestCase
+    {
+        [Test]
+        public virtual void TestLookup()
+        {
+            var codec = Codec.ForName("Lucene42");
+            assertEquals("Lucene42", codec.Name);
+        }
+
+        // we want an exception if its not found.
+        [Test]
+        public virtual void TestBogusLookup()
+        {
+            Assert.Throws<ArgumentException>(() => Codec.ForName("dskfdskfsdfksdfdsf"));
+        }
+
+        [Test]
+        public virtual void TestAvailableServices()
+        {
+            var codecs = Codec.AvailableCodecs;
+            Assert.IsTrue(codecs.Contains("Lucene42"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestNumericUtils.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestNumericUtils.cs b/test/core/Util/TestNumericUtils.cs
index c2064a5..0140d9a 100644
--- a/test/core/Util/TestNumericUtils.cs
+++ b/test/core/Util/TestNumericUtils.cs
@@ -17,388 +17,443 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using Lucene.Net.Support;
+using Lucene.Net.Test.Support;
 using NUnit.Framework;
 
 namespace Lucene.Net.Util
 {
-	
     [TestFixture]
-	public class TestNumericUtils:LuceneTestCase
-	{
-		private class AnonymousClassLongRangeBuilder:NumericUtils.LongRangeBuilder
-		{
-			public AnonymousClassLongRangeBuilder(long lower, long upper, bool useBitSet, Lucene.Net.Util.OpenBitSet bits, System.Collections.IEnumerator neededBounds, System.Collections.IEnumerator neededShifts,TestNumericUtils enclosingInstance)
-			{
-				InitBlock(lower, upper, useBitSet, bits, neededBounds, neededShifts, enclosingInstance);
-			}
-			private void  InitBlock(long lower, long upper, bool useBitSet, Lucene.Net.Util.OpenBitSet bits, System.Collections.IEnumerator neededBounds, System.Collections.IEnumerator neededShifts,TestNumericUtils enclosingInstance)
-			{
-				this.lower = lower;
-				this.upper = upper;
-				this.useBitSet = useBitSet;
-				this.bits = bits;
-				this.neededBounds = neededBounds;
-                this.neededShifts = neededShifts;
-				this.enclosingInstance = enclosingInstance;
-			}
-			private long lower;
-			private long upper;
-			private bool useBitSet;
-			private Lucene.Net.Util.OpenBitSet bits;
-			private System.Collections.IEnumerator neededBounds;
-            private System.Collections.IEnumerator neededShifts;
-			private TestNumericUtils enclosingInstance;
-			public TestNumericUtils Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			//@Override
-			public override void  AddRange(long min, long max, int shift)
-			{
-				Assert.IsTrue(min >= lower && min <= upper && max >= lower && max <= upper, "min, max should be inside bounds");
-				if (useBitSet)
-					for (long l = min; l <= max; l++)
-					{
-						Assert.IsFalse(bits.GetAndSet(l - lower), "ranges should not overlap");
-                        // extra exit condition to prevent overflow on MAX_VALUE
-                        if (l == max) break;
-					}
-                if (neededBounds == null || neededShifts == null) return;
-				// make unsigned longs for easier display and understanding
-				min ^= unchecked((long) 0x8000000000000000L);
-				max ^= unchecked((long) 0x8000000000000000L);
-				//System.out.println("Long.valueOf(0x"+Long.toHexString(min>>>shift)+"L),Long.valueOf(0x"+Long.toHexString(max>>>shift)+"L)/*shift="+shift+"*/,");
-                neededShifts.MoveNext();
-                Assert.AreEqual(((Int32)neededShifts.Current), shift, "shift");
-                neededBounds.MoveNext();
-                unchecked
+    public class TestNumericUtils : LuceneTestCase
+    {
+        [Test]
+        public virtual void TestLongConversionAndOrdering()
+        {
+            // generate a series of encoded longs, each numerical one bigger than the one before
+            BytesRef last = null, act = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+            for (var l = -100000L; l < 100000L; l++)
+            {
+                NumericUtils.LongToPrefixCodedBytes(l, 0, act);
+                if (last != null)
                 {
-                    Assert.AreEqual((long)neededBounds.Current, Number.URShift(min, shift), "inner min bound");
-                    neededBounds.MoveNext();
-                    Assert.AreEqual((long)neededBounds.Current, Number.URShift(max, shift), "inner max bound");
+                    // test if smaller
+                    Assert.IsTrue(last.CompareTo(act) < 0, "actual bigger than last (BytesRef)");
+                    Assert.IsTrue(last.Utf8ToString().CompareTo(act.Utf8ToString()) < 0, "actual bigger than last (as string)");
                 }
-			}
-		}
-
-		private class AnonymousClassIntRangeBuilder:NumericUtils.IntRangeBuilder
-		{
-            public AnonymousClassIntRangeBuilder(int lower, int upper, bool useBitSet, Lucene.Net.Util.OpenBitSet bits, IEnumerator<int> neededBounds, IEnumerator<int> neededShifts, TestNumericUtils enclosingInstance)
-			{
-                InitBlock(lower, upper, useBitSet, bits, neededBounds, neededShifts,enclosingInstance);
-			}
-            private void InitBlock(int lower, int upper, bool useBitSet, Lucene.Net.Util.OpenBitSet bits, IEnumerator<int> neededBounds, IEnumerator<int> neededShifts, TestNumericUtils enclosingInstance)
-			{
-				this.lower = lower;
-				this.upper = upper;
-				this.useBitSet = useBitSet;
-				this.bits = bits;
-				this.neededBounds = neededBounds;
-                this.neededShifts = neededShifts;
-				this.enclosingInstance = enclosingInstance;
-			}
-			private int lower;
-			private int upper;
-			private bool useBitSet;
-			private Lucene.Net.Util.OpenBitSet bits;
-            private IEnumerator<int> neededBounds;
-            private IEnumerator<int> neededShifts;
-			private TestNumericUtils enclosingInstance;
-			public TestNumericUtils Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			//@Override
-			public override void  AddRange(int min, int max, int shift)
-			{
-				Assert.IsTrue(min >= lower && min <= upper && max >= lower && max <= upper, "min, max should be inside bounds");
-				if (useBitSet)
-					for (int i = min; i <= max; i++)
-					{
-						Assert.IsFalse(bits.GetAndSet(i - lower), "ranges should not overlap");
-                        // extra exit condition to prevent overflow on MAX_VALUE
-                        if (i == max) break;
-					}
-                if (neededBounds == null) return;
-				// make unsigned ints for easier display and understanding
-				min ^= unchecked((int) 0x80000000);
-				max ^= unchecked((int) 0x80000000);
-                neededShifts.MoveNext();
-                Assert.AreEqual(((int)neededShifts.Current), shift,"shift");
-				//System.out.println("new Integer(0x"+Integer.toHexString(min>>>shift)+"),new Integer(0x"+Integer.toHexString(max>>>shift)+"),");
-                neededBounds.MoveNext();
-				Assert.AreEqual(((System.Int32) neededBounds.Current), Number.URShift(min, shift), "inner min bound");
-                neededBounds.MoveNext();
-				Assert.AreEqual(((System.Int32) neededBounds.Current), Number.URShift(max, shift), "inner max bound");
-			}
-		}
-		
+                // test is back and forward conversion works
+                Assert.IsTrue(l.Equals(NumericUtils.PrefixCodedToLong(act)), "forward and back conversion should generate same long");
+                //Assert.Equals("forward and back conversion should generate same long", l,
+                             //NumericUtils.PrefixCodedToLong(act));
+                // next step
+                last = act;
+                act = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+            }
+        }
+
         [Test]
-		public virtual void  TestLongConversionAndOrdering()
-		{
-			// generate a series of encoded longs, each numerical one bigger than the one before
-			System.String last = null;
-			for (long l = - 100000L; l < 100000L; l++)
-			{
-				System.String act = NumericUtils.LongToPrefixCoded(l);
-				if (last != null)
-				{
-					// test if smaller
-					Assert.IsTrue(String.CompareOrdinal(last, act) < 0, "actual bigger than last");
-				}
-				// test is back and forward conversion works
-				Assert.AreEqual(l, NumericUtils.PrefixCodedToLong(act), "forward and back conversion should generate same long");
-				// next step
-				last = act;
-			}
-		}
-		
+        public virtual void TestIntConversionAndOrdering()
+        {
+            // generate a series of encoded ints, each numerical one bigger than the one before
+            BytesRef last = null, act = new BytesRef(NumericUtils.BUF_SIZE_INT);
+            for (var i = -100000; i < 100000; i++)
+            {
+                NumericUtils.IntToPrefixCodedBytes(i, 0, act);
+                if (last != null)
+                {
+                    // test if smaller
+                    Assert.IsTrue(last.CompareTo(act) < 0, "actual bigger than last (BytesRef)");
+                    Assert.IsTrue(last.Utf8ToString().CompareTo(act.Utf8ToString()) < 0, "actual bigger than last (as string)");
+                }
+                // test is back and forward conversion works
+                Assert.IsTrue(i.Equals(NumericUtils.PrefixCodedToInt(act)), "forward and back conversion should generate same int");
+                //Assert.Equals("forward and back conversion should generate same int", i,
+                             //NumericUtils.PrefixCodedToInt(act));
+                // next step
+                last = act;
+                act = new BytesRef(NumericUtils.BUF_SIZE_INT);
+            }
+        }
+
+        [Test]
+        public virtual void TestLongSpecialValues()
+        {
+            var vals = new long[]
+                {
+                    long.MinValue, long.MinValue + 1, long.MinValue + 2, -5003400000000L,
+                    -4000L, -3000L, -2000L, -1000L, -1L, 0L, 1L, 10L, 300L, 50006789999999999L, long.MaxValue - 2,
+                    long.MaxValue - 1, long.MaxValue
+                };
+            var prefixVals = new BytesRef[vals.Length];
+
+            for (var i = 0; i < vals.Length; i++)
+            {
+                prefixVals[i] = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+                NumericUtils.LongToPrefixCodedBytes(vals[i], 0, prefixVals[i]);
+
+                // check forward and back conversion
+                Assert.IsTrue(vals[i].Equals(NumericUtils.PrefixCodedToLong(prefixVals[i])), "forward and back conversion should generate same long");
+                //.Equals("forward and back conversion should generate same long", vals[i],
+                             //NumericUtils.PrefixCodedToLong(prefixVals[i]));
+
+                Assert.Throws<FormatException>(() => NumericUtils.PrefixCodedToInt(prefixVals[i]),
+                                               "decoding a prefix coded long value as int should fail");
+            }
+
+            // check sort order (prefixVals should be ascending)
+            for (var i = 1; i < prefixVals.Length; i++)
+            {
+                Assert.IsTrue(prefixVals[i - 1].CompareTo(prefixVals[i]) < 0, "check sort order");
+            }
+
+            // check the prefix encoding, lower precision should have the difference to original value equal to the lower removed bits
+            var bytesRef = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+            foreach (var t in vals)
+            {
+                for (var j = 0; j < 64; j++)
+                {
+                    NumericUtils.LongToPrefixCodedBytes(t, j, bytesRef);
+                    var prefixVal = NumericUtils.PrefixCodedToLong(bytesRef);
+                    var mask = (1L << j) - 1L;
+                    Assert.IsTrue((t & mask).Equals(t - prefixVal), "difference between prefix val and original value for " + t + " with shift=" + j);
+                    //Assert.Equals(t & mask, t - prefixVal); //, "difference between prefix val and original value for " + t + " with shift=" + j);
+                }
+            }
+        }
+
         [Test]
-		public virtual void  TestIntConversionAndOrdering()
-		{
-			// generate a series of encoded ints, each numerical one bigger than the one before
-			System.String last = null;
-			for (int i = - 100000; i < 100000; i++)
-			{
-				System.String act = NumericUtils.IntToPrefixCoded(i);
-				if (last != null)
-				{
-					// test if smaller
-					Assert.IsTrue(String.CompareOrdinal(last, act) < 0, "actual bigger than last");
-				}
-				// test is back and forward conversion works
-				Assert.AreEqual(i, NumericUtils.PrefixCodedToInt(act), "forward and back conversion should generate same int");
-				// next step
-				last = act;
-			}
-		}
-		
+        public virtual void TestIntSpecialValues()
+        {
+            var vals = new int[]
+                {
+                    int.MinValue, int.MinValue + 1, int.MinValue + 2, -64765767,
+                    -4000, -3000, -2000, -1000, -1, 0, 1, 10, 300, 765878989, int.MaxValue - 2, int.MaxValue - 1,
+                    int.MaxValue
+                };
+            var prefixVals = new BytesRef[vals.Length];
+
+            for (var i = 0; i < vals.Length; i++)
+            {
+                prefixVals[i] = new BytesRef(NumericUtils.BUF_SIZE_INT);
+                NumericUtils.IntToPrefixCodedBytes(vals[i], 0, prefixVals[i]);
+
+                // check forward and back conversion
+                Assert.Equals(vals[i], NumericUtils.PrefixCodedToInt(prefixVals[i])); //"forward and back conversion should generate same int", 
+
+                Assert.Throws<FormatException>(() => NumericUtils.PrefixCodedToLong(prefixVals[i]), "decoding a prefix coded int value as long should fail");
+            }
+
+            // check sort order (prefixVals should be ascending)
+            for (var i = 1; i < prefixVals.Length; i++)
+            {
+                Assert.IsTrue(prefixVals[i - 1].CompareTo(prefixVals[i]) < 0, "check sort order");
+            }
+
+            // check the prefix encoding, lower precision should have the difference to original value equal to the lower removed bits
+            var bytesRef = new BytesRef(NumericUtils.BUF_SIZE_LONG);
+            foreach (var t in vals)
+            {
+                for (var j = 0; j < 32; j++)
+                {
+                    NumericUtils.IntToPrefixCodedBytes(t, j, bytesRef);
+                    var prefixVal = NumericUtils.PrefixCodedToInt(bytesRef);
+                    var mask = (1 << j) - 1;
+                    Assert.IsTrue((t & mask).Equals(t - prefixVal), 
+                                  "difference between prefix val and original value for " + t + " with shift=" + j);
+                    //Assert.Equals(
+                    // "difference between prefix val and original value for " + vals[i] + " with shift=" + j,
+                    // vals[i] & mask, vals[i] - prefixVal);
+                }
+            }
+        }
+
         [Test]
-		public virtual void  TestLongSpecialValues()
-		{
-			long[] vals = new long[]{System.Int64.MinValue, System.Int64.MinValue + 1, System.Int64.MinValue + 2, - 5003400000000L, - 4000L, - 3000L, - 2000L, - 1000L, - 1L, 0L, 1L, 10L, 300L, 50006789999999999L, System.Int64.MaxValue - 2, System.Int64.MaxValue - 1, System.Int64.MaxValue};
-			System.String[] prefixVals = new System.String[vals.Length];
-			
-			for (int i = 0; i < vals.Length; i++)
-			{
-				prefixVals[i] = NumericUtils.LongToPrefixCoded(vals[i]);
-				
-				// check forward and back conversion
-				Assert.AreEqual(vals[i], NumericUtils.PrefixCodedToLong(prefixVals[i]), "forward and back conversion should generate same long");
-				
-				// test if decoding values as int fails correctly
-			    Assert.Throws<FormatException>(() => NumericUtils.PrefixCodedToInt(prefixVals[i]),
-			                                   "decoding a prefix coded long value as int should fail");
-			}
-			
-			// check sort order (prefixVals should be ascending)
-			for (int i = 1; i < prefixVals.Length; i++)
-			{
-				Assert.IsTrue(String.CompareOrdinal(prefixVals[i - 1], prefixVals[i]) < 0, "check sort order");
-			}
-			
-			// check the prefix encoding, lower precision should have the difference to original value equal to the lower removed bits
-			for (int i = 0; i < vals.Length; i++)
-			{
-				for (int j = 0; j < 64; j++)
-				{
-					long prefixVal = NumericUtils.PrefixCodedToLong(NumericUtils.LongToPrefixCoded(vals[i], j));
-					long mask = (1L << j) - 1L;
-					Assert.AreEqual(vals[i] & mask, vals[i] - prefixVal, "difference between prefix val and original value for " + vals[i] + " with shift=" + j);
-				}
-			}
-		}
-		
+        public virtual void TestDoubles()
+        {
+            var vals = new double[]
+                {
+                    double.NegativeInfinity, -2.3E25, -1.0E15, -1.0, -1.0E-1, -1.0E-2, -0.0,
+                    +0.0, 1.0E-2, 1.0E-1, 1.0, 1.0E15, 2.3E25, double.PositiveInfinity, double.NaN
+                };
+            var longVals = new long[vals.Length];
+
+            // check forward and back conversion
+            for (var i = 0; i < vals.Length; i++)
+            {
+                longVals[i] = NumericUtils.DoubleToSortableLong(vals[i]);
+                Assert.IsTrue(vals[i].CompareTo(NumericUtils.SortableLongToDouble(longVals[i])) == 0,
+                    "forward and back conversion should generate same double");
+                           //double.Compare(vals[i], NumericUtils.SortableLongToDouble(longVals[i])) == 0);
+            }
+
+            // check sort order (prefixVals should be ascending)
+            for (var i = 1; i < longVals.Length; i++)
+            {
+                Assert.IsTrue(longVals[i - 1] < longVals[i], "check sort order");
+            }
+        }
+
+        public static readonly double[] DOUBLE_NANs =
+            {
+                double.NaN,
+                double.LongBitsToDouble(0x7ff0000000000001L),
+                double.LongBitsToDouble(0x7fffffffffffffffL),
+                double.LongBitsToDouble(0xfff0000000000001L),
+                double.LongBitsToDouble(0xffffffffffffffffL)
+            };
+
         [Test]
-		public virtual void  TestIntSpecialValues()
-		{
-			int[] vals = new int[]{System.Int32.MinValue, System.Int32.MinValue + 1, System.Int32.MinValue + 2, - 64765767, - 4000, - 3000, - 2000, - 1000, - 1, 0, 1, 10, 300, 765878989, System.Int32.MaxValue - 2, System.Int32.MaxValue - 1, System.Int32.MaxValue};
-			System.String[] prefixVals = new System.String[vals.Length];
-			
-			for (int i = 0; i < vals.Length; i++)
-			{
-				prefixVals[i] = NumericUtils.IntToPrefixCoded(vals[i]);
-				
-				// check forward and back conversion
-				Assert.AreEqual(vals[i], NumericUtils.PrefixCodedToInt(prefixVals[i]), "forward and back conversion should generate same int");
-				
-				// test if decoding values as long fails correctly
-			    Assert.Throws<FormatException>(() => NumericUtils.PrefixCodedToLong(prefixVals[i]),
-			                                   "decoding a prefix coded int value as long should fail");
-			}
-			
-			// check sort order (prefixVals should be ascending)
-			for (int i = 1; i < prefixVals.Length; i++)
-			{
-				Assert.IsTrue(String.CompareOrdinal(prefixVals[i - 1], prefixVals[i]) < 0, "check sort order");
-			}
-			
-			// check the prefix encoding, lower precision should have the difference to original value equal to the lower removed bits
-			for (int i = 0; i < vals.Length; i++)
-			{
-				for (int j = 0; j < 32; j++)
-				{
-					int prefixVal = NumericUtils.PrefixCodedToInt(NumericUtils.IntToPrefixCoded(vals[i], j));
-					int mask = (1 << j) - 1;
-					Assert.AreEqual(vals[i] & mask, vals[i] - prefixVal, "difference between prefix val and original value for " + vals[i] + " with shift=" + j);
-				}
-			}
-		}
-		
+        public virtual void TestSortableDoubleNaN()
+        {
+            var plusInf = NumericUtils.DoubleToSortableLong(double.PositiveInfinity);
+            foreach (var nan in DOUBLE_NANs)
+            {
+                Assert.IsTrue(double.IsNaN(nan));
+                var sortable = NumericUtils.DoubleToSortableLong(nan);
+                Assert.IsTrue(sortable > plusInf,
+                    "double not sorted correctly: " + nan + ", long repr: "
+                           + sortable + ", positive inf.: " + plusInf);
+            }
+        }
+
         [Test]
-		public virtual void  TestDoubles()
-		{
-			double[] vals = new double[]{System.Double.NegativeInfinity, - 2.3e25, - 1.0e15, - 1.0, - 1.0e-1, - 1.0e-2, - 0.0, + 0.0, 1.0e-2, 1.0e-1, 1.0, 1.0e15, 2.3e25, System.Double.PositiveInfinity};
-			long[] longVals = new long[vals.Length];
-			
-			// check forward and back conversion
-			for (int i = 0; i < vals.Length; i++)
-			{
-				longVals[i] = NumericUtils.DoubleToSortableLong(vals[i]);
-				Assert.IsTrue(vals[i].CompareTo(NumericUtils.SortableLongToDouble(longVals[i])) == 0, "forward and back conversion should generate same double");
-			}
-			
-			// check sort order (prefixVals should be ascending)
-			for (int i = 1; i < longVals.Length; i++)
-			{
-				Assert.IsTrue(longVals[i - 1] < longVals[i], "check sort order");
-			}
-		}
-		
+        public virtual void TestFloats()
+        {
+            var vals = new float[]
+                {
+                    float.NegativeInfinity, -2.3E25f, -1.0E15f, -1.0f, -1.0E-1f, -1.0E-2f, -0.0f,
+                    +0.0f, 1.0E-2f, 1.0E-1f, 1.0f, 1.0E15f, 2.3E25f, float.PositiveInfinity, float.NaN
+                };
+            var intVals = new int[vals.Length];
+
+            // check forward and back conversion
+            for (var i = 0; i < vals.Length; i++)
+            {
+                intVals[i] = NumericUtils.FloatToSortableInt(vals[i]);
+                Assert.IsTrue(vals[i].CompareTo(NumericUtils.SortableIntToFloat(intVals[i])) == 0,
+                    "forward and back conversion should generate same double");
+            }
+
+            // check sort order (prefixVals should be ascending)
+            for (var i = 1; i < intVals.Length; i++)
+            {
+                Assert.IsTrue(intVals[i - 1] < intVals[i], "check sort order");
+            }
+        }
+
+        public static readonly float[] FLOAT_NANs =
+            {
+                float.NaN,
+                float.IntBitsToFloat(0x7f800001),
+                float.IntBitsToFloat(0x7fffffff),
+                float.IntBitsToFloat(0xff800001),
+                float.IntBitsToFloat(0xffffffff)
+            };
+
         [Test]
-		public virtual void  TestFloats()
-		{
-			float[] vals = new float[]{System.Single.NegativeInfinity, - 2.3e25f, - 1.0e15f, - 1.0f, - 1.0e-1f, - 1.0e-2f, - 0.0f, + 0.0f, 1.0e-2f, 1.0e-1f, 1.0f, 1.0e15f, 2.3e25f, System.Single.PositiveInfinity};
-			int[] intVals = new int[vals.Length];
-			
-			// check forward and back conversion
-			for (int i = 0; i < vals.Length; i++)
-			{
-				intVals[i] = NumericUtils.FloatToSortableInt(vals[i]);
-				Assert.IsTrue(vals[i].CompareTo(NumericUtils.SortableIntToFloat(intVals[i])) == 0, "forward and back conversion should generate same double");
-			}
-			
-			// check sort order (prefixVals should be ascending)
-			for (int i = 1; i < intVals.Length; i++)
-			{
-				Assert.IsTrue(intVals[i - 1] < intVals[i], "check sort order");
-			}
-		}
-		
-		// INFO: Tests for trieCodeLong()/trieCodeInt() not needed because implicitely tested by range filter tests
-		
-		/// <summary>Note: The neededBounds iterator must be unsigned (easier understanding what's happening) </summary>
-        internal virtual void AssertLongRangeSplit(long lower, long upper, int precisionStep, bool useBitSet, IEnumerator<long> neededBounds, IEnumerator<int> neededShifts)
-		{
-		    OpenBitSet bits = useBitSet ? new OpenBitSet(upper - lower + 1) : null;
-
-		    NumericUtils.SplitLongRange(
-		        new AnonymousClassLongRangeBuilder(lower, upper, useBitSet, bits, neededBounds, neededShifts, this),
-		        precisionStep, lower, upper);
-
-		    if (useBitSet)
-		    {
-		        // after flipping all bits in the range, the cardinality should be zero
-		        bits.Flip(0, upper - lower + 1);
-		        Assert.IsTrue(bits.IsEmpty(), "The sub-range concenated should match the whole range");
-		    }
-		}
-
-        /* LUCENE-2541: NumericRangeQuery errors with endpoints near long min and max values */
+        public virtual void TestSortableFloatNaN()
+        {
+            var plusInf = NumericUtils.FloatToSortableInt(float.PositiveInfinity);
+            foreach (var nan in FLOAT_NANs)
+            {
+                Assert.IsTrue(float.IsNaN(nan));
+                var sortable = NumericUtils.FloatToSortableInt(nan);
+                Assert.IsTrue(sortable > plusInf, "float not sorted correctly: " + nan + ", int repr: "
+                           + sortable + ", positive inf.: " + plusInf);
+            }
+        }
+
+        // INFO: Tests for trieCodeLong()/trieCodeInt() not needed because implicitely tested by range filter tests
+
+        private sealed class AnonymousLongRangeBuilder : NumericUtils.LongRangeBuilder
+        {
+            private long lower, upper;
+            private OpenBitSet bits;
+            private bool useBitSet;
+            private IEnumerator<long> neededShifts, neededBounds;
+ 
+            public AnonymousLongRangeBuilder(long lower, long upper, OpenBitSet bits, bool useBitSet,
+                                             IEnumerator<long> neededShifts, IEnumerator<long> neededBounds)
+            {
+                this.lower = lower;
+                this.upper = upper;
+                this.bits = bits;
+                this.useBitSet = useBitSet;
+                this.neededBounds = neededBounds;
+                this.neededShifts = neededShifts;
+            }
+
+            public override void AddRange(long min, long max, int shift)
+            {
+                Assert.IsTrue(min >= lower && min <= upper && max >= lower && max <= upper,
+                    "min, max should be inside bounds");
+                if (useBitSet)
+                    for (long l = min; l <= max; l++)
+                    {
+                        Assert.IsFalse(bits.GetAndSet(l - lower), "ranges should not overlap");
+                        // extra exit condition to prevent overflow on MaxValue
+                        if (l == max) break;
+                    }
+                if (neededBounds == null || neededShifts == null)
+                    return;
+                // make unsigned longs for easier display and understanding
+                min ^= 0x8000000000000000L;
+                max ^= 0x8000000000000000L;
+                //System.out.println("0x"+long.toHexString(min>>>shift)+"L,0x"+long.toHexString(max>>>shift)+"L)/*shift="+shift+"*/,");
+                Assert.IsTrue(neededShifts.MoveNext());
+                Assert.IsTrue(neededShifts.Current.Equals(shift), "shift");
+                Assert.IsTrue(neededBounds.MoveNext());
+                Assert.IsTrue(neededBounds.Current.Equals(Number.URShift(min, shift)), "inner min bound");
+                Assert.IsTrue(neededBounds.MoveNext());
+                Assert.IsTrue(neededBounds.Current.Equals(Number.URShift(max, shift)), "inner max bound");
+            }
+        }
+
+        /** Note: The neededBounds IEnumerable must be unsigned (easier understanding what's happening) */
+
+        private void AssertLongRangeSplit(long lower, long upper, int precisionStep,
+                                          bool useBitSet, IEnumerable<long> expectedBounds, IEnumerable<int> expectedShifts
+            )
+        {
+            // Cannot use FixedBitSet since the range could be long:
+            var bits = useBitSet ? new OpenBitSet(upper - lower + 1) : null;
+            var neededBounds = (expectedBounds == null) ? null : expectedBounds.GetEnumerator();
+            var neededShifts = (expectedShifts == null) ? null : expectedShifts.GetEnumerator();
+
+            NumericUtils.SplitLongRange(new AnonymousLongRangeBuilder(), precisionStep, lower, upper);
+
+            if (useBitSet)
+            {
+                // after flipping all bits in the range, the cardinality should be zero
+                bits.Flip(0, upper - lower + 1);
+                Assert.IsTrue(bits.Cardinality.Equals(0), "The sub-range concenated should match the whole range");
+            }
+        }
+
+        /** LUCENE-2541: NumericRangeQuery errors with endpoints near long min and max values */
         [Test]
-        public void TestLongExtremeValues()
+        public virtual void TestLongExtremeValues()
         {
             // upper end extremes
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 1, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 2, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 4, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 6, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 8, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-
-            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 64, true,
-                new ulong[] { 0xffffffffffffffffL, 0xffffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
-            
-            AssertLongRangeSplit(long.MaxValue - 0xfL, long.MaxValue, 4, true,
-                new ulong[] { 0xfffffffffffffffL, 0xfffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 4 }.AsEnumerable().GetEnumerator());
-            AssertLongRangeSplit(long.MaxValue - 0x10L, long.MaxValue, 4, true,
-                new ulong[] { 0xffffffffffffffefL, 0xffffffffffffffefL, 0xfffffffffffffffL, 0xfffffffffffffffL }.Cast<long>().GetEnumerator(),
-                new int[] { 0, 4 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 1, true, new long[]
+                {
+                    0xffffffffffffffffL, 
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 2, true, new long[]
+                {
+                    0xffffffffffffffffL,
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 4, true, new long[]
+                {
+                    0xffffffffffffffffL, 
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 6, true, new long[]
+                {
+                    0xffffffffffffffffL, 
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue, long.MaxValue, 8, true, new long[]
+                {
+                    0xffffffffffffffffL,
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue, long.MinValue, 64, true, new long[]
+                {
+                    0xffffffffffffffffL,
+                    0xffffffffffffffffL
+                }, new int[] {0});
+
+            AssertLongRangeSplit(long.MaxValue - 0xfL, long.MaxValue, 4, true, new long[]
+                {
+                    0xfffffffffffffffL,
+                    0xfffffffffffffffL
+                }, new int[] {4});
+
+            AssertLongRangeSplit(long.MaxValue - 0x10L, long.MaxValue, 4, true, new long[]
+                {
+                    0xffffffffffffffefL,
+                    0xffffffffffffffefL,
+                    0xfffffffffffffffL,
+                    0xfffffffffffffffL
+                }, new int[] {0, 4});
 
             // lower end extremes
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 1, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 1, true, new long[]
+                {
+                    0x0000000000000000L, 
+                    0x0000000000000000L
+                }, new int[] {0});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 2, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 2, true, new long[]
+                {
+                    0x0000000000000000L, 
+                    0x0000000000000000L
+                }, new int[] {0});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 4, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 4, true, new long[]
+                {
+                     0x0000000000000000L, 
+                     0x0000000000000000L
+                }, new int[] {0});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 6, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 6, true, new long[]
+                {
+                    0x0000000000000000L,
+                    0x0000000000000000L
+                }, new int[] {0});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 8, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 8, true, new long[]
+                {
+                    0x0000000000000000L,
+                    0x0000000000000000L
+                }, new int[] {0});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue, 64, true,
-                new long[] { 0x0000000000000000L, 0x0000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MinValue, 64, true, new long[]
+                {
+                    0x0000000000000000L,
+                    0x0000000000000000L
+                }, new int[] {0});
 
+            AssertLongRangeSplit(long.MinValue, long.MaxValue + 0xfL, 4, true, new long[]
+                {
+                    0x000000000000000L, 
+                    0x000000000000000L
+                }, new int[] {4});
 
-            AssertLongRangeSplit(long.MinValue, long.MinValue + 0xfL, 4, true,
-                new long[] { 0x000000000000000L, 0x000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 4 }.AsEnumerable().GetEnumerator());
-            AssertLongRangeSplit(long.MinValue, long.MinValue + 0x10L, 4, true,
-                new long[] { 0x0000000000000010L, 0x0000000000000010L, 0x000000000000000L, 0x000000000000000L }.Cast<long>().GetEnumerator(),
-                new int[] { 0, 4 }.AsEnumerable().GetEnumerator());
+            AssertLongRangeSplit(long.MinValue, long.MaxValue + 0x10L, 4, true, new long[]
+                {
+                    0x0000000000000010L, 
+                    0x0000000000000010L,
+                    0x000000000000000L,
+                    0x000000000000000L
+                }, 
+                new int[] {0, 4});
         }
 
         [Test]
-        public void TestRandomSplit()
+        public virtual void TestRandomSplit()
         {
-            Random random = new Random();
-            for (int i = 0; i < 100; i++)
+            var num = (long) AtLeast(10);
+            for (long i = 0; i < num; i++)
             {
-                ExecuteOneRandomSplit(random);
+                ExecuteOneRandomSplit(new Random());
             }
         }
 
         private void ExecuteOneRandomSplit(Random random)
         {
-            long lower = RandomLong(random);
-            long len = (long)random.Next(16384 * 1024); // not too large bitsets, else OOME!
+            var lower = RandomLong(random);
+            long len = random.Next(16384*1024); // not too large bitsets, else OOME!
             while (lower + len < lower)
-            { // overflow
+            {
+                // overflow
                 lower >>= 1;
             }
             AssertLongRangeSplit(lower, lower + len, random.Next(64) + 1, true, null, null);
@@ -410,160 +465,177 @@ namespace Lucene.Net.Util
             switch (random.Next(4))
             {
                 case 0:
-                    val = 1L << (random.Next(63)); //  patterns like 0x000000100000 (-1 yields patterns like 0x0000fff)
+                    val = 1L << (random.Next(63));
+                        //  patterns like 0x000000100000 (-1 yields patterns like 0x0000fff)
                     break;
                 case 1:
                     val = -1L << (random.Next(63)); // patterns like 0xfffff00000
                     break;
                 default:
-                    val = random.Next();
-                    break;
+                    val = random.NextLong();
             }
 
             val += random.Next(5) - 2;
 
-            if (random.Next(2) == 1)
+            if (random.NextBool())
             {
-                if (random.Next(2) == 1) val += random.Next(100) - 50;
-                if (random.Next(2) == 1) val = ~val;
-                if (random.Next(2) == 1) val = val << 1;
-                if (random.Next(2) == 1) val = Number.URShift(val, 1);
+                if (random.NextBool()) val += random.Next(100) - 50;
+                if (random.NextBool()) val = ~val;
+                if (random.NextBool()) val = val << 1;
+                if (random.NextBool()) val = Number.URShift(val, 1);
             }
 
             return val;
         }
 
-
         [Test]
-		public void  TestSplitLongRange()
-		{
-			// a hard-coded "standard" range
-            AssertLongRangeSplit(- 5000L, 9500L, 4, true,
-                                 new System.Int64[]
-                                     {
-                                         0x7fffffffffffec78L, 0x7fffffffffffec7fL, unchecked((long) (0x8000000000002510L)),
-                                         unchecked((long) (0x800000000000251cL)), 0x7fffffffffffec8L, 0x7fffffffffffecfL,
-                                         0x800000000000250L, 0x800000000000250L, 0x7fffffffffffedL, 0x7fffffffffffefL,
-                                         0x80000000000020L, 0x80000000000024L, 0x7ffffffffffffL, 0x8000000000001L
-                                     }.Cast<long>().GetEnumerator(), new int[] {0, 0, 4, 4, 8, 8, 12}.Cast<int>().GetEnumerator());
-			
-			// the same with no range splitting
-            AssertLongRangeSplit(-5000L, 9500L, 64, true,
-                                 new System.Int64[] {0x7fffffffffffec78L, unchecked((long) (0x800000000000251cL))}.Cast
-                                     <long>().GetEnumerator(), new int[] { 0 }.Cast<int>().GetEnumerator());
-			
-			// this tests optimized range splitting, if one of the inner bounds
-			// is also the bound of the next lower precision, it should be used completely
-            AssertLongRangeSplit(0L, 1024L + 63L, 4, true,
-                                 new System.Int64[]
-                                     {0x800000000000040L, 0x800000000000043L, 0x80000000000000L, 0x80000000000003L}.Cast
-                                     <long>().GetEnumerator(), new int[] { 4, 8 }.Cast<int>().GetEnumerator());
-			
-			// the full long range should only consist of a lowest precision range; no bitset testing here, as too much memory needed :-)
-            AssertLongRangeSplit(System.Int64.MinValue, System.Int64.MaxValue, 8, false,
-                                 new System.Int64[] {0x00L, 0xffL}.Cast<long>().GetEnumerator(),
-                                 new int[] { 56 }.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=4
-            AssertLongRangeSplit(System.Int64.MinValue, System.Int64.MaxValue, 4, false,
-                                 new System.Int64[] {0x0L, 0xfL}.Cast<long>().GetEnumerator(),
-                                 new int[] { 60 }.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=2
-            AssertLongRangeSplit(System.Int64.MinValue, System.Int64.MaxValue, 2, false,
-                                 new System.Int64[] {0x0L, 0x3L}.Cast<long>().GetEnumerator(),
-                                 new int[] {62}.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=1
-            AssertLongRangeSplit(System.Int64.MinValue, System.Int64.MaxValue, 1, false,
-                                 new System.Int64[] {0x0L, 0x1L}.ToList().GetEnumerator(),
-                                 new int[] {63}.Cast<int>().GetEnumerator());
-			
-			// a inverse range should produce no sub-ranges
-            AssertLongRangeSplit(9500L, -5000L, 4, false,
-                                 Enumerable.Empty<long>().GetEnumerator(),
-                                 new int[] {}.Cast<int>().GetEnumerator());
-			
-			// a 0-length range should reproduce the range itsself
-            AssertLongRangeSplit(9500L, 9500L, 4, false, new long[]
-                                                             {
-                                                                 unchecked((long) (0x800000000000251cL)),
-                                                                 unchecked((long) (0x800000000000251cL))
-                                                             }.Cast<long>().GetEnumerator(),
-                                 new int[] {0}.Cast<int>().GetEnumerator());
-		}
-		
-
-		/// <summary>Note: The neededBounds iterator must be unsigned (easier understanding what's happening) </summary>
-		protected internal virtual void  AssertIntRangeSplit(int lower, int upper, int precisionStep, bool useBitSet, IEnumerator<int> neededBounds, IEnumerator<int> neededShifts)
-		{
-		    OpenBitSet bits = useBitSet ? new OpenBitSet(upper - lower + 1) : null;
-
-            NumericUtils.SplitIntRange(new AnonymousClassIntRangeBuilder(lower, upper, useBitSet, bits, neededBounds, neededShifts,this), precisionStep, lower, upper);
-			
-			if (useBitSet)
-			{
-				// after flipping all bits in the range, the cardinality should be zero
-				bits.Flip(0, upper - lower + 1);
-				Assert.IsTrue(bits.IsEmpty(), "The sub-range concenated should match the whole range");
-			}
-		}
-		
+        public virtual void TestSplitLongRange()
+        {
+            // a hard-coded "standard" range
+            AssertLongRangeSplit(-5000L, 9500L, 4, true, new long[]
+                {
+                    0x7fffffffffffec78L,
+                    0x7fffffffffffec7fL,
+                    0x8000000000002510L,
+                    0x800000000000251cL,
+                    0x7fffffffffffec8L,
+                    0x7fffffffffffecfL,
+                    0x800000000000250L,
+                    0x800000000000250L,
+                    0x7fffffffffffedL,
+                    0x7fffffffffffefL,
+                    0x80000000000020L,
+                    0x80000000000024L,
+                    0x7ffffffffffffL,
+                    0x8000000000001L
+                },
+                new int[]
+                    {
+                        0,
+                        0,
+                        4,
+                        4,
+                        8,
+                        8,
+                        12
+                    });
+
+            // the same with no range splitting
+            AssertLongRangeSplit(-5000L, 9500L, 64, true, new long[] { 0x7fffffffffffec78L, 0x800000000000251cL}, new int[] {0});
+
+            // this tests optimized range splitting, if one of the inner bounds
+            // is also the bound of the next lower precision, it should be used completely
+            AssertLongRangeSplit(0L, 1024L + 63L, 4, true, new long[] {0x800000000000040L, 0x800000000000043L, 0x80000000000000L, 0x80000000000003L}, new int[] {4, 8});
+
+            // the full long range should only consist of a lowest precision range; no bitset testing here, as too much memory needed :-)
+            AssertLongRangeSplit(long.MinValue, long.MaxValue, 8, false, new long[] { 0x00L, 0xffL}, new int[] {56});
+
+            // the same with precisionStep=4
+            AssertLongRangeSplit(long.MinValue, long.MaxValue, 4, false, new long[] {0x0L, 0xfL}, new int[] {60});
+
+            // the same with precisionStep=2
+            AssertLongRangeSplit(long.MinValue, long.MaxValue, 2, false, new long[] {0x0L, 0x3L}, new int[] {62});
+
+            // the same with precisionStep=1
+            AssertLongRangeSplit(long.MinValue, long.MaxValue, 1, false, new long[] {0x0L, 0x1L}, new int[] {63});
+
+            // a inverse range should produce no sub-ranges
+            AssertLongRangeSplit(9500L, -5000L, 4, false, new long[0], new int[0]);
+
+            // a 0-Length range should reproduce the range itself
+            AssertLongRangeSplit(9500L, 9500L, 4, false, new long[] { 0x800000000000251cL, 0x800000000000251cL }, new int[] {0});
+        }
+
+        private sealed class AnonymousIntRangeBuilder : NumericUtils.IntRangeBuilder
+        {
+            private int lower, upper;
+            private bool useBitSet;
+            private FixedBitSet bits;
+            private IEnumerator<int> neededBounds, neededShifts; 
+
+            public override void AddRange(int min, int max, int shift)
+            {
+                Assert.IsTrue(min >= lower && min <= upper && max >= lower && max <= upper,
+                    "min, max should be inside bounds");
+                if (useBitSet)
+                    for (int i = min; i <= max; i++)
+                    {
+                        Assert.IsFalse(bits.GetAndSet(i - lower), "ranges should not overlap");
+                        // extra exit condition to prevent overflow on MaxValue
+                        if (i == max) break;
+                    }
+                if (neededBounds == null)
+                    return;
+                // make unsigned ints for easier display and understanding
+                min ^= 0x80000000;
+                max ^= 0x80000000;
+                //System.out.println("0x"+int.toHexString(min>>>shift)+",0x"+int.toHexString(max>>>shift)+")/*shift="+shift+"*/,");
+                Assert.IsTrue(neededShifts.MoveNext());
+                Assert.IsTrue(neededShifts.Current.Equals(shift), "shift");
+                Assert.IsTrue(neededBounds.MoveNext());
+                Assert.IsTrue(neededBounds.Current.Equals(Number.URShift(min, shift)), "inner min bound");
+                Assert.IsTrue(neededBounds.MoveNext());
+                Assert.IsTrue(neededBounds.Current.Equals(Number.URShift(max, shift)), "inner max bound");
+            }
+        }
+
+        /** Note: The neededBounds IEnumerable must be unsigned (easier understanding what's happening) */
+
+        private void AssertIntRangeSplit(int lower, int upper, int precisionStep,
+                                         bool useBitSet, IEnumerable<int> expectedBounds, IEnumerable<int> expectedShifts)
+        {
+            var bits = useBitSet ? new FixedBitSet(upper - lower + 1) : null;
+            var neededBounds = (expectedBounds == null) ? null : expectedBounds.GetEnumerator();
+            var neededShifts = (expectedShifts == null) ? null : expectedShifts.GetEnumerator();
+
+            NumericUtils.SplitIntRange(new AnonymousIntRangeBuilder(), precisionStep, lower, upper);
+
+            if (useBitSet)
+            {
+                // after flipping all bits in the range, the cardinality should be zero
+                bits.Flip(0, upper - lower + 1);
+                Assert.IsTrue(bits.Cardinality().Equals(0), "The sub-range concenated should match the whole range");
+            }
+        }
+
         [Test]
-		public virtual void  TestSplitIntRange()
-		{
-			// a hard-coded "standard" range
-            AssertIntRangeSplit(- 5000, 9500, 4, true,
-                                new System.Int32[]
-                                    {
-                                        0x7fffec78, 0x7fffec7f, unchecked((System.Int32) 0x80002510),
-                                        unchecked((System.Int32) 0x8000251c), 0x7fffec8, 0x7fffecf, 0x8000250, 0x8000250,
-                                        0x7fffed, 0x7fffef, 0x800020, 0x800024, 0x7ffff, 0x80001
-                                    }.Cast<int>().GetEnumerator
-                                    (), new int[] { 0, 0, 4, 4, 8, 8, 12 }.Cast<int>().GetEnumerator());
-			
-			// the same with no range splitting
-            AssertIntRangeSplit(-5000, 9500, 32, true,
-                                new System.Int32[] {0x7fffec78, unchecked((System.Int32) 0x8000251c)}.Cast<int>().
-                                    GetEnumerator(), new int[] { 0 }.Cast<int>().GetEnumerator());
-			
-			// this tests optimized range splitting, if one of the inner bounds
-			// is also the bound of the next lower precision, it should be used completely
-            AssertIntRangeSplit(0, 1024 + 63, 4, true,
-                                new System.Int32[] {0x8000040, 0x8000043, 0x800000, 0x800003}.Cast<int>().GetEnumerator(),
-                                new int[] { 4, 8 }.Cast<int>().GetEnumerator());
-			
-			// the full int range should only consist of a lowest precision range; no bitset testing here, as too much memory needed :-)
-            AssertIntRangeSplit(System.Int32.MinValue, System.Int32.MaxValue, 8, false,
-                                new System.Int32[] {0x00, 0xff}.Cast<int>().GetEnumerator(),
-                                new int[] { 24 }.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=4
-            AssertIntRangeSplit(System.Int32.MinValue, System.Int32.MaxValue, 4, false,
-                                new System.Int32[] {0x0, 0xf}.Cast<int>().GetEnumerator(),
-                                new int[] {28}.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=2
-            AssertIntRangeSplit(System.Int32.MinValue, System.Int32.MaxValue, 2, false,
-                                new System.Int32[] {0x0, 0x3}.Cast<int>().GetEnumerator(),
-                                new int[] {30}.Cast<int>().GetEnumerator());
-			
-			// the same with precisionStep=1
-            AssertIntRangeSplit(System.Int32.MinValue, System.Int32.MaxValue, 1, false,
-                                new System.Int32[] {0x0, 0x1}.Cast<int>().GetEnumerator(),
-                                new int[] {31}.Cast<int>().GetEnumerator());
-			
-			// a inverse range should produce no sub-ranges
-            AssertIntRangeSplit(9500, -5000, 4, false, Enumerable.Empty<int>().GetEnumerator(),
-                                new int[] {}.Cast<int>().GetEnumerator());
-			
-			// a 0-length range should reproduce the range itsself
-            AssertIntRangeSplit(9500, 9500, 4, false, new System.Int32[]
-                                                          {
-                                                              unchecked((System.Int32) 0x8000251c),
-                                                              unchecked((System.Int32) 0x8000251c)
-                                                          }.Cast<int>().GetEnumerator(),
-                                new int[] {0}.Cast<int>().GetEnumerator());
-		}
-	}
+        public virtual void TestSplitIntRange()
+        {
+            // a hard-coded "standard" range
+            AssertIntRangeSplit(-5000, 9500, 4, true, new int[] {
+                0x7fffec78, 0x7fffec7f,
+                0x80002510, 0x8000251c,
+                0x7fffec8, 0x7fffecf,
+                0x8000250, 0x8000250,
+                0x7fffed, 0x7fffef,
+                0x800020, 0x800024,
+                0x7ffff, 0x80001
+            }, new int[] {0, 0, 4, 4, 8, 8, 12 } );
+
+            // the same with no range splitting
+            AssertIntRangeSplit(-5000, 9500, 32, true, new int[] {0x7fffec78, 0x8000251c}, new int[] {0});
+
+            // this tests optimized range splitting, if one of the inner bounds
+            // is also the bound of the next lower precision, it should be used completely
+            AssertIntRangeSplit(0, 1024 + 63, 4, true, new int[] {0x8000040, 0x8000043, 0x800000, 0x800003}, new int[] {4, 8});
+
+            // the full int range should only consist of a lowest precision range; no bitset testing here, as too much memory needed :-)
+            AssertIntRangeSplit(int.MinValue, int.MaxValue, 8, false, new int[] {0x00, 0xff}, new int[] {24});
+
+            // the same with precisionStep=4
+            AssertIntRangeSplit(int.MinValue, int.MaxValue, 4, false, new int[] {0x0, 0xf}, new int[] {28});
+
+            // the same with precisionStep=2
+            AssertIntRangeSplit(int.MinValue, int.MinValue, 2, false, new int[] {0x0, 0x3}, new int[] {30});
+
+            // the same with precisionStep=1
+            AssertIntRangeSplit(int.MinValue, int.MaxValue, 1, false, new int[] { 0x0, 0x1 }, new int[] { 31 });
+
+            // a inverse range should produce no sub-ranges
+            AssertIntRangeSplit(9500, -5000, 4, false, new int[0], new int[0]);
+
+            // a 0-Length range should reproduce the range itself
+            AssertIntRangeSplit(9500, 9500, 4, false, new int[] { 0x8000251c, 0x8000251c }, new int[] { 0 });
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/06f5d4b8/test/core/Util/TestOpenBitSet.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestOpenBitSet.cs b/test/core/Util/TestOpenBitSet.cs
index 70d0ea0..5d09cd8 100644
--- a/test/core/Util/TestOpenBitSet.cs
+++ b/test/core/Util/TestOpenBitSet.cs
@@ -16,7 +16,9 @@
  */
 
 using System;
+using System.Collections;
 using Lucene.Net.Support;
+using Lucene.Net.Test.Support;
 using NUnit.Framework;
 
 using DocIdSetIterator = Lucene.Net.Search.DocIdSetIterator;
@@ -29,31 +31,86 @@ namespace Lucene.Net.Util
 	[TestFixture]
 	public class TestOpenBitSet:LuceneTestCase
 	{
-		internal System.Random rand;
+		internal Random rand;
 		
-		internal virtual void  DoGet(System.Collections.BitArray a, OpenBitSet b)
+		internal virtual void  DoGet(BitArray a, OpenBitSet b)
 		{
-			int max = a.Count;
-			for (int i = 0; i < max; i++)
+			var max = a.Count;
+			for (var i = 0; i < max; i++)
 			{
                 Assert.AreEqual(a.Get(i) != b.Get(i), "mismatch: BitSet=[" + i + "]=" + a.Get(i));
+                Assert.AreEqual(a.Get(i) != b.Get((long)i), "mismatch: BitSet=[" + i + "]=" + a.Get(i));
 			}
 		}
 		
-		internal virtual void  DoNextSetBit(System.Collections.BitArray a, OpenBitSet b)
+        internal virtual void DoGetFast(BitArray a, OpenBitSet b, int max)
+        {
+            for (var i = 0; i < max; i++)
+            {
+                Assert.AreEqual(a.Get(i) != b.Get(i), "mismatch: BitSet=[" + i + "]=" + a.Get(i));
+                Assert.AreEqual(a.Get(i) != b.Get((long)i), "mismatch: BitSet=[" + i + "]=" + a.Get(i));
+            }
+        }
+
+		internal virtual void  DoNextSetBit(BitArray a, OpenBitSet b)
 		{
 			int aa = - 1, bb = - 1;
 			do 
 			{
-				aa = BitSetSupport.NextSetBit(a, aa + 1);
+				aa = a.NextSetBit(aa + 1);
 				bb = b.NextSetBit(bb + 1);
 				Assert.AreEqual(aa, bb);
 			}
 			while (aa >= 0);
 		}
+
+        internal virtual void DoNextSetBitLong(BitArray a, OpenBitSet b)
+        {
+            int aa = -1, bb = -1;
+            do
+            {
+                aa = a.NextSetBit(aa + 1);
+                bb = (int) b.NextSetBit((long) (bb + 1));
+                Assert.AreEqual(aa, bb);
+            } while (aa >= 0);
+        }
 		
+        internal virtual void DoPrevSetBit(BitArray a, OpenBitSet b)
+        {
+            var aa = a.Count + rand.Next(100);
+            var bb = aa;
+            do
+            {
+                // aa = a.prevSetBit(aa-1);
+                aa--;
+                while ((aa >= 0) && (!a[aa]))
+                {
+                    aa--;
+                }
+                bb = b.PrevSetBit(bb - 1);
+                Assert.AreEqual(aa, bb);
+            } while (aa >= 0);
+        }
+
+        internal virtual void DoPrevSetBitLong(BitArray a, OpenBitSet b)
+        {
+            var aa = a.Count + rand.Next(100);
+            var bb = aa;
+            do
+            {
+                // aa = a.prevSetBit(aa-1);
+                aa--;
+                while ((aa >= 0) && (!a[aa]))
+                {
+                    aa--;
+                }
+                bb = (int)b.prevSetBit((long)(bb - 1));
+                assertEquals(aa, bb);
+            } while (aa >= 0);
+        }
+
 		// test interleaving different OpenBitSetIterator.next()/skipTo()
-		internal virtual void  DoIterate(System.Collections.BitArray a, OpenBitSet b, int mode)
+		internal virtual void  DoIterate(BitArray a, OpenBitSet b, int mode)
 		{
 			if (mode == 1)
 				DoIterate1(a, b);
@@ -61,27 +118,27 @@ namespace Lucene.Net.Util
 				DoIterate2(a, b);
 		}
 		
-		internal virtual void  DoIterate1(System.Collections.BitArray a, OpenBitSet b)
+		internal virtual void  DoIterate1(BitArray a, OpenBitSet b)
 		{
 			int aa = - 1, bb = - 1;
-			OpenBitSetIterator iterator = new OpenBitSetIterator(b);
+			var iterator = new OpenBitSetIterator(b);
 			do 
 			{
-				aa = BitSetSupport.NextSetBit(a, aa + 1);
-				bb = rand.NextDouble() > 0.5 ? iterator.NextDoc() : iterator.Advance(bb + 1);
-				Assert.AreEqual(aa == - 1?DocIdSetIterator.NO_MORE_DOCS:aa, bb);
+				aa = a.NextSetBit(aa + 1);
+				bb = rand.NextBool() ? iterator.NextDoc() : iterator.Advance(bb + 1);
+				Assert.AreEqual(aa == - 1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
 			}
 			while (aa >= 0);
 		}
 		
-		internal virtual void  DoIterate2(System.Collections.BitArray a, OpenBitSet b)
+		internal virtual void  DoIterate2(BitArray a, OpenBitSet b)
 		{
 			int aa = - 1, bb = - 1;
-			OpenBitSetIterator iterator = new OpenBitSetIterator(b);
+			var iterator = new OpenBitSetIterator(b);
 			do 
 			{
-				aa = BitSetSupport.NextSetBit(a, aa + 1);
-				bb = rand.NextDouble() > 0.5 ? iterator.NextDoc() : iterator.Advance(bb + 1);
+				aa = a.NextSetBit(aa + 1);
+				bb = rand.NextBool() ? iterator.NextDoc() : iterator.Advance(bb + 1);
 				Assert.AreEqual(aa == - 1?DocIdSetIterator.NO_MORE_DOCS:aa, bb);
 			}
 			while (aa >= 0);
@@ -89,54 +146,72 @@ namespace Lucene.Net.Util
 		
 		internal virtual void  DoRandomSets(int maxSize, int iter, int mode)
 		{
-			System.Collections.BitArray a0 = null;
+			BitArray a0 = null;
 			OpenBitSet b0 = null;
 			
-			for (int i = 0; i < iter; i++)
+			for (var i = 0; i < iter; i++)
 			{
-				int sz = rand.Next(maxSize);
-				System.Collections.BitArray a = new System.Collections.BitArray(sz);
-				OpenBitSet b = new OpenBitSet(sz);
+				var sz = rand.Next(maxSize);
+				var a = new BitArray(sz);
+				var b = new OpenBitSet(sz);
 				
 				// test the various ways of setting bits
-				if (sz > 0)
-				{
-					int nOper = rand.Next(sz);
-					for (int j = 0; j < nOper; j++)
-					{
-						int idx;
-						
-						idx = rand.Next(sz);
-						a.Set(idx, true);
-						b.FastSet(idx);
-						idx = rand.Next(sz);
-						a.Set(idx, false);
-						b.FastClear(idx);
-						idx = rand.Next(sz);
-						a.Set(idx, !a.Get(idx));
-						b.FastFlip(idx);
-						
-						bool val = b.FlipAndGet(idx);
-						bool val2 = b.FlipAndGet(idx);
-						Assert.IsTrue(val != val2);
-						
-						val = b.GetAndSet(idx);
-						Assert.IsTrue(val2 == val);
-						Assert.IsTrue(b.Get(idx));
-						
-						if (!val)
-							b.FastClear(idx);
-						Assert.IsTrue(b.Get(idx) == val);
-					}
-				}
+                if (sz > 0)
+                {
+                    int nOper = rand.Next(sz);
+                    for (int j = 0; j < nOper; j++)
+                    {
+                        int idx;
+
+                        idx = rand.Next(sz);
+                        a.Set(idx);
+                        b.FastSet(idx);
+
+                        idx = rand.Next(sz);
+                        a.Set(idx);
+                        b.FastSet((long)idx);
+
+                        idx = rand.Next(sz);
+                        a.Clear(idx);
+                        b.FastClear(idx);
+
+                        idx = rand.Next(sz);
+                        a.Clear(idx);
+                        b.FastClear((long)idx);
+
+                        idx = rand.Next(sz);
+                        a.Flip(idx);
+                        b.FastFlip(idx);
+
+                        var val = b.FlipAndGet(idx);
+                        var val2 = b.FlipAndGet(idx);
+                        assertTrue(val != val2);
+
+                        idx = rand.Next(sz);
+                        a.Flip(idx);
+                        b.FastFlip((long)idx);
+
+                        val = b.FlipAndGet((long)idx);
+                        val2 = b.FlipAndGet((long)idx);
+                        assertTrue(val != val2);
+
+                        val = b.GetAndSet(idx);
+                        assertTrue(val2 == val);
+                        assertTrue(b[idx]);
+
+                        if (!val) b.FastClear(idx);
+                        assertTrue(b[idx] == val);
+                    }
+                }
 				
 				// test that the various ways of accessing the bits are equivalent
 				DoGet(a, b);
+			    DoGetFast(a, b, sz);
 				
                 // {{dougsale-2.4.0}}
                 //
                 // Java's java.util.BitSet automatically grows as needed - i.e., when a bit is referenced beyond
-                // the size of the BitSet, an exception isn't thrown - rather, the set grows to the size of the 
+                // the size of the BitSet, an exception isn't thrown - rather, the Set grows to the size of the 
                 // referenced bit.
                 //
                 // System.Collections.BitArray does not have this feature, and thus I've faked it here by
@@ -148,6 +223,10 @@ namespace Lucene.Net.Util
                 int fromIndex, toIndex;
                 fromIndex = rand.Next(sz + 80);
                 toIndex = fromIndex + rand.Next((sz >> 1) + 1);
+                //var aa = (BitArray)a.Clone();
+                //aa.Flip(fromIndex, toIndex);
+                //var bb = b.Clone();
+                //bb.Flip(fromIndex, toIndex);
 
                 // {{dougsale-2.4.0}}:
                 // The following commented-out, compound statement's 'for loop' implicitly grows the Java BitSets 'a'
@@ -156,16 +235,16 @@ namespace Lucene.Net.Util
                 // So, if necessary, lets explicitly grow 'a' now; then 'a' and its clone, 'aa', will be of the required size.
                 if (a.Count < toIndex && fromIndex < toIndex)
                 {
-                    System.Collections.BitArray tmp = new System.Collections.BitArray(toIndex, false);
-                    for (int k = 0; k < a.Count; k++)
+                    var tmp = new BitArray(toIndex, false);
+                    for (var k = 0; k < a.Count; k++)
                         tmp.Set(k, a.Get(k));
                     a = tmp;
                 }
                 // {{dougsale-2.4.0}}: now we can invoke this statement without going 'out-of-bounds'
-                System.Collections.BitArray aa = (System.Collections.BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, !a.Get(j));
-                OpenBitSet bb = (OpenBitSet)b.Clone(); bb.Flip(fromIndex, toIndex);
+                var aa = (BitArray)a.Clone(); for (int j = fromIndex; j < toIndex; j++) aa.Set(j, !a.Get(j));
+                var bb = (OpenBitSet)b.Clone(); bb.Flip(fromIndex, toIndex);
 
-                DoIterate(aa, bb, mode); // a problem here is from flip or doIterate
+                DoIterate(aa, bb, mode); // a problem here is from Flip or doIterate
 
                 fromIndex = rand.Next(sz + 80);
                 toIndex = fromIndex + rand.Next((sz >> 1) + 1);
@@ -176,18 +255,18 @@ namespace Lucene.Net.Util
                 // So, if necessary, lets explicitly grow 'aa' now
                 if (a.Count < toIndex && fromIndex < toIndex)
                 {
-                    aa = new System.Collections.BitArray(toIndex);
-                    for (int k = 0; k < a.Count; k++)
+                    aa = new BitArray(toIndex);
+                    for (var k = 0; k < a.Count; k++)
                         aa.Set(k, a.Get(k));
                 }
                 else
                 {
-                    aa = (System.Collections.BitArray)a.Clone();
+                    aa = (BitArray)a.Clone();
                 }
-                for (int j = fromIndex; j < toIndex; j++) aa.Set(j, false);
+                for (var j = fromIndex; j < toIndex; j++) aa.Set(j, false);
                 bb = (OpenBitSet)b.Clone(); bb.Clear(fromIndex, toIndex);
 
-                DoNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit
+                DoNextSetBit(aa, bb); // a problem here is from Clear() or nextSetBit
 
                 fromIndex = rand.Next(sz + 80);
                 toIndex = fromIndex + rand.Next((sz >> 1) + 1);
@@ -198,18 +277,18 @@ namespace Lucene.Net.Util
                 // So, if necessary, lets explicitly grow 'aa' now
                 if (a.Count < toIndex && fromIndex < toIndex)
                 {
-                    aa = new System.Collections.BitArray(toIndex);
-                    for (int k = 0; k < a.Count; k++)
+                    aa = new BitArray(toIndex);
+                    for (var k = 0; k < a.Count; k++)
                         aa.Set(k, a.Get(k));
                 }
                 else
                 {
-                    aa = (System.Collections.BitArray)a.Clone();
+                    aa = (BitArray)a.Clone();
                 }
-                for (int j = fromIndex; j < toIndex; j++) aa.Set(j, true);
+                for (var j = fromIndex; j < toIndex; j++) aa.Set(j, true);
                 bb = (OpenBitSet)b.Clone(); bb.Set(fromIndex, toIndex);
 				
-				DoNextSetBit(aa, bb); // a problem here is from set() or nextSetBit     
+				DoNextSetBit(aa, bb); // a problem here is from Set() or nextSetBit     
 				
 				
 				if (a0 != null)
@@ -221,8 +300,8 @@ namespace Lucene.Net.Util
                     // {{dougsale-2.4.0}}
                     //
                     // The Java code used java.util.BitSet, which grows as needed.
-                    // When a bit, outside the dimension of the set is referenced,
-                    // the set automatically grows to the necessary size.  The
+                    // When a bit, outside the dimension of the Set is referenced,
+                    // the Set automatically grows to the necessary size.  The
                     // new entries default to false.
                     //
                     // BitArray does not grow automatically and is not growable.
@@ -238,52 +317,52 @@ namespace Lucene.Net.Util
                     //BitArray a_xor = (BitArray)a.Clone(); a_xor.Xor(a0);
                     //BitArray a_andn = (BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
 
-                    System.Collections.BitArray a_and;
-                    System.Collections.BitArray a_or;
-                    System.Collections.BitArray a_xor;
-                    System.Collections.BitArray a_andn;
+                    BitArray a_and;
+                    BitArray a_or;
+                    BitArray a_xor;
+                    BitArray a_andn;
 
                     if (a.Count < a0.Count)
                     {
                         // the Java code would have implicitly resized 'a_and', 'a_or', 'a_xor', and 'a_andn'
                         // in this case, so we explicitly create a resized stand-in for 'a' here, allowing for
                         // a to keep its original size while 'a_and', 'a_or', 'a_xor', and 'a_andn' are resized
-                        System.Collections.BitArray tmp = new System.Collections.BitArray(a0.Count, false);
+                        var tmp = new BitArray(a0.Count, false);
                         for (int z = 0; z < a.Count; z++)
                             tmp.Set(z, a.Get(z));
 
-                        a_and = (System.Collections.BitArray)tmp.Clone(); a_and.And(a0);
-                        a_or = (System.Collections.BitArray)tmp.Clone(); a_or.Or(a0);
-                        a_xor = (System.Collections.BitArray)tmp.Clone(); a_xor.Xor(a0);
-                        a_andn = (System.Collections.BitArray)tmp.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                        a_and = (BitArray)tmp.Clone(); a_and.And(a0);
+                        a_or = (BitArray)tmp.Clone(); a_or.Or(a0);
+                        a_xor = (BitArray)tmp.Clone(); a_xor.Xor(a0);
+                        a_andn = (BitArray)tmp.Clone(); for (var j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
                     }
                     else if (a.Count > a0.Count)
                     {
                         // the Java code would have implicitly resized 'a0' in this case, so
                         // we explicitly do so here:
-                        System.Collections.BitArray tmp = new System.Collections.BitArray(a.Count, false);
-                        for (int z = 0; z < a0.Count; z++)
+                        var tmp = new BitArray(a.Count, false);
+                        for (var z = 0; z < a0.Count; z++)
                             tmp.Set(z, a0.Get(z));
                         a0 = tmp;
 
-                        a_and = (System.Collections.BitArray)a.Clone(); a_and.And(a0);
-                        a_or = (System.Collections.BitArray)a.Clone(); a_or.Or(a0);
-                        a_xor = (System.Collections.BitArray)a.Clone(); a_xor.Xor(a0);
-                        a_andn = (System.Collections.BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                        a_and = (BitArray)a.Clone(); a_and.And(a0);
+                        a_or = (BitArray)a.Clone(); a_or.Or(a0);
+                        a_xor = (BitArray)a.Clone(); a_xor.Xor(a0);
+                        a_andn = (BitArray)a.Clone(); for (var j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
                     }
                     else
                     {
                         // 'a' and 'a0' are the same size, no explicit growing necessary
-                        a_and = (System.Collections.BitArray)a.Clone(); a_and.And(a0);
-                        a_or = (System.Collections.BitArray)a.Clone(); a_or.Or(a0);
-                        a_xor = (System.Collections.BitArray)a.Clone(); a_xor.Xor(a0);
-                        a_andn = (System.Collections.BitArray)a.Clone(); for (int j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
+                        a_and = (BitArray)a.Clone(); a_and.And(a0);
+                        a_or = (BitArray)a.Clone(); a_or.Or(a0);
+                        a_xor = (BitArray)a.Clone(); a_xor.Xor(a0);
+                        a_andn = (BitArray)a.Clone(); for (var j = 0; j < a_andn.Count; j++) if (a0.Get(j)) a_andn.Set(j, false);
                     }
 
-                    OpenBitSet b_and = (OpenBitSet)b.Clone(); Assert.AreEqual(b, b_and); b_and.And(b0);
-                    OpenBitSet b_or = (OpenBitSet)b.Clone(); b_or.Or(b0);
-                    OpenBitSet b_xor = (OpenBitSet)b.Clone(); b_xor.Xor(b0);
-                    OpenBitSet b_andn = (OpenBitSet)b.Clone(); b_andn.AndNot(b0);
+                    var b_and = (OpenBitSet)b.Clone(); Assert.AreEqual(b, b_and); b_and.And(b0);
+                    var b_or = (OpenBitSet)b.Clone(); b_or.Or(b0);
+                    var b_xor = (OpenBitSet)b.Clone(); b_xor.Xor(b0);
+                    var b_andn = (OpenBitSet)b.Clone(); b_andn.AndNot(b0);
 
                     DoIterate(a_and, b_and, mode);
                     DoIterate(a_or, b_or, mode);
@@ -334,8 +413,8 @@ namespace Lucene.Net.Util
 		public virtual void  TestEquals()
 		{
 			rand = NewRandom();
-			OpenBitSet b1 = new OpenBitSet(1111);
-			OpenBitSet b2 = new OpenBitSet(2222);
+			var b1 = new OpenBitSet(1111);
+			var b2 = new OpenBitSet(2222);
 			Assert.IsTrue(b1.Equals(b2));
 			Assert.IsTrue(b2.Equals(b1));
 			b1.Set(10);
@@ -369,7 +448,7 @@ namespace Lucene.Net.Util
 			Assert.AreEqual(1, BitUtil.Ntz2(num));
 			Assert.AreEqual(1, BitUtil.Ntz3(num));
 			
-			for (int i = 0; i < 64; i++)
+			for (var i = 0; i < 64; i++)
 			{
 				num = 1L << i;
 				Assert.AreEqual(i, BitUtil.Ntz(num));
@@ -381,8 +460,8 @@ namespace Lucene.Net.Util
         [Test]
         public void TestHashCodeEquals()
         {
-            OpenBitSet bs1 = new OpenBitSet(200);
-            OpenBitSet bs2 = new OpenBitSet(64);
+            var bs1 = new OpenBitSet(200);
+            var bs2 = new OpenBitSet(64);
             bs1.Set(3);
             bs2.Set(3);
             Assert.AreEqual(bs1, bs2);