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:44 UTC

[08/50] [abbrv] git commit: Port: more util test classes

Port: more util test classes


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

Branch: refs/heads/branch_4x
Commit: f1544d6656045a482173cb1ff189e9fcde7050b5
Parents: 27c7d0d
Author: James Blair <jm...@gmail.com>
Authored: Thu Jul 11 18:37:06 2013 -0400
Committer: James Blair <jm...@gmail.com>
Committed: Thu Jul 11 18:37:06 2013 -0400

----------------------------------------------------------------------
 test/core/Util/TestSmallFloat.cs        | 262 ++++++++++++++++-----------
 test/core/Util/TestSortedVIntList.cs    | 244 -------------------------
 test/core/Util/TestSorterTemplate.cs    | 198 ++++++++++++++++++++
 test/core/Util/TestStringHelper.cs      |  48 -----
 test/core/Util/TestStringIntern.cs      | 137 --------------
 test/core/Util/TestUnicodeUtil.cs       | 173 ++++++++++++++++++
 test/core/Util/TestVersion.cs           |  45 ++++-
 test/core/Util/TestVersionComparator.cs |  38 ++++
 test/core/Util/TestVirtualMethod.cs     |  88 +++++++++
 9 files changed, 688 insertions(+), 545 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestSmallFloat.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestSmallFloat.cs b/test/core/Util/TestSmallFloat.cs
