You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2015/12/10 19:38:52 UTC

[03/27] lucenenet git commit: adding converted analysis common tests

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
new file mode 100644
index 0000000..fa3e078
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiAnalyzer.cs
@@ -0,0 +1,183 @@
+using System;
+
+namespace org.apache.lucene.analysis.th
+{
+
+	/*
+	 * 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 KeywordTokenizer = org.apache.lucene.analysis.core.KeywordTokenizer;
+	using StopAnalyzer = org.apache.lucene.analysis.core.StopAnalyzer;
+	using FlagsAttribute = org.apache.lucene.analysis.tokenattributes.FlagsAttribute;
+	using CharArraySet = org.apache.lucene.analysis.util.CharArraySet;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// Test case for ThaiAnalyzer, modified from TestFrenchAnalyzer
+	/// 
+	/// </summary>
+
+	public class TestThaiAnalyzer : BaseTokenStreamTestCase
+	{
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void setUp() throws Exception
+	  public override void setUp()
+	  {
+		base.setUp();
+		assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiTokenizer.DBBI_AVAILABLE);
+	  }
+	  /*
+	   * testcase for offsets
+	   */
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testOffsets() throws Exception
+	  public virtual void testOffsets()
+	  {
+		assertAnalyzesTo(new ThaiAnalyzer(TEST_VERSION_CURRENT, CharArraySet.EMPTY_SET), "การที่ได้ต้องแสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"}, new int[] {0, 3, 6, 9, 13, 17, 20, 23}, new int[] {3, 6, 9, 13, 17, 20, 23, 25});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testStopWords() throws Exception
+	  public virtual void testStopWords()
+	  {
+		assertAnalyzesTo(new ThaiAnalyzer(TEST_VERSION_CURRENT), "การที่ได้ต้องแสดงว่างานดี", new string[] {"แสดง", "งาน", "ดี"}, new int[] {13, 20, 23}, new int[] {17, 23, 25}, new int[] {5, 2, 1});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBackwardsStopWords() throws Exception
+	  public virtual void testBackwardsStopWords()
+	  {
+		 assertAnalyzesTo(new ThaiAnalyzer(Version.LUCENE_35), "การที่ได้ต้องแสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"}, new int[] {0, 3, 6, 9, 13, 17, 20, 23}, new int[] {3, 6, 9, 13, 17, 20, 23, 25});
+	  }
+
+	  /// <summary>
+	  /// Thai numeric tokens were typed as <ALPHANUM> instead of <NUM>. </summary>
+	  /// @deprecated (3.1) testing backwards behavior 
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Deprecated("(3.1) testing backwards behavior") public void testBuggyTokenType30() throws Exception
+	  [Obsolete("(3.1) testing backwards behavior")]
+	  public virtual void testBuggyTokenType30()
+	  {
+		assertAnalyzesTo(new ThaiAnalyzer(Version.LUCENE_30), "การที่ได้ต้องแสดงว่างานดี ๑๒๓", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี", "๑๒๓"}, new string[] {"<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>"});
+	  }
+
+	  /// @deprecated (3.1) testing backwards behavior 
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Deprecated("(3.1) testing backwards behavior") public void testAnalyzer30() throws Exception
+	  [Obsolete("(3.1) testing backwards behavior")]
+	  public virtual void testAnalyzer30()
+	  {
+			ThaiAnalyzer analyzer = new ThaiAnalyzer(Version.LUCENE_30);
+
+		assertAnalyzesTo(analyzer, "", new string[] {});
+
+		assertAnalyzesTo(analyzer, "การที่ได้ต้องแสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
+
+		assertAnalyzesTo(analyzer, "บริษัทชื่อ XY&Z - คุยกับ xyz@demo.com", new string[] {"บริษัท", "ชื่อ", "xy&z", "คุย", "กับ", "xyz@demo.com"});
+
+		// English stop words
+		assertAnalyzesTo(analyzer, "ประโยคว่า The quick brown fox jumped over the lazy dogs", new string[] {"ประโยค", "ว่า", "quick", "brown", "fox", "jumped", "over", "lazy", "dogs"});
+	  }
+
+	  /*
+	   * Test that position increments are adjusted correctly for stopwords.
+	   */
+	  // note this test uses stopfilter's stopset
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testPositionIncrements() throws Exception
+	  public virtual void testPositionIncrements()
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final ThaiAnalyzer analyzer = new ThaiAnalyzer(TEST_VERSION_CURRENT, org.apache.lucene.analysis.core.StopAnalyzer.ENGLISH_STOP_WORDS_SET);
+		ThaiAnalyzer analyzer = new ThaiAnalyzer(TEST_VERSION_CURRENT, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
+		assertAnalyzesTo(analyzer, "การที่ได้ต้อง the แสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"}, new int[] {0, 3, 6, 9, 18, 22, 25, 28}, new int[] {3, 6, 9, 13, 22, 25, 28, 30}, new int[] {1, 1, 1, 1, 2, 1, 1, 1});
+
+		// case that a stopword is adjacent to thai text, with no whitespace
+		assertAnalyzesTo(analyzer, "การที่ได้ต้องthe แสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"}, new int[] {0, 3, 6, 9, 17, 21, 24, 27}, new int[] {3, 6, 9, 13, 21, 24, 27, 29}, new int[] {1, 1, 1, 1, 2, 1, 1, 1});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testReusableTokenStream() throws Exception
+	  public virtual void testReusableTokenStream()
+	  {
+		ThaiAnalyzer analyzer = new ThaiAnalyzer(TEST_VERSION_CURRENT, CharArraySet.EMPTY_SET);
+		assertAnalyzesTo(analyzer, "", new string[] {});
+
+		  assertAnalyzesTo(analyzer, "การที่ได้ต้องแสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
+
+		  assertAnalyzesTo(analyzer, "บริษัทชื่อ XY&Z - คุยกับ xyz@demo.com", new string[] {"บริษัท", "ชื่อ", "xy", "z", "คุย", "กับ", "xyz", "demo.com"});
+	  }
+
+	  /// @deprecated (3.1) for version back compat 
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Deprecated("(3.1) for version back compat") public void testReusableTokenStream30() throws Exception
+	  [Obsolete("(3.1) for version back compat")]
+	  public virtual void testReusableTokenStream30()
+	  {
+		  ThaiAnalyzer analyzer = new ThaiAnalyzer(Version.LUCENE_30);
+		  assertAnalyzesTo(analyzer, "", new string[] {});
+
+		  assertAnalyzesTo(analyzer, "การที่ได้ต้องแสดงว่างานดี", new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
+
+		  assertAnalyzesTo(analyzer, "บริษัทชื่อ XY&Z - คุยกับ xyz@demo.com", new string[] {"บริษัท", "ชื่อ", "xy&z", "คุย", "กับ", "xyz@demo.com"});
+	  }
+
+	  /// <summary>
+	  /// blast some random strings through the analyzer </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testRandomStrings() throws Exception
+	  public virtual void testRandomStrings()
+	  {
+		checkRandomData(random(), new ThaiAnalyzer(TEST_VERSION_CURRENT), 1000 * RANDOM_MULTIPLIER);
+	  }
+
+	  /// <summary>
+	  /// blast some random large strings through the analyzer </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testRandomHugeStrings() throws Exception
+	  public virtual void testRandomHugeStrings()
+	  {
+		Random random = random();
+		checkRandomData(random, new ThaiAnalyzer(TEST_VERSION_CURRENT), 100 * RANDOM_MULTIPLIER, 8192);
+	  }
+
+	  // LUCENE-3044
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testAttributeReuse() throws Exception
+	  public virtual void testAttributeReuse()
+	  {
+		ThaiAnalyzer analyzer = new ThaiAnalyzer(Version.LUCENE_30);
+		// just consume
+		TokenStream ts = analyzer.tokenStream("dummy", "ภาษาไทย");
+		assertTokenStreamContents(ts, new string[] {"ภาษา", "ไทย"});
+		// this consumer adds flagsAtt, which this analyzer does not use. 
+		ts = analyzer.tokenStream("dummy", "ภาษาไทย");
+		ts.addAttribute(typeof(FlagsAttribute));
+		assertTokenStreamContents(ts, new string[] {"ภาษา", "ไทย"});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testTwoSentences() throws Exception
+	  public virtual void testTwoSentences()
+	  {
+		assertAnalyzesTo(new ThaiAnalyzer(TEST_VERSION_CURRENT, CharArraySet.EMPTY_SET), "This is a test. การที่ได้ต้องแสดงว่างานดี", new string[] {"this", "is", "a", "test", "การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"}, new int[] {0, 5, 8, 10, 16, 19, 22, 25, 29, 33, 36, 39}, new int[] {4, 7, 9, 14, 19, 22, 25, 29, 33, 36, 39, 41});
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiTokenizerFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiTokenizerFactory.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiTokenizerFactory.cs
new file mode 100644
index 0000000..2712a4e
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiTokenizerFactory.cs
@@ -0,0 +1,59 @@
+namespace org.apache.lucene.analysis.th
+{
+
+	/*
+	 * 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 BaseTokenStreamFactoryTestCase = org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+
+	/// <summary>
+	/// Simple tests to ensure the Thai word filter factory is working.
+	/// </summary>
+	public class TestThaiTokenizerFactory : BaseTokenStreamFactoryTestCase
+	{
+	  /// <summary>
+	  /// Ensure the filter actually decomposes text.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testWordBreak() throws Exception
+	  public virtual void testWordBreak()
+	  {
+		assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiTokenizer.DBBI_AVAILABLE);
+		Tokenizer tokenizer = tokenizerFactory("Thai").create(new StringReader("การที่ได้ต้องแสดงว่างานดี"));
+		assertTokenStreamContents(tokenizer, new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
+	  }
+
+	  /// <summary>
+	  /// Test that bogus arguments result in exception </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBogusArguments() throws Exception
+	  public virtual void testBogusArguments()
+	  {
+		assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiTokenizer.DBBI_AVAILABLE);
+		try
+		{
+		  tokenizerFactory("Thai", "bogusArg", "bogusValue");
+		  fail();
+		}
+		catch (System.ArgumentException expected)
+		{
+		  assertTrue(expected.Message.contains("Unknown parameters"));
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiWordFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiWordFilterFactory.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiWordFilterFactory.cs
new file mode 100644
index 0000000..4abfc55
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Th/TestThaiWordFilterFactory.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace org.apache.lucene.analysis.th
+{
+
+	/*
+	 * 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 BaseTokenStreamFactoryTestCase = org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+
+	/// <summary>
+	/// Simple tests to ensure the Thai word filter factory is working.
+	/// </summary>
+	[Obsolete]
+	public class TestThaiWordFilterFactory : BaseTokenStreamFactoryTestCase
+	{
+	  /// <summary>
+	  /// Ensure the filter actually decomposes text.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testWordBreak() throws Exception
+	  public virtual void testWordBreak()
+	  {
+		assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiWordFilter.DBBI_AVAILABLE);
+		Reader reader = new StringReader("การที่ได้ต้องแสดงว่างานดี");
+		TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+		stream = tokenFilterFactory("ThaiWord").create(stream);
+		assertTokenStreamContents(stream, new string[] {"การ", "ที่", "ได้", "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
+	  }
+
+	  /// <summary>
+	  /// Test that bogus arguments result in exception </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBogusArguments() throws Exception
+	  public virtual void testBogusArguments()
+	  {
+		assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiWordFilter.DBBI_AVAILABLE);
+		try
+		{
+		  tokenFilterFactory("ThaiWord", "bogusArg", "bogusValue");
+		  fail();
+		}
+		catch (System.ArgumentException expected)
+		{
+		  assertTrue(expected.Message.contains("Unknown parameters"));
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilter.cs
new file mode 100644
index 0000000..02c94a8
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilter.cs
@@ -0,0 +1,37 @@
+namespace org.apache.lucene.analysis.tr
+{
+
+	/*
+	 * 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.
+	 */
+
+
+
+	public class TestApostropheFilter : BaseTokenStreamTestCase
+	{
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testApostropheFilter() throws Exception
+	  public virtual void testApostropheFilter()
+	  {
+		TokenStream stream = new MockTokenizer(new StringReader("Türkiye'de 2003'te Van Gölü'nü gördüm"), MockTokenizer.WHITESPACE, false);
+		stream = new TurkishLowerCaseFilter(stream);
+		stream = new ApostropheFilter(stream);
+		assertTokenStreamContents(stream, new string[]{"türkiye", "2003", "van", "gölü", "gördüm"});
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilterFactory.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilterFactory.cs
new file mode 100644
index 0000000..ebf2117
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestApostropheFilterFactory.cs
@@ -0,0 +1,62 @@
+namespace org.apache.lucene.analysis.tr
+{
+
+	/*
+	 * 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 BaseTokenStreamFactoryTestCase = org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+
+
+	/// <summary>
+	/// Simple tests to ensure the apostrophe filter factory is working.
+	/// </summary>
+	public class TestApostropheFilterFactory : BaseTokenStreamFactoryTestCase
+	{
+	  /// <summary>
+	  /// Ensure the filter actually removes characters after an apostrophe.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testApostrophes() throws Exception
+	  public virtual void testApostrophes()
+	  {
+		Reader reader = new StringReader("Türkiye'de 2003'te Van Gölü'nü gördüm");
+		TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+		stream = tokenFilterFactory("Apostrophe").create(stream);
+		assertTokenStreamContents(stream, new string[]{"Türkiye", "2003", "Van", "Gölü", "gördüm"});
+	  }
+
+	  /// <summary>
+	  /// Test that bogus arguments result in exception
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBogusArguments() throws Exception
+	  public virtual void testBogusArguments()
+	  {
+		try
+		{
+		  tokenFilterFactory("Apostrophe", "bogusArg", "bogusValue");
+		  fail();
+		}
+		catch (System.ArgumentException expected)
+		{
+		  assertTrue(expected.Message.contains("Unknown parameter(s):"));
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishAnalyzer.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishAnalyzer.cs
new file mode 100644
index 0000000..103da78
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishAnalyzer.cs
@@ -0,0 +1,73 @@
+namespace org.apache.lucene.analysis.tr
+{
+
+	/*
+	 * 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 CharArraySet = org.apache.lucene.analysis.util.CharArraySet;
+
+	public class TestTurkishAnalyzer : BaseTokenStreamTestCase
+	{
+	  /// <summary>
+	  /// This test fails with NPE when the 
+	  /// stopwords file is missing in classpath 
+	  /// </summary>
+	  public virtual void testResourcesAvailable()
+	  {
+		new TurkishAnalyzer(TEST_VERSION_CURRENT);
+	  }
+
+	  /// <summary>
+	  /// test stopwords and stemming </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBasics() throws java.io.IOException
+	  public virtual void testBasics()
+	  {
+		Analyzer a = new TurkishAnalyzer(TEST_VERSION_CURRENT);
+		// stemming
+		checkOneTerm(a, "ağacı", "ağaç");
+		checkOneTerm(a, "ağaç", "ağaç");
+		// stopword
+		assertAnalyzesTo(a, "dolayı", new string[] {});
+		// apostrophes
+		checkOneTerm(a, "Kıbrıs'ta", "kıbrıs");
+		assertAnalyzesTo(a, "Van Gölü'ne", new string[]{"van", "göl"});
+	  }
+
+	  /// <summary>
+	  /// test use of exclusion set </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testExclude() throws java.io.IOException
+	  public virtual void testExclude()
+	  {
+		CharArraySet exclusionSet = new CharArraySet(TEST_VERSION_CURRENT, asSet("ağacı"), false);
+		Analyzer a = new TurkishAnalyzer(TEST_VERSION_CURRENT, TurkishAnalyzer.DefaultStopSet, exclusionSet);
+		checkOneTerm(a, "ağacı", "ağacı");
+		checkOneTerm(a, "ağaç", "ağaç");
+	  }
+
+	  /// <summary>
+	  /// blast some random strings through the analyzer </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testRandomStrings() throws Exception
+	  public virtual void testRandomStrings()
+	  {
+		checkRandomData(random(), new TurkishAnalyzer(TEST_VERSION_CURRENT), 1000 * RANDOM_MULTIPLIER);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilter.cs
new file mode 100644
index 0000000..8d3b5cb
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilter.cs
@@ -0,0 +1,102 @@
+namespace org.apache.lucene.analysis.tr
+{
+
+	/*
+	 * 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 KeywordTokenizer = org.apache.lucene.analysis.core.KeywordTokenizer;
+
+	/// <summary>
+	/// Test the Turkish lowercase filter.
+	/// </summary>
+	public class TestTurkishLowerCaseFilter : BaseTokenStreamTestCase
+	{
+
+	  /// <summary>
+	  /// Test composed forms
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testTurkishLowerCaseFilter() throws Exception
+	  public virtual void testTurkishLowerCaseFilter()
+	  {
+		TokenStream stream = new MockTokenizer(new StringReader("\u0130STANBUL \u0130ZM\u0130R ISPARTA"), MockTokenizer.WHITESPACE, false);
+		TurkishLowerCaseFilter filter = new TurkishLowerCaseFilter(stream);
+		assertTokenStreamContents(filter, new string[] {"istanbul", "izmir", "\u0131sparta"});
+	  }
+
+	  /// <summary>
+	  /// Test decomposed forms
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testDecomposed() throws Exception
+	  public virtual void testDecomposed()
+	  {
+		TokenStream stream = new MockTokenizer(new StringReader("\u0049\u0307STANBUL \u0049\u0307ZM\u0049\u0307R ISPARTA"), MockTokenizer.WHITESPACE, false);
+		TurkishLowerCaseFilter filter = new TurkishLowerCaseFilter(stream);
+		assertTokenStreamContents(filter, new string[] {"istanbul", "izmir", "\u0131sparta"});
+	  }
+
+	  /// <summary>
+	  /// Test decomposed forms with additional accents
+	  /// In this example, U+0049 + U+0316 + U+0307 is canonically equivalent
+	  /// to U+0130 + U+0316, and is lowercased the same way.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testDecomposed2() throws Exception
+	  public virtual void testDecomposed2()
+	  {
+		TokenStream stream = new MockTokenizer(new StringReader("\u0049\u0316\u0307STANBUL \u0049\u0307ZM\u0049\u0307R I\u0316SPARTA"), MockTokenizer.WHITESPACE, false);
+		TurkishLowerCaseFilter filter = new TurkishLowerCaseFilter(stream);
+		assertTokenStreamContents(filter, new string[] {"i\u0316stanbul", "izmir", "\u0131\u0316sparta"});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testDecomposed3() throws Exception
+	  public virtual void testDecomposed3()
+	  {
+		TokenStream stream = new MockTokenizer(new StringReader("\u0049\u0307"), MockTokenizer.WHITESPACE, false);
+		TurkishLowerCaseFilter filter = new TurkishLowerCaseFilter(stream);
+		assertTokenStreamContents(filter, new string[] {"i"});
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testEmptyTerm() throws java.io.IOException
+	  public virtual void testEmptyTerm()
+	  {
+		Analyzer a = new AnalyzerAnonymousInnerClassHelper(this);
+		checkOneTerm(a, "", "");
+	  }
+
+	  private class AnalyzerAnonymousInnerClassHelper : Analyzer
+	  {
+		  private readonly TestTurkishLowerCaseFilter outerInstance;
+
+		  public AnalyzerAnonymousInnerClassHelper(TestTurkishLowerCaseFilter outerInstance)
+		  {
+			  this.outerInstance = outerInstance;
+		  }
+
+		  protected internal override TokenStreamComponents createComponents(string fieldName, Reader reader)
+		  {
+			Tokenizer tokenizer = new KeywordTokenizer(reader);
+			return new TokenStreamComponents(tokenizer, new TurkishLowerCaseFilter(tokenizer));
+		  }
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilterFactory.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilterFactory.cs
new file mode 100644
index 0000000..1aed94d
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Tr/TestTurkishLowerCaseFilterFactory.cs
@@ -0,0 +1,60 @@
+namespace org.apache.lucene.analysis.tr
+{
+
+	/*
+	 * 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 BaseTokenStreamFactoryTestCase = org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+
+	/// <summary>
+	/// Simple tests to ensure the Turkish lowercase filter factory is working.
+	/// </summary>
+	public class TestTurkishLowerCaseFilterFactory : BaseTokenStreamFactoryTestCase
+	{
+	  /// <summary>
+	  /// Ensure the filter actually lowercases text.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testCasing() throws Exception
+	  public virtual void testCasing()
+	  {
+		Reader reader = new StringReader("AĞACI");
+		TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+		stream = tokenFilterFactory("TurkishLowerCase").create(stream);
+		assertTokenStreamContents(stream, new string[] {"ağacı"});
+	  }
+
+	  /// <summary>
+	  /// Test that bogus arguments result in exception </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public void testBogusArguments() throws Exception
+	  public virtual void testBogusArguments()
+	  {
+		try
+		{
+		  tokenFilterFactory("TurkishLowerCase", "bogusArg", "bogusValue");
+		  fail();
+		}
+		catch (System.ArgumentException expected)
+		{
+		  assertTrue(expected.Message.contains("Unknown parameters"));
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/BaseTokenStreamFactoryTestCase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/BaseTokenStreamFactoryTestCase.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/BaseTokenStreamFactoryTestCase.cs
new file mode 100644
index 0000000..483eef2
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/BaseTokenStreamFactoryTestCase.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.util
+{
+
+	/*
+	 * 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 Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// Base class for testing tokenstream factories. 
+	/// <para>
+	/// Example usage:
+	/// <code><pre>
+	///   Reader reader = new StringReader("Some Text to Analyze");
+	///   reader = charFilterFactory("htmlstrip").create(reader);
+	///   TokenStream stream = tokenizerFactory("standard").create(reader);
+	///   stream = tokenFilterFactory("lowercase").create(stream);
+	///   stream = tokenFilterFactory("asciifolding").create(stream);
+	///   assertTokenStreamContents(stream, new String[] { "some", "text", "to", "analyze" });
+	/// </pre></code>
+	/// </para>
+	/// </summary>
+	// TODO: this has to be here, since the abstract factories are not in lucene-core,
+	// so test-framework doesnt know about them...
+	// this also means we currently cannot use this in other analysis modules :(
+	// TODO: maybe after we improve the abstract factory/SPI apis, they can sit in core and resolve this.
+	public abstract class BaseTokenStreamFactoryTestCase : BaseTokenStreamTestCase
+	{
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private AbstractAnalysisFactory analysisFactory(Class<? extends AbstractAnalysisFactory> clazz, org.apache.lucene.util.Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception
+	  private AbstractAnalysisFactory analysisFactory<T1>(Type<T1> clazz, Version matchVersion, ResourceLoader loader, params string[] keysAndValues) where T1 : AbstractAnalysisFactory
+	  {
+		if (keysAndValues.Length % 2 == 1)
+		{
+		  throw new System.ArgumentException("invalid keysAndValues map");
+		}
+		IDictionary<string, string> args = new Dictionary<string, string>();
+		for (int i = 0; i < keysAndValues.Length; i += 2)
+		{
+		  string previous = args[keysAndValues[i]] = keysAndValues[i + 1];
+		  assertNull("duplicate values for key: " + keysAndValues[i], previous);
+		}
+		if (matchVersion != null)
+		{
+		  string previous = args["luceneMatchVersion"] = matchVersion.ToString();
+		  assertNull("duplicate values for key: luceneMatchVersion", previous);
+		}
+		AbstractAnalysisFactory factory = null;
+		try
+		{
+		  factory = clazz.GetConstructor(typeof(IDictionary)).newInstance(args);
+		}
+		catch (InvocationTargetException e)
+		{
+		  // to simplify tests that check for illegal parameters
+		  if (e.InnerException is System.ArgumentException)
+		  {
+			throw (System.ArgumentException) e.InnerException;
+		  }
+		  else
+		  {
+			throw e;
+		  }
+		}
+		if (factory is ResourceLoaderAware)
+		{
+		  ((ResourceLoaderAware) factory).inform(loader);
+		}
+		return factory;
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenizerFactory with the specified name and key-value arguments.
+	  /// <seealso cref="ClasspathResourceLoader"/> is used for loading resources, so any required ones should
+	  /// be on the test classpath.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenizerFactory tokenizerFactory(String name, String... keysAndValues) throws Exception
+	  protected internal virtual TokenizerFactory tokenizerFactory(string name, params string[] keysAndValues)
+	  {
+		return tokenizerFactory(name, TEST_VERSION_CURRENT, keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenizerFactory with the specified name and key-value arguments.
+	  /// <seealso cref="ClasspathResourceLoader"/> is used for loading resources, so any required ones should
+	  /// be on the test classpath.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenizerFactory tokenizerFactory(String name, org.apache.lucene.util.Version version, String... keysAndValues) throws Exception
+	  protected internal virtual TokenizerFactory tokenizerFactory(string name, Version version, params string[] keysAndValues)
+	  {
+		return tokenizerFactory(name, version, new ClasspathResourceLoader(this.GetType()), keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenizerFactory with the specified name, version, resource loader, 
+	  /// and key-value arguments.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenizerFactory tokenizerFactory(String name, org.apache.lucene.util.Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception
+	  protected internal virtual TokenizerFactory tokenizerFactory(string name, Version matchVersion, ResourceLoader loader, params string[] keysAndValues)
+	  {
+		return (TokenizerFactory) analysisFactory(TokenizerFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenFilterFactory with the specified name and key-value arguments.
+	  /// <seealso cref="ClasspathResourceLoader"/> is used for loading resources, so any required ones should
+	  /// be on the test classpath.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenFilterFactory tokenFilterFactory(String name, org.apache.lucene.util.Version version, String... keysAndValues) throws Exception
+	  protected internal virtual TokenFilterFactory tokenFilterFactory(string name, Version version, params string[] keysAndValues)
+	  {
+		return tokenFilterFactory(name, version, new ClasspathResourceLoader(this.GetType()), keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenFilterFactory with the specified name and key-value arguments.
+	  /// <seealso cref="ClasspathResourceLoader"/> is used for loading resources, so any required ones should
+	  /// be on the test classpath.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenFilterFactory tokenFilterFactory(String name, String... keysAndValues) throws Exception
+	  protected internal virtual TokenFilterFactory tokenFilterFactory(string name, params string[] keysAndValues)
+	  {
+		return tokenFilterFactory(name, TEST_VERSION_CURRENT, keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized TokenFilterFactory with the specified name, version, resource loader, 
+	  /// and key-value arguments.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected TokenFilterFactory tokenFilterFactory(String name, org.apache.lucene.util.Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception
+	  protected internal virtual TokenFilterFactory tokenFilterFactory(string name, Version matchVersion, ResourceLoader loader, params string[] keysAndValues)
+	  {
+		return (TokenFilterFactory) analysisFactory(TokenFilterFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized CharFilterFactory with the specified name and key-value arguments.
+	  /// <seealso cref="ClasspathResourceLoader"/> is used for loading resources, so any required ones should
+	  /// be on the test classpath.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected CharFilterFactory charFilterFactory(String name, String... keysAndValues) throws Exception
+	  protected internal virtual CharFilterFactory charFilterFactory(string name, params string[] keysAndValues)
+	  {
+		return charFilterFactory(name, TEST_VERSION_CURRENT, new ClasspathResourceLoader(this.GetType()), keysAndValues);
+	  }
+
+	  /// <summary>
+	  /// Returns a fully initialized CharFilterFactory with the specified name, version, resource loader, 
+	  /// and key-value arguments.
+	  /// </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: protected CharFilterFactory charFilterFactory(String name, org.apache.lucene.util.Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception
+	  protected internal virtual CharFilterFactory charFilterFactory(string name, Version matchVersion, ResourceLoader loader, params string[] keysAndValues)
+	  {
+		return (CharFilterFactory) analysisFactory(CharFilterFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/StringMockResourceLoader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/StringMockResourceLoader.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/StringMockResourceLoader.cs
new file mode 100644
index 0000000..7373c42
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/StringMockResourceLoader.cs
@@ -0,0 +1,74 @@
+using System;
+
+namespace org.apache.lucene.analysis.util
+{
+
+	/*
+	 * Licensed to the Apache Software Foundation (ASF) under one or more
+	 * contributor license agreements.  See the NOTICE file distributed with
+	 * this work for additional information regarding copyright ownership.
+	 * The ASF licenses this file to You under the Apache License, Version 2.0
+	 * (the "License"); you may not use this file except in compliance with
+	 * the License.  You may obtain a copy of the License at
+	 *
+	 *     http://www.apache.org/licenses/LICENSE-2.0
+	 *
+	 * Unless required by applicable law or agreed to in writing, software
+	 * distributed under the License is distributed on an "AS IS" BASIS,
+	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	 * See the License for the specific language governing permissions and
+	 * limitations under the License.
+	 */
+
+
+	/// <summary>
+	/// Fake resource loader for tests: works if you want to fake reading a single file </summary>
+	public class StringMockResourceLoader : ResourceLoader
+	{
+	  internal string text;
+
+	  public StringMockResourceLoader(string text)
+	  {
+		this.text = text;
+	  }
+
+//JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET:
+//ORIGINAL LINE: @Override public <T> Class<? extends T> findClass(String cname, Class<T> expectedType)
+//JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET:
+//ORIGINAL LINE: @Override public <T> Class<? extends T> findClass(String cname, Class<T> expectedType)
+	  public override Type<?> findClass<T>(string cname, Type<T> expectedType) where ? : T
+	  {
+		try
+		{
+		  return Type.GetType(cname).asSubclass(expectedType);
+		}
+		catch (Exception e)
+		{
+		  throw new Exception("Cannot load class: " + cname, e);
+		}
+	  }
+
+	  public override T newInstance<T>(string cname, Type<T> expectedType)
+	  {
+//JAVA TO C# CONVERTER TODO TASK: Java wildcard generics are not converted to .NET:
+//ORIGINAL LINE: Class<? extends T> clazz = findClass(cname, expectedType);
+		Type<?> clazz = findClass(cname, expectedType);
+		try
+		{
+		  return clazz.newInstance();
+		}
+		catch (Exception e)
+		{
+		  throw new Exception("Cannot create instance: " + cname, e);
+		}
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public java.io.InputStream openResource(String resource) throws java.io.IOException
+	  public override System.IO.Stream openResource(string resource)
+	  {
+		return new ByteArrayInputStream(text.GetBytes(StandardCharsets.UTF_8));
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestAnalysisSPILoader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestAnalysisSPILoader.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestAnalysisSPILoader.cs
new file mode 100644
index 0000000..edfad89
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestAnalysisSPILoader.cs
@@ -0,0 +1,256 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.util
+{
+
+	/*
+	 * 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 HTMLStripCharFilterFactory = org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory;
+	using LowerCaseFilterFactory = org.apache.lucene.analysis.core.LowerCaseFilterFactory;
+	using WhitespaceTokenizerFactory = org.apache.lucene.analysis.core.WhitespaceTokenizerFactory;
+	using RemoveDuplicatesTokenFilterFactory = org.apache.lucene.analysis.miscellaneous.RemoveDuplicatesTokenFilterFactory;
+	using LuceneTestCase = org.apache.lucene.util.LuceneTestCase;
+
+	public class TestAnalysisSPILoader : LuceneTestCase
+	{
+
+	  private IDictionary<string, string> versionArgOnly()
+	  {
+		return new HashMapAnonymousInnerClassHelper(this);
+	  }
+
+	  private class HashMapAnonymousInnerClassHelper : Dictionary<string, string>
+	  {
+		  private readonly TestAnalysisSPILoader outerInstance;
+
+		  public HashMapAnonymousInnerClassHelper(TestAnalysisSPILoader outerInstance)
+		  {
+			  this.outerInstance = outerInstance;
+
+			  this.put("luceneMatchVersion", TEST_VERSION_CURRENT.ToString());
+		  }
+
+	  }
+
+	  public virtual void testLookupTokenizer()
+	  {
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.forName("Whitespace", versionArgOnly()).GetType());
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.forName("WHITESPACE", versionArgOnly()).GetType());
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.forName("whitespace", versionArgOnly()).GetType());
+	  }
+
+	  public virtual void testBogusLookupTokenizer()
+	  {
+		try
+		{
+		  TokenizerFactory.forName("sdfsdfsdfdsfsdfsdf", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  TokenizerFactory.forName("!(**#$U*#$*", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testLookupTokenizerClass()
+	  {
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.lookupClass("Whitespace"));
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.lookupClass("WHITESPACE"));
+		assertSame(typeof(WhitespaceTokenizerFactory), TokenizerFactory.lookupClass("whitespace"));
+	  }
+
+	  public virtual void testBogusLookupTokenizerClass()
+	  {
+		try
+		{
+		  TokenizerFactory.lookupClass("sdfsdfsdfdsfsdfsdf");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  TokenizerFactory.lookupClass("!(**#$U*#$*");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testAvailableTokenizers()
+	  {
+		assertTrue(TokenizerFactory.availableTokenizers().contains("whitespace"));
+	  }
+
+	  public virtual void testLookupTokenFilter()
+	  {
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.forName("Lowercase", versionArgOnly()).GetType());
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.forName("LOWERCASE", versionArgOnly()).GetType());
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.forName("lowercase", versionArgOnly()).GetType());
+
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.forName("RemoveDuplicates", versionArgOnly()).GetType());
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.forName("REMOVEDUPLICATES", versionArgOnly()).GetType());
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.forName("removeduplicates", versionArgOnly()).GetType());
+	  }
+
+	  public virtual void testBogusLookupTokenFilter()
+	  {
+		try
+		{
+		  TokenFilterFactory.forName("sdfsdfsdfdsfsdfsdf", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  TokenFilterFactory.forName("!(**#$U*#$*", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testLookupTokenFilterClass()
+	  {
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.lookupClass("Lowercase"));
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.lookupClass("LOWERCASE"));
+		assertSame(typeof(LowerCaseFilterFactory), TokenFilterFactory.lookupClass("lowercase"));
+
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.lookupClass("RemoveDuplicates"));
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.lookupClass("REMOVEDUPLICATES"));
+		assertSame(typeof(RemoveDuplicatesTokenFilterFactory), TokenFilterFactory.lookupClass("removeduplicates"));
+	  }
+
+	  public virtual void testBogusLookupTokenFilterClass()
+	  {
+		try
+		{
+		  TokenFilterFactory.lookupClass("sdfsdfsdfdsfsdfsdf");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  TokenFilterFactory.lookupClass("!(**#$U*#$*");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testAvailableTokenFilters()
+	  {
+		assertTrue(TokenFilterFactory.availableTokenFilters().contains("lowercase"));
+		assertTrue(TokenFilterFactory.availableTokenFilters().contains("removeduplicates"));
+	  }
+
+	  public virtual void testLookupCharFilter()
+	  {
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.forName("HTMLStrip", versionArgOnly()).GetType());
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.forName("HTMLSTRIP", versionArgOnly()).GetType());
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.forName("htmlstrip", versionArgOnly()).GetType());
+	  }
+
+	  public virtual void testBogusLookupCharFilter()
+	  {
+		try
+		{
+		  CharFilterFactory.forName("sdfsdfsdfdsfsdfsdf", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  CharFilterFactory.forName("!(**#$U*#$*", new Dictionary<string, string>());
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testLookupCharFilterClass()
+	  {
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.lookupClass("HTMLStrip"));
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.lookupClass("HTMLSTRIP"));
+		assertSame(typeof(HTMLStripCharFilterFactory), CharFilterFactory.lookupClass("htmlstrip"));
+	  }
+
+	  public virtual void testBogusLookupCharFilterClass()
+	  {
+		try
+		{
+		  CharFilterFactory.lookupClass("sdfsdfsdfdsfsdfsdf");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+
+		try
+		{
+		  CharFilterFactory.lookupClass("!(**#$U*#$*");
+		  fail();
+		}
+		catch (System.ArgumentException)
+		{
+		  //
+		}
+	  }
+
+	  public virtual void testAvailableCharFilters()
+	  {
+		assertTrue(CharFilterFactory.availableCharFilters().contains("htmlstrip"));
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayIterator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayIterator.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayIterator.cs
new file mode 100644
index 0000000..e0f13e1
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayIterator.cs
@@ -0,0 +1,181 @@
+using System;
+
+namespace org.apache.lucene.analysis.util
+{
+
+	/*
+	 * 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 LuceneTestCase = org.apache.lucene.util.LuceneTestCase;
+	using TestUtil = org.apache.lucene.util.TestUtil;
+
+	public class TestCharArrayIterator : LuceneTestCase
+	{
+
+	  public virtual void testWordInstance()
+	  {
+		doTests(CharArrayIterator.newWordInstance());
+	  }
+
+	  public virtual void testConsumeWordInstance()
+	  {
+		// we use the default locale, as its randomized by LuceneTestCase
+		BreakIterator bi = BreakIterator.getWordInstance(Locale.Default);
+		CharArrayIterator ci = CharArrayIterator.newWordInstance();
+		for (int i = 0; i < 10000; i++)
+		{
+		  char[] text = TestUtil.randomUnicodeString(random()).toCharArray();
+		  ci.setText(text, 0, text.Length);
+		  consume(bi, ci);
+		}
+	  }
+
+	  /* run this to test if your JRE is buggy
+	  public void testWordInstanceJREBUG() {
+	    // we use the default locale, as its randomized by LuceneTestCase
+	    BreakIterator bi = BreakIterator.getWordInstance(Locale.getDefault());
+	    Segment ci = new Segment();
+	    for (int i = 0; i < 10000; i++) {
+	      char text[] = TestUtil.randomUnicodeString(random).toCharArray();
+	      ci.array = text;
+	      ci.offset = 0;
+	      ci.count = text.length;
+	      consume(bi, ci);
+	    }
+	  }
+	  */
+
+	  public virtual void testSentenceInstance()
+	  {
+		doTests(CharArrayIterator.newSentenceInstance());
+	  }
+
+	  public virtual void testConsumeSentenceInstance()
+	  {
+		// we use the default locale, as its randomized by LuceneTestCase
+		BreakIterator bi = BreakIterator.getSentenceInstance(Locale.Default);
+		CharArrayIterator ci = CharArrayIterator.newSentenceInstance();
+		for (int i = 0; i < 10000; i++)
+		{
+		  char[] text = TestUtil.randomUnicodeString(random()).toCharArray();
+		  ci.setText(text, 0, text.Length);
+		  consume(bi, ci);
+		}
+	  }
+
+	  /* run this to test if your JRE is buggy
+	  public void testSentenceInstanceJREBUG() {
+	    // we use the default locale, as its randomized by LuceneTestCase
+	    BreakIterator bi = BreakIterator.getSentenceInstance(Locale.getDefault());
+	    Segment ci = new Segment();
+	    for (int i = 0; i < 10000; i++) {
+	      char text[] = TestUtil.randomUnicodeString(random).toCharArray();
+	      ci.array = text;
+	      ci.offset = 0;
+	      ci.count = text.length;
+	      consume(bi, ci);
+	    }
+	  }
+	  */
+
+	  private void doTests(CharArrayIterator ci)
+	  {
+		// basics
+		ci.setText("testing".ToCharArray(), 0, "testing".Length);
+		assertEquals(0, ci.BeginIndex);
+		assertEquals(7, ci.EndIndex);
+		assertEquals(0, ci.Index);
+		assertEquals('t', ci.current());
+		assertEquals('e', ci.next());
+		assertEquals('g', ci.last());
+		assertEquals('n', ci.previous());
+		assertEquals('t', ci.first());
+		assertEquals(CharacterIterator.DONE, ci.previous());
+
+		// first()
+		ci.setText("testing".ToCharArray(), 0, "testing".Length);
+		ci.next();
+		// Sets the position to getBeginIndex() and returns the character at that position. 
+		assertEquals('t', ci.first());
+		assertEquals(ci.BeginIndex, ci.Index);
+		// or DONE if the text is empty
+		ci.setText(new char[] {}, 0, 0);
+		assertEquals(CharacterIterator.DONE, ci.first());
+
+		// last()
+		ci.setText("testing".ToCharArray(), 0, "testing".Length);
+		// Sets the position to getEndIndex()-1 (getEndIndex() if the text is empty) 
+		// and returns the character at that position. 
+		assertEquals('g', ci.last());
+		assertEquals(ci.Index, ci.EndIndex - 1);
+		// or DONE if the text is empty
+		ci.setText(new char[] {}, 0, 0);
+		assertEquals(CharacterIterator.DONE, ci.last());
+		assertEquals(ci.EndIndex, ci.Index);
+
+		// current()
+		// Gets the character at the current position (as returned by getIndex()). 
+		ci.setText("testing".ToCharArray(), 0, "testing".Length);
+		assertEquals('t', ci.current());
+		ci.last();
+		ci.next();
+		// or DONE if the current position is off the end of the text.
+		assertEquals(CharacterIterator.DONE, ci.current());
+
+		// next()
+		ci.setText("te".ToCharArray(), 0, 2);
+		// Increments the iterator's index by one and returns the character at the new index.
+		assertEquals('e', ci.next());
+		assertEquals(1, ci.Index);
+		// or DONE if the new position is off the end of the text range.
+		assertEquals(CharacterIterator.DONE, ci.next());
+		assertEquals(ci.EndIndex, ci.Index);
+
+		// setIndex()
+		ci.setText("test".ToCharArray(), 0, "test".Length);
+		try
+		{
+		  ci.Index = 5;
+		  fail();
+		}
+		catch (Exception e)
+		{
+		  assertTrue(e is System.ArgumentException);
+		}
+
+		// clone()
+		char[] text = "testing".ToCharArray();
+		ci.setText(text, 0, text.Length);
+		ci.next();
+		CharArrayIterator ci2 = ci.clone();
+		assertEquals(ci.Index, ci2.Index);
+		assertEquals(ci.next(), ci2.next());
+		assertEquals(ci.last(), ci2.last());
+	  }
+
+	  private void consume(BreakIterator bi, CharacterIterator ci)
+	  {
+		bi.Text = ci;
+		while (bi.next() != BreakIterator.DONE)
+		{
+		  ;
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c64856a7/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
new file mode 100644
index 0000000..9202318
--- /dev/null
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Util/TestCharArrayMap.cs
@@ -0,0 +1,288 @@
+using System.Collections.Generic;
+using System.Text;
+
+/*
+ * 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.
+ */
+
+namespace org.apache.lucene.analysis.util
+{
+
+	using LuceneTestCase = org.apache.lucene.util.LuceneTestCase;
+
+	public class TestCharArrayMap : LuceneTestCase
+	{
+	  public virtual void doRandom(int iter, bool ignoreCase)
+	  {
+		CharArrayMap<int?> map = new CharArrayMap<int?>(TEST_VERSION_CURRENT, 1, ignoreCase);
+		Dictionary<string, int?> hmap = new Dictionary<string, int?>();
+
+		char[] key;
+		for (int i = 0; i < iter; i++)
+		{
+		  int len = random().Next(5);
+		  key = new char[len];
+		  for (int j = 0; j < key.Length; j++)
+		  {
+			key[j] = (char)random().Next(127);
+		  }
+		  string keyStr = new string(key);
+		  string hmapKey = ignoreCase ? keyStr.ToLower(Locale.ROOT) : keyStr;
+
+		  int val = random().Next();
+
+		  object o1 = map.put(key, val);
+		  object o2 = hmap[hmapKey].Value = val;
+		  assertEquals(o1,o2);
+
+		  // add it again with the string method
+		  assertEquals(val, map.put(keyStr,val).intValue());
+
+		  assertEquals(val, map.get(key,0,key.Length).intValue());
+		  assertEquals(val, map.get(key).intValue());
+		  assertEquals(val, map.get(keyStr).intValue());
+
+		  assertEquals(hmap.Count, map.size());
+		}
+	  }
+
+	  public virtual void testCharArrayMap()
+	  {
+		int num = 5 * RANDOM_MULTIPLIER;
+		for (int i = 0; i < num; i++)
+		{ // pump this up for more random testing
+		  doRandom(1000,false);
+		  doRandom(1000,true);
+		}
+	  }
+
+	  public virtual void testMethods()
+	  {
+		CharArrayMap<int?> cm = new CharArrayMap<int?>(TEST_VERSION_CURRENT, 2, false);
+		Dictionary<string, int?> hm = new Dictionary<string, int?>();
+		hm["foo"] = 1;
+		hm["bar"] = 2;
+		cm.putAll(hm);
+		assertEquals(hm.Count, cm.size());
+		hm["baz"] = 3;
+		cm.putAll(hm);
+		assertEquals(hm.Count, cm.size());
+
+		CharArraySet cs = cm.Keys;
+		int n = 0;
+		foreach (object o in cs)
+		{
+		  assertTrue(cm.containsKey(o));
+		  char[] co = (char[]) o;
+		  assertTrue(cm.containsKey(co, 0, co.Length));
+		  n++;
+		}
+		assertEquals(hm.Count, n);
+		assertEquals(hm.Count, cs.size());
+		assertEquals(cm.size(), cs.size());
+		cs.clear();
+		assertEquals(0, cs.size());
+		assertEquals(0, cm.size());
+		try
+		{
+		  cs.add("test");
+		  fail("keySet() allows adding new keys");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // pass
+		}
+		cm.putAll(hm);
+		assertEquals(hm.Count, cs.size());
+		assertEquals(cm.size(), cs.size());
+
+		IEnumerator<KeyValuePair<object, int?>> iter1 = cm.entrySet().GetEnumerator();
+		n = 0;
+		while (iter1.MoveNext())
+		{
+		  KeyValuePair<object, int?> entry = iter1.Current;
+		  object key = entry.Key;
+		  int? val = entry.Value;
+		  assertEquals(cm.get(key), val);
+		  entry.Value = val * 100;
+		  assertEquals(val * 100, (int)cm.get(key));
+		  n++;
+		}
+		assertEquals(hm.Count, n);
+		cm.clear();
+		cm.putAll(hm);
+		assertEquals(cm.size(), n);
+
+		CharArrayMap<int?>.EntryIterator iter2 = cm.entrySet().GetEnumerator();
+		n = 0;
+		while (iter2.hasNext())
+		{
+		  char[] keyc = iter2.nextKey();
+		  int? val = iter2.currentValue();
+		  assertEquals(hm[new string(keyc)], val);
+		  iter2.Value = val * 100;
+		  assertEquals(val * 100, (int)cm.get(keyc));
+		  n++;
+		}
+		assertEquals(hm.Count, n);
+
+		cm.entrySet().clear();
+		assertEquals(0, cm.size());
+		assertEquals(0, cm.entrySet().size());
+		assertTrue(cm.Empty);
+	  }
+
+	  public virtual void testModifyOnUnmodifiable()
+	  {
+		CharArrayMap<int?> map = new CharArrayMap<int?>(TEST_VERSION_CURRENT, 2, false);
+		map.put("foo",1);
+		map.put("bar",2);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int size = map.size();
+		int size = map.size();
+		assertEquals(2, size);
+		assertTrue(map.containsKey("foo"));
+		assertEquals(1, map.get("foo").intValue());
+		assertTrue(map.containsKey("bar"));
+		assertEquals(2, map.get("bar").intValue());
+
+		map = CharArrayMap.unmodifiableMap(map);
+		assertEquals("Map size changed due to unmodifiableMap call", size, map.size());
+		string NOT_IN_MAP = "SirGallahad";
+		assertFalse("Test String already exists in map", map.containsKey(NOT_IN_MAP));
+		assertNull("Test String already exists in map", map.get(NOT_IN_MAP));
+
+		try
+		{
+		  map.put(NOT_IN_MAP.ToCharArray(), 3);
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertFalse("Test String has been added to unmodifiable map", map.containsKey(NOT_IN_MAP));
+		  assertNull("Test String has been added to unmodifiable map", map.get(NOT_IN_MAP));
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.put(NOT_IN_MAP, 3);
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertFalse("Test String has been added to unmodifiable map", map.containsKey(NOT_IN_MAP));
+		  assertNull("Test String has been added to unmodifiable map", map.get(NOT_IN_MAP));
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.put(new StringBuilder(NOT_IN_MAP), 3);
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertFalse("Test String has been added to unmodifiable map", map.containsKey(NOT_IN_MAP));
+		  assertNull("Test String has been added to unmodifiable map", map.get(NOT_IN_MAP));
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.clear();
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.entrySet().clear();
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.Keys.Clear();
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.put((object) NOT_IN_MAP, 3);
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertFalse("Test String has been added to unmodifiable map", map.containsKey(NOT_IN_MAP));
+		  assertNull("Test String has been added to unmodifiable map", map.get(NOT_IN_MAP));
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		try
+		{
+		  map.putAll(Collections.singletonMap(NOT_IN_MAP, 3));
+		  fail("Modified unmodifiable map");
+		}
+		catch (System.NotSupportedException)
+		{
+		  // expected
+		  assertFalse("Test String has been added to unmodifiable map", map.containsKey(NOT_IN_MAP));
+		  assertNull("Test String has been added to unmodifiable map", map.get(NOT_IN_MAP));
+		  assertEquals("Size of unmodifiable map has changed", size, map.size());
+		}
+
+		assertTrue(map.containsKey("foo"));
+		assertEquals(1, map.get("foo").intValue());
+		assertTrue(map.containsKey("bar"));
+		assertEquals(2, map.get("bar").intValue());
+	  }
+
+	  public virtual void testToString()
+	  {
+		CharArrayMap<int?> cm = new CharArrayMap<int?>(TEST_VERSION_CURRENT, Collections.singletonMap("test",1), false);
+		assertEquals("[test]",cm.Keys.ToString());
+		assertEquals("[1]",cm.values().ToString());
+		assertEquals("[test=1]",cm.entrySet().ToString());
+		assertEquals("{test=1}",cm.ToString());
+		cm.put("test2", 2);
+		assertTrue(cm.Keys.ToString().Contains(", "));
+		assertTrue(cm.values().ToString().Contains(", "));
+		assertTrue(cm.entrySet().ToString().Contains(", "));
+		assertTrue(cm.ToString().Contains(", "));
+	  }
+	}
+
+
+}
\ No newline at end of file