index de1c613..99ed773 100644
--- a/test/core/Util/TestSmallFloat.cs
+++ b/test/core/Util/TestSmallFloat.cs
@@ -21,114 +21,156 @@ using NUnit.Framework;
 
 namespace Lucene.Net.Util
 {
-	
-	/// <version>  $Id$
-	/// </version>
-	[TestFixture]
-	public class TestSmallFloat:LuceneTestCase
-	{
-		
-		// original lucene byteToFloat
-		internal static float Orig_byteToFloat(byte b)
-		{
-			if (b == 0)
-			// zero is a special case
-				return 0.0f;
-			int mantissa = b & 7;
-			int exponent = (b >> 3) & 31;
-			int bits = ((exponent + (63 - 15)) << 24) | (mantissa << 21);
-			return BitConverter.ToSingle(BitConverter.GetBytes(bits), 0);
-		}
-		
-		// original lucene floatToByte
-		internal static sbyte Orig_floatToByte(float f)
-		{
-			if (f < 0.0f)
-			// round negatives up to zero
-				f = 0.0f;
-			
-			if (f == 0.0f)
-			// zero is a special case
-				return 0;
-			
-			int bits = BitConverter.ToInt32(BitConverter.GetBytes(f), 0);
-			int mantissa = (bits & 0xffffff) >> 21;
-			int exponent = (((bits >> 24) & 0x7f) - 63) + 15;
-			
-			if (exponent > 31)
-			{
-				// overflow: use max value
-				exponent = 31;
-				mantissa = 7;
-			}
-			
-			if (exponent < 0)
-			{
-				// underflow: use min value
-				exponent = 0;
-				mantissa = 1;
-			}
-			
-			return (sbyte) ((exponent << 3) | mantissa); // pack into a byte
-		}
-		
-		[Test]
-		public virtual void  TestByteToFloat()
-		{
-			for (int i = 0; i < 256; i++)
-			{
-				float f1 = Orig_byteToFloat((byte) i);
-				float f2 = SmallFloat.ByteToFloat((byte) i, 3, 15);
-				float f3 = SmallFloat.Byte315ToFloat((byte) i);
-				Assert.AreEqual(f1, f2, 0.0);
-				Assert.AreEqual(f2, f3, 0.0);
-				
-				float f4 = SmallFloat.ByteToFloat((byte) i, 5, 2);
-				float f5 = SmallFloat.Byte52ToFloat((byte) i);
-				Assert.AreEqual(f4, f5, 0.0);
-			}
-		}
-		
-		[Test]
-		public virtual void  TestFloatToByte()
-		{
-			System.Random rand = NewRandom();
-			// up iterations for more exhaustive test after changing something
-			for (int i = 0; i < 100000; i++)
-			{
-				float f = BitConverter.ToSingle(BitConverter.GetBytes(rand.Next()), 0);
-				if (f != f)
-					continue; // skip NaN
-				sbyte b1 = Orig_floatToByte(f);
-				sbyte b2 = SmallFloat.FloatToByte(f, 3, 15);
-				sbyte b3 = SmallFloat.FloatToByte315(f);
-				Assert.AreEqual(b1, b2);
-				Assert.AreEqual(b2, b3);
-				
-				sbyte b4 = SmallFloat.FloatToByte(f, 5, 2);
-				sbyte b5 = SmallFloat.FloatToByte52(f);
-				Assert.AreEqual(b4, b5);
-			}
-		}
-		
-		/// <summary> 
-		/// // Do an exhaustive test of all possible floating point values
-		/// // for the 315 float against the original norm encoding in Similarity.
-		/// // Takes 75 seconds on my Pentium4 3GHz, with Java5 -server
-		/// public void testAllFloats() {
-		/// for(int i = Integer.MIN_VALUE;;i++) {
-		/// float f = Float.intBitsToFloat(i);
-		/// if (f==f) { // skip non-numbers
-		/// byte b1 = orig_floatToByte(f);
-		/// byte b2 = SmallFloat.floatToByte315(f);
-		/// if (b1!=b2) {
-		/// TestCase.fail("Failed floatToByte315 for float " + f);
-		/// }
-		/// }
-		/// if (i==Integer.MAX_VALUE) break;
-		/// }
-		/// }
-		/// *
-		/// </summary>
-	}
+
+    /// <version>  $Id$
+    /// </version>
+    [TestFixture]
+    public class TestSmallFloat : LuceneTestCase
+    {
+
+        // original lucene byteToFloat
+        internal static float Orig_byteToFloat(byte b)
+        {
+            if (b == 0)
+                // zero is a special case
+                return 0.0f;
+            int mantissa = b & 7;
+            int exponent = (b >> 3) & 31;
+            int bits = ((exponent + (63 - 15)) << 24) | (mantissa << 21);
+            return BitConverter.ToSingle(BitConverter.GetBytes(bits), 0);
+        }
+
+        internal static sbyte Orig_floatToByte_v13(float f)
+        {
+            if (f < 0.0f)                                 // round negatives up to zero
+                f = 0.0f;
+
+            if (f == 0.0f)                                // zero is a special case
+                return 0;
+
+            int bits = BitConverter.ToInt32(BitConverter.GetBytes(f), 0);           // parse float into parts
+            int mantissa = (bits & 0xffffff) >> 21;
+            int exponent = (((bits >> 24) & 0x7f) - 63) + 15;
+
+            if (exponent > 31)
+            {                          // overflow: use max value
+                exponent = 31;
+                mantissa = 7;
+            }
+
+            if (exponent < 0)
+            {                           // underflow: use min value
+                exponent = 0;
+                mantissa = 1;
+            }
+
+            return (sbyte)((exponent << 3) | mantissa);    // pack into a byte
+        }
+
+        // original lucene floatToByte
+        internal static sbyte Orig_floatToByte(float f)
+        {
+            if (f < 0.0f)
+                // round negatives up to zero
+                f = 0.0f;
+
+            if (f == 0.0f)
+                // zero is a special case
+                return 0;
+
+            int bits = BitConverter.ToInt32(BitConverter.GetBytes(f), 0);
+            int mantissa = (bits & 0xffffff) >> 21;
+            int exponent = (((bits >> 24) & 0x7f) - 63) + 15;
+
+            if (exponent > 31)
+            {
+                // overflow: use max value
+                exponent = 31;
+                mantissa = 7;
+            }
+
+            if (exponent < 0)
+            {
+                // underflow: use min value
+                exponent = 0;
+                mantissa = 1;
+            }
+
+            return (sbyte)((exponent << 3) | mantissa); // pack into a byte
+        }
+
+        [Test]
+        public virtual void TestByteToFloat()
+        {
+            for (int i = 0; i < 256; i++)
+            {
+                float f1 = Orig_byteToFloat((byte)i);
+                float f2 = SmallFloat.ByteToFloat((byte)i, 3, 15);
+                float f3 = SmallFloat.Byte315ToFloat((sbyte)i);
+                Assert.AreEqual(f1, f2, 0.0);
+                Assert.AreEqual(f2, f3, 0.0);
+
+                float f4 = SmallFloat.ByteToFloat((byte)i, 5, 2);
+                float f5 = SmallFloat.Byte52ToFloat((sbyte)i);
+                Assert.AreEqual(f4, f5, 0.0);
+            }
+        }
+
+        [Test]
+        public virtual void TestFloatToByte()
+        {
+            assertEquals(0, Orig_floatToByte_v13(5.8123817E-10f));       // verify the old bug (see LUCENE-2937)
+            assertEquals(1, Orig_floatToByte(5.8123817E-10f));           // verify it's fixed in this test code
+            assertEquals(1, SmallFloat.FloatToByte315(5.8123817E-10f));  // verify it's fixed
+
+            // test some constants
+            assertEquals(0, SmallFloat.FloatToByte315(0));
+            assertEquals(1, SmallFloat.FloatToByte315(float.MinValue));             // underflow rounds up to smallest positive
+            assertEquals(255, SmallFloat.FloatToByte315(float.MaxValue) & 0xff);    // overflow rounds down to largest positive
+            assertEquals(255, SmallFloat.FloatToByte315(float.PositiveInfinity) & 0xff);
+
+            // all negatives map to 0
+            assertEquals(0, SmallFloat.FloatToByte315(-float.MinValue));
+            assertEquals(0, SmallFloat.FloatToByte315(-float.MaxValue));
+            assertEquals(0, SmallFloat.FloatToByte315(float.NegativeInfinity));
+
+
+            // up iterations for more exhaustive test after changing something
+            int num = AtLeast(100000);
+            for (int i = 0; i < num; i++)
+            {
+                float f = BitConverter.ToSingle(BitConverter.GetBytes(new Random().Next()), 0);
+                if (float.IsNaN(f)) continue;    // skip NaN
+                sbyte b1 = Orig_floatToByte(f);
+                sbyte b2 = SmallFloat.FloatToByte(f, 3, 15);
+                sbyte b3 = SmallFloat.FloatToByte315(f);
+                assertEquals(b1, b2);
+                assertEquals(b2, b3);
+
+                sbyte b4 = SmallFloat.FloatToByte(f, 5, 2);
+                sbyte b5 = SmallFloat.FloatToByte52(f);
+                assertEquals(b4, b5);
+            }
+        }
+
+        /// <summary> 
+        /// // Do an exhaustive test of all possible floating point values
+        /// // for the 315 float against the original norm encoding in Similarity.
+        /// // Takes 75 seconds on my Pentium4 3GHz, with Java5 -server
+        /// public void testAllFloats() {
+        /// for(int i = Integer.MinValue;;i++) {
+        /// float f = Float.intBitsToFloat(i);
+        /// if (f==f) { // skip non-numbers
+        /// byte b1 = orig_floatToByte(f);
+        /// byte b2 = SmallFloat.floatToByte315(f);
+        /// if (b1!=b2) {
+        /// TestCase.fail("Failed floatToByte315 for float " + f);
+        /// }
+        /// }
+        /// if (i==Integer.MaxValue) break;
+        /// }
+        /// }
+        /// *
+        /// </summary>
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestSortedVIntList.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestSortedVIntList.cs b/test/core/Util/TestSortedVIntList.cs
deleted file mode 100644
index be63f10..0000000
--- a/test/core/Util/TestSortedVIntList.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-/* 
- * 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 System;
-
-using NUnit.Framework;
-
-using DocIdSetIterator = Lucene.Net.Search.DocIdSetIterator;
-
-namespace Lucene.Net.Util
-{
-	
-	[TestFixture]
-	public class TestSortedVIntList:LuceneTestCase
-	{
-		
-		internal virtual void  TstIterator(SortedVIntList vintList, int[] ints)
-		{
-			for (int i = 0; i < ints.Length; i++)
-			{
-				if ((i > 0) && (ints[i - 1] == ints[i]))
-				{
-					return ; // DocNrSkipper should not skip to same document.
-				}
-			}
-			DocIdSetIterator m = vintList.Iterator();
-			for (int i = 0; i < ints.Length; i++)
-			{
-				Assert.IsTrue(m.NextDoc() != DocIdSetIterator.NO_MORE_DOCS, "No end of Matcher at: " + i);
-				Assert.AreEqual(ints[i], m.DocID());
-			}
-			Assert.IsTrue(m.NextDoc() == DocIdSetIterator.NO_MORE_DOCS, "End of Matcher");
-		}
-		
-		internal virtual void  TstVIntList(SortedVIntList vintList, int[] ints, int expectedByteSize)
-		{
-			Assert.AreEqual(ints.Length, vintList.Size, "Size");
-			Assert.AreEqual(expectedByteSize, vintList.ByteSize, "Byte size");
-			TstIterator(vintList, ints);
-		}
-		
-		public virtual void  TstViaBitSet(int[] ints, int expectedByteSize)
-		{
-			int MAX_INT_FOR_BITSET = 1024 * 1024;
-			//mgarski - BitArray cannot grow, so make as large as we would need it to be
-			System.Collections.BitArray bs = new System.Collections.BitArray(MAX_INT_FOR_BITSET);
-			for (int i = 0; i < ints.Length; i++)
-			{
-				if (ints[i] > MAX_INT_FOR_BITSET)
-				{
-					return ; // BitSet takes too much memory
-				}
-				if ((i > 0) && (ints[i - 1] == ints[i]))
-				{
-					return ; // BitSet cannot store duplicate.
-				}
-				bs.Set(ints[i], true);
-			}
-			SortedVIntList svil = new SortedVIntList(bs);
-			TstVIntList(svil, ints, expectedByteSize);
-			TstVIntList(new SortedVIntList(svil.Iterator()), ints, expectedByteSize);
-		}
-		
-		private const int VB1 = 0x7F;
-		private const int BIT_SHIFT = 7;
-		private static readonly int VB2 = (VB1 << BIT_SHIFT) | VB1;
-		private static readonly int VB3 = (VB2 << BIT_SHIFT) | VB1;
-		private static readonly int VB4 = (VB3 << BIT_SHIFT) | VB1;
-		
-		private int VIntByteSize(int i)
-		{
-			System.Diagnostics.Debug.Assert(i >= 0);
-			if (i <= VB1)
-				return 1;
-			if (i <= VB2)
-				return 2;
-			if (i <= VB3)
-				return 3;
-			if (i <= VB4)
-				return 4;
-			return 5;
-		}
-		
-		private int VIntListByteSize(int[] ints)
-		{
-			int byteSize = 0;
-			int last = 0;
-			for (int i = 0; i < ints.Length; i++)
-			{
-				byteSize += VIntByteSize(ints[i] - last);
-				last = ints[i];
-			}
-			return byteSize;
-		}
-		
-		public virtual void  TstInts(int[] ints)
-		{
-			int expectedByteSize = VIntListByteSize(ints);
-			try
-			{
-				TstVIntList(new SortedVIntList(ints), ints, expectedByteSize);
-				TstViaBitSet(ints, expectedByteSize);
-			}
-			catch (System.IO.IOException ioe)
-			{
-				throw new System.SystemException("", ioe);
-			}
-		}
-		
-		public virtual void  TstIllegalArgExc(int[] ints)
-		{
-            Assert.Throws<ArgumentException>(() => new SortedVIntList(ints), "Expected ArgumentException");
-		}
-		
-		private int[] FibArray(int a, int b, int size)
-		{
-			int[] fib = new int[size];
-			fib[0] = a;
-			fib[1] = b;
-			for (int i = 2; i < size; i++)
-			{
-				fib[i] = fib[i - 1] + fib[i - 2];
-			}
-			return fib;
-		}
-		
-		private int[] ReverseDiffs(int[] ints)
-		{
-			// reverse the order of the successive differences
-			int[] res = new int[ints.Length];
-			for (int i = 0; i < ints.Length; i++)
-			{
-				res[i] = ints[ints.Length - 1] + (ints[0] - ints[ints.Length - 1 - i]);
-			}
-			return res;
-		}
-		
-		[Test]
-		public virtual void  Test01()
-		{
-			TstInts(new int[]{});
-		}
-		[Test]
-		public virtual void  Test02()
-		{
-			TstInts(new int[]{0});
-		}
-		[Test]
-		public virtual void  Test04a()
-		{
-			TstInts(new int[]{0, VB2 - 1});
-		}
-		[Test]
-		public virtual void  Test04b()
-		{
-			TstInts(new int[]{0, VB2});
-		}
-		[Test]
-		public virtual void  Test04c()
-		{
-			TstInts(new int[]{0, VB2 + 1});
-		}
-		[Test]
-		public virtual void  Test05()
-		{
-			TstInts(FibArray(0, 1, 7)); // includes duplicate value 1
-		}
-		[Test]
-		public virtual void  Test05b()
-		{
-			TstInts(ReverseDiffs(FibArray(0, 1, 7)));
-		}
-		[Test]
-		public virtual void  Test06()
-		{
-			TstInts(FibArray(1, 2, 45)); // no duplicates, size 46 exceeds max int.
-		}
-		[Test]
-		public virtual void  Test06b()
-		{
-			TstInts(ReverseDiffs(FibArray(1, 2, 45)));
-		}
-		[Test]
-		public virtual void  Test07a()
-		{
-			TstInts(new int[]{0, VB3});
-		}
-		[Test]
-		public virtual void  Test07b()
-		{
-			TstInts(new int[]{1, VB3 + 2});
-		}
-		[Test]
-		public virtual void  Test07c()
-		{
-			TstInts(new int[]{2, VB3 + 4});
-		}
-		[Test]
-		public virtual void  Test08a()
-		{
-			TstInts(new int[]{0, VB4 + 1});
-		}
-		[Test]
-		public virtual void  Test08b()
-		{
-			TstInts(new int[]{1, VB4 + 1});
-		}
-		[Test]
-		public virtual void  Test08c()
-		{
-			TstInts(new int[]{2, VB4 + 1});
-		}
-		
-		[Test]
-		public virtual void  Test10()
-		{
-			TstIllegalArgExc(new int[]{- 1});
-		}
-		[Test]
-		public virtual void  Test11()
-		{
-			TstIllegalArgExc(new int[]{1, 0});
-		}
-		[Test]
-		public virtual void  Test12()
-		{
-			TstIllegalArgExc(new int[]{0, 1, 1, 2, 3, 5, 8, 0});
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestSorterTemplate.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestSorterTemplate.cs b/test/core/Util/TestSorterTemplate.cs
new file mode 100644
index 0000000..9f60d38
--- /dev/null
+++ b/test/core/Util/TestSorterTemplate.cs
@@ -0,0 +1,198 @@
+using System;
+using Lucene.Net.Support;
+using Lucene.Net.Test.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestSorterTemplate : LuceneTestCase
+    {
+        private Random random = new Random();
+
+        private static readonly int SLOW_SORT_THRESHOLD = 1000;
+
+        // A sorter template that compares only the last 32 bits
+        internal class Last32BitsSorterTemplate : SorterTemplate
+        {
+
+            long[] arr;
+            long pivot;
+
+            internal Last32BitsSorterTemplate(long[] arr)
+            {
+                this.arr = arr;
+            }
+
+            protected internal override void Swap(int i, int j)
+            {
+                long tmp = arr[i];
+                arr[i] = arr[j];
+                arr[j] = tmp;
+            }
+
+            private int CompareValues(long i, long j)
+            {
+                // only compare the last 32 bits
+                long a = i & 0xFFFFFFFFL;
+                long b = j & 0xFFFFFFFFL;
+                return a < b ? -1 : a == b ? 0 : 1;
+            }
+
+            protected internal override int Compare(int i, int j)
+            {
+                return CompareValues(arr[i], arr[j]);
+            }
+
+            protected internal override void SetPivot(int i)
+            {
+                pivot = arr[i];
+            }
+
+            protected internal override int ComparePivot(int j)
+            {
+                return CompareValues(pivot, arr[j]);
+            }
+
+            protected override void Merge(int lo, int pivot, int hi, int len1, int len2)
+            {
+                // TimSort and MergeSort should call runMerge to sort out trivial cases
+                Assert.IsTrue(len1 >= 1);
+                Assert.IsTrue(len2 >= 1);
+                Assert.IsTrue(len1 + len2 >= 3);
+                Assert.IsTrue(Compare(lo, pivot) > 0);
+                Assert.IsTrue(Compare(pivot - 1, hi - 1) > 0);
+                Assert.IsFalse(Compare(pivot - 1, pivot) <= 0);
+                base.Merge(lo, pivot, hi, len1, len2);
+            }
+
+        }
+
+        void TestSort(int[] intArr)
+        {
+            // we modify the array as a long[] and store the original ord in the first 32 bits
+            // to be able to check stability
+            long[] arr = ToLongsAndOrds(intArr);
+
+            // use MergeSort as a reference
+            // Assert.AreEqual checks for sorting + stability
+            // Assert.AreEqual(ToInts) checks for sorting only
+            long[] mergeSorted = Arrays.CopyOf(arr, arr.Length);
+            new Last32BitsSorterTemplate(mergeSorted).MergeSort(0, arr.Length - 1);
+
+            if (arr.Length < SLOW_SORT_THRESHOLD)
+            {
+                long[] insertionSorted = Arrays.CopyOf(arr, arr.Length);
+                new Last32BitsSorterTemplate(insertionSorted).InsertionSort(0, arr.Length - 1);
+                Assert.AreEqual(mergeSorted, insertionSorted);
+
+                long[] binarySorted = Arrays.CopyOf(arr, arr.Length);
+                new Last32BitsSorterTemplate(binarySorted).BinarySort(0, arr.Length - 1);
+                Assert.AreEqual(mergeSorted, binarySorted);
+            }
+
+            long[] quickSorted = Arrays.CopyOf(arr, arr.Length);
+            new Last32BitsSorterTemplate(quickSorted).QuickSort(0, arr.Length - 1);
+            Assert.AreEqual(ToInts(mergeSorted), ToInts(quickSorted));
+
+            long[] timSorted = Arrays.CopyOf(arr, arr.Length);
+            new Last32BitsSorterTemplate(timSorted).TimSort(0, arr.Length - 1);
+            Assert.AreEqual(mergeSorted, timSorted);
+        }
+
+        private int[] ToInts(long[] longArr)
+        {
+            int[] arr = new int[longArr.Length];
+            for (int i = 0; i < longArr.Length; ++i)
+            {
+                arr[i] = (int)longArr[i];
+            }
+            return arr;
+        }
+
+        private long[] ToLongsAndOrds(int[] intArr)
+        {
+            long[] arr = new long[intArr.Length];
+            for (int i = 0; i < intArr.Length; ++i)
+            {
+                arr[i] = (((long)i) << 32) | (intArr[i] & 0xFFFFFFFFL);
+            }
+            return arr;
+        }
+
+        int RandomLength()
+        {
+            return _TestUtil.NextInt(random, 1, random.NextBool() ? SLOW_SORT_THRESHOLD : 100000);
+        }
+
+        [Test]
+        public void TestEmpty()
+        {
+            TestSort(new int[0]);
+        }
+
+        [Test]
+        public void TestAscending()
+        {
+            int Length = RandomLength();
+            int[] arr = new int[Length];
+            arr[0] = random.Next(10);
+            for (int i = 1; i < arr.Length; ++i)
+            {
+                arr[i] = arr[i - 1] + _TestUtil.NextInt(random, 0, 10);
+            }
+            TestSort(arr);
+        }
+
+        [Test]
+        public void TestDescending()
+        {
+            int Length = RandomLength();
+            int[] arr = new int[Length];
+            arr[0] = random.Next(10);
+            for (int i = 1; i < arr.Length; ++i)
+            {
+                arr[i] = arr[i - 1] - _TestUtil.NextInt(random, 0, 10);
+            }
+            TestSort(arr);
+        }
+
+        [Test]
+        public void TestStrictlyDescending()
+        {
+            int Length = RandomLength();
+            int[] arr = new int[Length];
+            arr[0] = random.Next(10);
+            for (int i = 1; i < arr.Length; ++i)
+            {
+                arr[i] = arr[i - 1] - _TestUtil.NextInt(random, 1, 10);
+            }
+            TestSort(arr);
+        }
+
+        [Test]
+        public void TestRandom1()
+        {
+            int Length = RandomLength();
+            int[] arr = new int[Length];
+            for (int i = 1; i < arr.Length; ++i)
+            {
+                arr[i] = random.Next();
+            }
+            TestSort(arr);
+        }
+
+        [Test]
+        public void TestRandom2()
+        {
+            int Length = RandomLength();
+            int[] arr = new int[Length];
+            for (int i = 1; i < arr.Length; ++i)
+            {
+                arr[i] = random.Next(10);
+            }
+            TestSort(arr);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestStringHelper.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestStringHelper.cs b/test/core/Util/TestStringHelper.cs
deleted file mode 100644
index b9eb290..0000000
--- a/test/core/Util/TestStringHelper.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 
- * 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 System;
-
-using NUnit.Framework;
-
-namespace Lucene.Net.Util
-{
-	
-	[TestFixture]
-	public class TestStringHelper:LuceneTestCase
-	{
-		
-		
-		[Test]
-		public virtual void  TestStringDifference()
-		{
-			System.String test1 = "test";
-			System.String test2 = "testing";
-			
-			int result = StringHelper.StringDifference(test1, test2);
-			Assert.IsTrue(result == 4);
-			
-			test2 = "foo";
-			result = StringHelper.StringDifference(test1, test2);
-			Assert.IsTrue(result == 0);
-			
-			test2 = "test";
-			result = StringHelper.StringDifference(test1, test2);
-			Assert.IsTrue(result == 4);
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestStringIntern.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestStringIntern.cs b/test/core/Util/TestStringIntern.cs
deleted file mode 100644
index 52b902d..0000000
--- a/test/core/Util/TestStringIntern.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-/* 
- * 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 System;
-using System.Threading;
-
-using NUnit.Framework;
-
-namespace Lucene.Net.Util
-{
-	
-    [TestFixture]
-	public class TestStringIntern:LuceneTestCase
-	{
-		public TestStringIntern()
-		{
-			InitBlock();
-		}
-		private class TestRun
-		{
-			public TestRun(Int32 seed, int iter, bool newStrings, TestStringIntern enclosingInstance)
-			{
-				this.seed = seed;
-				this.iter = iter;
-				this.newStrings = newStrings;
-				this.enclosingInstance = enclosingInstance;
-                this.Reset = new ManualResetEvent(false);
-			}
-			private System.Int32 seed;
-			private int iter;
-			private bool newStrings;
-			private TestStringIntern enclosingInstance;
-			public TestStringIntern Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-
-            public ManualResetEvent Reset;
-
-			public void Run(System.Object state)
-			{
-				System.Random rand = new Random(seed);
-				System.String[] myInterned = new System.String[Enclosing_Instance.testStrings.Length];
-				for (int j = 0; j < iter; j++)
-				{
-					int idx = rand.Next(Enclosing_Instance.testStrings.Length);
-					System.String s = Enclosing_Instance.testStrings[idx];
-					if (newStrings == true && (new System.Random().NextDouble()) > 0.5)
-						s = new System.Text.StringBuilder(s).ToString(); // make a copy half of the time
-					System.String interned = StringHelper.Intern(s);
-					System.String prevInterned = myInterned[idx];
-					System.String otherInterned = Enclosing_Instance.internedStrings[idx];
-					
-					// test against other threads
-                    Assert.IsFalse(otherInterned != null && otherInterned != interned);
-					Enclosing_Instance.internedStrings[idx] = interned;
-					
-					// test against local copy
-                    Assert.IsFalse(prevInterned != null && prevInterned != interned);
-					myInterned[idx] = interned;
-				}
-                this.Reset.Set();
-			}
-		}
-		private void  InitBlock()
-		{
-			r = NewRandom();
-		}
-		internal System.String[] testStrings;
-		internal System.String[] internedStrings;
-		internal System.Random r;
-		
-		private System.String RandStr(int len)
-		{
-			char[] arr = new char[len];
-			for (int i = 0; i < len; i++)
-			{
-				arr[i] = (char) ('a' + r.Next(26));
-			}
-			return new System.String(arr);
-		}
-		
-		private void  MakeStrings(int sz)
-		{
-			testStrings = new System.String[sz];
-			internedStrings = new System.String[sz];
-			for (int i = 0; i < sz; i++)
-			{
-				testStrings[i] = RandStr(r.Next(8) + 3);
-			}
-		}
-		
-        [Test]
-		public virtual void  TestStringIntern_Renamed()
-		{
-			MakeStrings(1024 * 10); // something greater than the capacity of the default cache size
-			// makeStrings(100);  // realistic for perf testing
-			int nThreads = 20;
-			// final int iter=100000;
-			int iter = 1000000;
-			bool newStrings = true;
-			
-			// try native intern
-			// StringHelper.interner = new StringInterner();
-			
-			TestRun[] threads = new TestRun[nThreads];
-            ManualResetEvent[] resets = new ManualResetEvent[nThreads];
-			for (int i = 0; i < nThreads; i++)
-			{
-				int seed = i;
-				threads[i] = new TestRun(seed, iter, newStrings, this);
-                resets[i] = threads[i].Reset;
-                ThreadPool.QueueUserWorkItem(new WaitCallback(threads[i].Run));
-			}
-
-            WaitHandle.WaitAll(resets);
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestUnicodeUtil.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestUnicodeUtil.cs b/test/core/Util/TestUnicodeUtil.cs
new file mode 100644
index 0000000..6a733a7
--- /dev/null
+++ b/test/core/Util/TestUnicodeUtil.cs
@@ -0,0 +1,173 @@
+using System;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestUnicodeUtil : LuceneTestCase
+    {
+        private Random random = new Random();
+        
+        [Test]
+        public void TestCodePointCount()
+        {
+            // Check invalid codepoints.
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0x80, 'z', 'z', 'z'));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xc0 - 1, 'z', 'z', 'z'));
+            // Check 5-byte and longer sequences.
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xf8, 'z', 'z', 'z'));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xfc, 'z', 'z', 'z'));
+            // Check improperly terminated codepoints.
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xc2));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xe2));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xe2, 0x82));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xf0));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xf0, 0xa4));
+            AssertcodePointCountThrowsAssertionOn(AsByteArray('z', 0xf0, 0xa4, 0xad));
+
+            // Check some typical examples (multibyte).
+            Assert.AreEqual(0, UnicodeUtil.CodePointCount(new BytesRef(AsByteArray())));
+            Assert.AreEqual(3, UnicodeUtil.CodePointCount(new BytesRef(AsByteArray('z', 'z', 'z'))));
+            Assert.AreEqual(2, UnicodeUtil.CodePointCount(new BytesRef(AsByteArray('z', 0xc2, 0xa2))));
+            Assert.AreEqual(2, UnicodeUtil.CodePointCount(new BytesRef(AsByteArray('z', 0xe2, 0x82, 0xac))));
+            Assert.AreEqual(2, UnicodeUtil.CodePointCount(new BytesRef(AsByteArray('z', 0xf0, 0xa4, 0xad, 0xa2))));
+
+            // And do some random stuff.
+            var utf8 = new BytesRef(20);
+            int num = AtLeast(50000);
+            for (var i = 0; i < num; i++)
+            {
+                string s = _TestUtil.RandomUnicodeString(random);
+                UnicodeUtil.UTF16toUTF8(s, 0, s.Length, utf8);
+                Assert.AreEqual(s.CodePointCount(0, s.Length),
+                             UnicodeUtil.CodePointCount(utf8));
+            }
+        }
+
+        private sbyte[] AsByteArray(params int[] ints)
+        {
+            var asByteArray = new sbyte[ints.Length];
+            for (var i = 0; i < ints.Length; i++)
+            {
+                asByteArray[i] = (sbyte)ints[i];
+            }
+            return asByteArray;
+        }
+
+        private void AssertcodePointCountThrowsAssertionOn(params sbyte[] bytes)
+        {
+            var threwAssertion = false;
+            try
+            {
+                UnicodeUtil.CodePointCount(new BytesRef(bytes));
+            }
+            catch (ArgumentException e)
+            {
+                threwAssertion = true;
+            }
+            Assert.IsTrue(threwAssertion);
+        }
+
+        [Test]
+        public void TestUTF8toUTF32()
+        {
+            var utf8 = new BytesRef(20);
+            var utf32 = new IntsRef(20);
+            var codePoints = new int[20];
+            int num = AtLeast(50000);
+            for (var i = 0; i < num; i++)
+            {
+                string s = _TestUtil.RandomUnicodeString(random);
+                UnicodeUtil.UTF16toUTF8(s, 0, s.Length, utf8);
+                UnicodeUtil.UTF8toUTF32(utf8, utf32);
+
+                var charUpto = 0;
+                var intUpto = 0;
+                while (charUpto < s.Length)
+                {
+                    int cp = s.CodePointAt(charUpto);
+                    codePoints[intUpto++] = cp;
+                    charUpto += Character.CharCount(cp);
+                }
+                if (!ArrayUtil.Equals(codePoints, 0, utf32.ints, utf32.offset, intUpto))
+                {
+                    Console.WriteLine("FAILED");
+                    for (int j = 0; j < s.Length; j++)
+                    {
+                        Console.WriteLine("  char[" + j + "]=" + int.ToHexString(s.CharAt(j)));
+                    }
+                    Console.WriteLine();
+                    Assert.AreEqual(intUpto, utf32.length);
+                    for (int j = 0; j < intUpto; j++)
+                    {
+                        Console.WriteLine("  " + int.ToHexString(utf32.ints[j]) + " vs " + int.ToHexString(codePoints[j]));
+                    }
+                    Fail("mismatch");
+                }
+            }
+        }
+
+        [Test]
+        public void TestNewString()
+        {
+            int[] codePoints = {
+                Character.ToCodePoint(Character.MIN_HIGH_SURROGATE,
+                    Character.MAX_LOW_SURROGATE),
+                Character.ToCodePoint(Character.MAX_HIGH_SURROGATE,
+                    Character.MIN_LOW_SURROGATE), Character.MAX_HIGH_SURROGATE, 'A',
+                -1,};
+
+            string cpString = "" + Character.MIN_HIGH_SURROGATE
+                + Character.MAX_LOW_SURROGATE + Character.MAX_HIGH_SURROGATE
+                + Character.MIN_LOW_SURROGATE + Character.MAX_HIGH_SURROGATE + 'A';
+
+            var tests = new int[,] { {0, 1, 0, 2}, {0, 2, 0, 4}, {1, 1, 2, 2},
+                {1, 2, 2, 3}, {1, 3, 2, 4}, {2, 2, 4, 2}, {2, 3, 0, -1}, {4, 5, 0, -1},
+                {3, -1, 0, -1}};
+
+            for (int i = 0; i < tests.length; ++i)
+            {
+                int[] t = tests[i];
+                var s = t[0];
+                var c = t[1];
+                var rs = t[2];
+                var rc = t[3];
+
+                try
+                {
+                    string str = UnicodeUtil.NewString(codePoints, s, c);
+                    Assert.IsFalse(rc == -1);
+                    Assert.AreEqual(cpString.Substring(rs, rs + rc), str);
+                    continue;
+                }
+                catch (IndexOutOfRangeException e1)
+                {
+                    // Ignored.
+                }
+                catch (ArgumentException e2)
+                {
+                    // Ignored.
+                }
+                Assert.IsTrue(rc == -1);
+            }
+        }
+
+        public void testUTF8UTF16CharsRef()
+        {
+            int num = AtLeast(3989);
+            for (int i = 0; i < num; i++)
+            {
+                string unicode = _TestUtil.RandomRealisticUnicodeString(random);
+                var bytesRef = new BytesRef(unicode);
+                var arr = new char[1 + random.Next(100)];
+                var offset = random.Next(arr.Length);
+                var len = random.Next(arr.Length - offset);
+                var cRef = new CharsRef(arr, offset, len);
+                UnicodeUtil.UTF8toUTF16(bytesRef, cRef);
+                Assert.AreEqual(cRef.ToString(), unicode);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestVersion.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestVersion.cs b/test/core/Util/TestVersion.cs
index 20f3f43..a970f61 100644
--- a/test/core/Util/TestVersion.cs
+++ b/test/core/Util/TestVersion.cs
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Linq;
 using NUnit.Framework;
 
 namespace Lucene.Net.Util
@@ -24,15 +25,47 @@ namespace Lucene.Net.Util
     public class TestVersion : LuceneTestCase
     {
         [Test]
-        public virtual void TestOnOrAfter()
+        public void Test()
         {
-            foreach (Version v in Enum.GetValues(typeof(Version)))
+            foreach (var v in Enum.GetValues(typeof(Version)))
             {
-                Assert.IsTrue(Version.LUCENE_CURRENT.OnOrAfter(v), string.Format("LUCENE_CURRENT must be always OnOrAfter({0})", v));
+                Assert.IsTrue("LUCENE_CURRENT must be always onOrAfter(" + v + ")", Version.LUCENE_CURRENT.OnOrAfter(v));
+            }
+            Assert.IsTrue(Version.LUCENE_40.OnOrAfter(Version.LUCENE_31));
+            Assert.IsTrue(Version.LUCENE_40.OnOrAfter(Version.LUCENE_40));
+            Assert.IsFalse(Version.LUCENE_30.OnOrAfter(Version.LUCENE_31));
+        }
+
+        [Test]
+        public void TestParseLeniently()
+        {
+            assertEquals(Version.LUCENE_40, Version.ParseLeniently("4.0"));
+            assertEquals(Version.LUCENE_40, Version.ParseLeniently("LUCENE_40"));
+            assertEquals(Version.LUCENE_CURRENT, Version.ParseLeniently("LUCENE_CURRENT"));
+        }
+
+        [Test]
+        public void TestDeprecations()
+        {
+            var values = Enum.GetValues(typeof (Version)).OfType<Version>().ToList();
+            // all but the latest version should be deprecated
+            for (int i = 0; i < values.Count; i++)
+            {
+                if (i + 1 == values.Count)
+                {
+                    Assert.AreSame(Version.LUCENE_CURRENT, values[i], "Last constant must be LUCENE_CURRENT");
+                }
+                var field = typeof(Version).GetField(Enum.GetName(typeof(Version), values[i]));
+                bool dep = field.IsDefined(typeof(ObsoleteAttribute), true);
+                if (i + 2 != values.Count)
+                {
+                    Assert.IsTrue(dep, Enum.GetName(typeof(Version), values[i]) + " should be deprecated");
+                }
+                else
+                {
+                    Assert.IsFalse(dep, Enum.GetName(typeof(Version), values[i]) + " should not be deprecated");
+                }
             }
-            Assert.IsTrue(Version.LUCENE_30.OnOrAfter(Version.LUCENE_29));
-            Assert.IsTrue(Version.LUCENE_30.OnOrAfter(Version.LUCENE_30));
-            Assert.IsFalse(Version.LUCENE_29.OnOrAfter(Version.LUCENE_30));
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestVersionComparator.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestVersionComparator.cs b/test/core/Util/TestVersionComparator.cs
new file mode 100644
index 0000000..e117900
--- /dev/null
+++ b/test/core/Util/TestVersionComparator.cs
@@ -0,0 +1,38 @@
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestVersionComparator : LuceneTestCase
+    {
+        [Test]
+        public void TestVersions()
+        {
+            var comp = StringHelper.VersionComparator;
+            Assert.IsTrue(comp.Compare("1", "2") < 0);
+            Assert.IsTrue(comp.Compare("1", "1") == 0);
+            Assert.IsTrue(comp.Compare("2", "1") > 0);
+
+            Assert.IsTrue(comp.Compare("1.1", "1") > 0);
+            Assert.IsTrue(comp.Compare("1", "1.1") < 0);
+            Assert.IsTrue(comp.Compare("1.1", "1.1") == 0);
+
+            Assert.IsTrue(comp.Compare("1.0", "1") == 0);
+            Assert.IsTrue(comp.Compare("1", "1.0") == 0);
+            Assert.IsTrue(comp.Compare("1.0.1", "1.0") > 0);
+            Assert.IsTrue(comp.Compare("1.0", "1.0.1") < 0);
+
+            Assert.IsTrue(comp.Compare("1.02.003", "1.2.3.0") == 0);
+            Assert.IsTrue(comp.Compare("1.2.3.0", "1.02.003") == 0);
+
+            Assert.IsTrue(comp.Compare("1.10", "1.9") > 0);
+            Assert.IsTrue(comp.Compare("1.9", "1.10") < 0);
+
+            Assert.IsTrue(comp.Compare("0", "1.0") < 0);
+            Assert.IsTrue(comp.Compare("00", "1.0") < 0);
+            Assert.IsTrue(comp.Compare("-1.0", "1.0") < 0);
+            Assert.IsTrue(comp.Compare("3.0", int.MinValue.ToString()) > 0);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f1544d66/test/core/Util/TestVirtualMethod.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestVirtualMethod.cs b/test/core/Util/TestVirtualMethod.cs
new file mode 100644
index 0000000..429cedf
--- /dev/null
+++ b/test/core/Util/TestVirtualMethod.cs
@@ -0,0 +1,88 @@
+using System;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestVirtualMethod : LuceneTestCase
+    {
+        private static readonly VirtualMethod<TestVirtualMethod> publicTestMethod =
+            new VirtualMethod<TestVirtualMethod>(typeof(TestVirtualMethod), "publicTest", typeof(string));
+        private static VirtualMethod<TestVirtualMethod> protectedTestMethod =
+            new VirtualMethod<TestVirtualMethod>(typeof(TestVirtualMethod), "protectedTest", typeof(int));
+
+        public void publicTest(string test) { }
+        protected void protectedTest(int test) { }
+
+        internal class TestClass1 : TestVirtualMethod
+        {
+            public override void publicTest(string test) { }
+            protected override void protectedTest(int test) { }
+        }
+
+        internal class TestClass2 : TestClass1
+        {
+            public override void protectedTest(int test) { }
+        }
+
+        internal class TestClass3 : TestClass2
+        {
+            public override void publicTest(string test) { }
+        }
+
+        internal class TestClass4 : TestVirtualMethod
+        {
+        }
+
+        internal class TestClass5 : TestClass4
+        {
+        }
+
+        [Test]
+        public void TestGeneral()
+        {
+            Assert.AreEqual(0, publicTestMethod.GetImplementationDistance(this.GetType()));
+            Assert.AreEqual(1, publicTestMethod.GetImplementationDistance(typeof(TestClass1)));
+            Assert.AreEqual(1, publicTestMethod.GetImplementationDistance(typeof(TestClass2)));
+            Assert.AreEqual(3, publicTestMethod.GetImplementationDistance(typeof(TestClass3)));
+            Assert.IsFalse(publicTestMethod.IsOverriddenAsOf(typeof(TestClass4)));
+            Assert.IsFalse(publicTestMethod.IsOverriddenAsOf(typeof(TestClass5)));
+
+            Assert.AreEqual(0, protectedTestMethod.GetImplementationDistance(this.GetType()));
+            Assert.AreEqual(1, protectedTestMethod.GetImplementationDistance(typeof(TestClass1)));
+            Assert.AreEqual(2, protectedTestMethod.GetImplementationDistance(typeof(TestClass2)));
+            Assert.AreEqual(2, protectedTestMethod.GetImplementationDistance(typeof(TestClass3)));
+            Assert.IsFalse(protectedTestMethod.IsOverriddenAsOf(typeof(TestClass4)));
+            Assert.IsFalse(protectedTestMethod.IsOverriddenAsOf(typeof(TestClass5)));
+
+            Assert.IsTrue(VirtualMethod.compareImplementationDistance(typeof(TestClass3), publicTestMethod, protectedTestMethod) > 0);
+            Assert.AreEqual(0, VirtualMethod.compareImplementationDistance(typeof(TestClass5), publicTestMethod, protectedTestMethod));
+        }
+
+        [Test]
+        public void TestExceptions()
+        {
+            Assert.Throws<ArgumentException>(() =>
+                {
+                    publicTestMethod.GetImplementationDistance((Type)typeof(LuceneTestCase));
+                }, "LuceneTestCase is not a subclass and can never override publicTest(string)")
+
+            Assert.Throws<ArgumentException>(() =>
+                {
+                    new VirtualMethod<TestVirtualMethod>(typeof(TestVirtualMethod), "bogus");
+                }, "Method bogus() does not exist, so IAE should be thrown");
+
+            Assert.Throws<ArgumentException>(() =>
+                {
+                    new VirtualMethod<TestClass2>(typeof(TestClass2), "publicTest", typeof(string));
+                }, "Method publicTest(string) is not declared in TestClass2, so IAE should be thrown");
+
+            Assert.Throws<InvalidOperationException>(() =>
+                {
+                    new VirtualMethod<TestVirtualMethod>(typeof(TestVirtualMethod), "publicTest", typeof(string));
+                }, "Violating singleton status succeeded");
+
+        }
+    }
+}