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 2014/11/08 00:12:32 UTC

[28/34] lucenenet git commit: Raw porting of Lucene.Net.Analysis.Common

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilter.cs
new file mode 100644
index 0000000..6073eca
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilter.cs
@@ -0,0 +1,135 @@
+namespace org.apache.lucene.analysis.el
+{
+
+	/// <summary>
+	/// Copyright 2005 The Apache Software Foundation
+	/// 
+	/// Licensed 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>
+
+	using CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+	using CharacterUtils = org.apache.lucene.analysis.util.CharacterUtils;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// Normalizes token text to lower case, removes some Greek diacritics,
+	/// and standardizes final sigma to sigma. 
+	/// <a name="version"/>
+	/// <para>You must specify the required <seealso cref="Version"/>
+	/// compatibility when creating GreekLowerCaseFilter:
+	/// <ul>
+	///   <li> As of 3.1, supplementary characters are properly lowercased.
+	/// </ul>
+	/// </para>
+	/// </summary>
+	public sealed class GreekLowerCaseFilter : TokenFilter
+	{
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly CharacterUtils charUtils;
+
+	  /// <summary>
+	  /// Create a GreekLowerCaseFilter that normalizes Greek token text.
+	  /// </summary>
+	  /// <param name="matchVersion"> Lucene compatibility version, 
+	  ///   See <a href="#version">above</a> </param>
+	  /// <param name="in"> TokenStream to filter </param>
+	  public GreekLowerCaseFilter(Version matchVersion, TokenStream @in) : base(@in)
+	  {
+		this.charUtils = CharacterUtils.getInstance(matchVersion);
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public boolean incrementToken() throws java.io.IOException
+	  public override bool incrementToken()
+	  {
+		if (input.incrementToken())
+		{
+		  char[] chArray = termAtt.buffer();
+		  int chLen = termAtt.length();
+		  for (int i = 0; i < chLen;)
+		  {
+			i += char.toChars(lowerCase(charUtils.codePointAt(chArray, i, chLen)), chArray, i);
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+
+	  private int lowerCase(int codepoint)
+	  {
+		switch (codepoint)
+		{
+		  /* There are two lowercase forms of sigma:
+		   *   U+03C2: small final sigma (end of word)
+		   *   U+03C3: small sigma (otherwise)
+		   *   
+		   * Standardize both to U+03C3
+		   */
+		  case '\u03C2': // small final sigma
+			return '\u03C3'; // small sigma
+
+		  /* Some greek characters contain diacritics.
+		   * This filter removes these, converting to the lowercase base form.
+		   */
+
+		  case '\u0386': // capital alpha with tonos
+		  case '\u03AC': // small alpha with tonos
+			return '\u03B1'; // small alpha
+
+		  case '\u0388': // capital epsilon with tonos
+		  case '\u03AD': // small epsilon with tonos
+			return '\u03B5'; // small epsilon
+
+		  case '\u0389': // capital eta with tonos
+		  case '\u03AE': // small eta with tonos
+			return '\u03B7'; // small eta
+
+		  case '\u038A': // capital iota with tonos
+		  case '\u03AA': // capital iota with dialytika
+		  case '\u03AF': // small iota with tonos
+		  case '\u03CA': // small iota with dialytika
+		  case '\u0390': // small iota with dialytika and tonos
+			return '\u03B9'; // small iota
+
+		  case '\u038E': // capital upsilon with tonos
+		  case '\u03AB': // capital upsilon with dialytika
+		  case '\u03CD': // small upsilon with tonos
+		  case '\u03CB': // small upsilon with dialytika
+		  case '\u03B0': // small upsilon with dialytika and tonos
+			return '\u03C5'; // small upsilon
+
+		  case '\u038C': // capital omicron with tonos
+		  case '\u03CC': // small omicron with tonos
+			return '\u03BF'; // small omicron
+
+		  case '\u038F': // capital omega with tonos
+		  case '\u03CE': // small omega with tonos
+			return '\u03C9'; // small omega
+
+		  /* The previous implementation did the conversion below.
+		   * Only implemented for backwards compatibility with old indexes.
+		   */
+
+		  case '\u03A2': // reserved
+			return '\u03C2'; // small final sigma
+
+		  default:
+			return char.ToLower(codepoint);
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilterFactory.cs
new file mode 100644
index 0000000..d6f084d
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekLowerCaseFilterFactory.cs
@@ -0,0 +1,66 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.el
+{
+
+	/*
+	 * 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 AbstractAnalysisFactory = org.apache.lucene.analysis.util.AbstractAnalysisFactory;
+	using MultiTermAwareComponent = org.apache.lucene.analysis.util.MultiTermAwareComponent;
+	using TokenFilterFactory = org.apache.lucene.analysis.util.TokenFilterFactory;
+
+	/// <summary>
+	/// Factory for <seealso cref="GreekLowerCaseFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_glc" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.GreekLowerCaseFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class GreekLowerCaseFilterFactory : TokenFilterFactory, MultiTermAwareComponent
+	{
+
+	  /// <summary>
+	  /// Creates a new GreekLowerCaseFilterFactory </summary>
+	  public GreekLowerCaseFilterFactory(IDictionary<string, string> args) : base(args)
+	  {
+		assureMatchVersion();
+		if (args.Count > 0)
+		{
+		  throw new System.ArgumentException("Unknown parameters: " + args);
+		}
+	  }
+
+	  public override GreekLowerCaseFilter create(TokenStream @in)
+	  {
+		return new GreekLowerCaseFilter(luceneMatchVersion, @in);
+	  }
+
+	  public virtual AbstractAnalysisFactory MultiTermComponent
+	  {
+		  get
+		  {
+			return this;
+		  }
+	  }
+	}
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilter.cs
new file mode 100644
index 0000000..90912da
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilter.cs
@@ -0,0 +1,72 @@
+namespace org.apache.lucene.analysis.el
+{
+
+	/*
+	 * 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 SetKeywordMarkerFilter = org.apache.lucene.analysis.miscellaneous.SetKeywordMarkerFilter; // for javadoc
+	using KeywordAttribute = org.apache.lucene.analysis.tokenattributes.KeywordAttribute;
+	using CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+
+	/// <summary>
+	/// A <seealso cref="TokenFilter"/> that applies <seealso cref="GreekStemmer"/> to stem Greek
+	/// words.
+	/// <para>
+	/// To prevent terms from being stemmed use an instance of
+	/// <seealso cref="SetKeywordMarkerFilter"/> or a custom <seealso cref="TokenFilter"/> that sets
+	/// the <seealso cref="KeywordAttribute"/> before this <seealso cref="TokenStream"/>.
+	/// </para>
+	/// <para>
+	/// NOTE: Input is expected to be casefolded for Greek (including folding of final
+	/// sigma to sigma), and with diacritics removed. This can be achieved by using 
+	/// either <seealso cref="GreekLowerCaseFilter"/> or ICUFoldingFilter before GreekStemFilter.
+	/// @lucene.experimental
+	/// </para>
+	/// </summary>
+	public sealed class GreekStemFilter : TokenFilter
+	{
+	  private readonly GreekStemmer stemmer = new GreekStemmer();
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAttr = addAttribute(typeof(KeywordAttribute));
+
+	  public GreekStemFilter(TokenStream input) : base(input)
+	  {
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public boolean incrementToken() throws java.io.IOException
+	  public override bool incrementToken()
+	  {
+		if (input.incrementToken())
+		{
+		  if (!keywordAttr.Keyword)
+		  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int newlen = stemmer.stem(termAtt.buffer(), termAtt.length());
+			int newlen = stemmer.stem(termAtt.buffer(), termAtt.length());
+			termAtt.Length = newlen;
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilterFactory.cs
new file mode 100644
index 0000000..95229f2
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemFilterFactory.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.el
+{
+
+	/*
+	 * 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 TokenFilterFactory = org.apache.lucene.analysis.util.TokenFilterFactory;
+
+	/// <summary>
+	/// Factory for <seealso cref="GreekStemFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_gstem" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.GreekLowerCaseFilterFactory"/&gt;
+	///     &lt;filter class="solr.GreekStemFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class GreekStemFilterFactory : TokenFilterFactory
+	{
+
+	  /// <summary>
+	  /// Creates a new GreekStemFilterFactory </summary>
+	  public GreekStemFilterFactory(IDictionary<string, string> args) : base(args)
+	  {
+		if (args.Count > 0)
+		{
+		  throw new System.ArgumentException("Unknown parameters: " + args);
+		}
+	  }
+
+	  public override TokenStream create(TokenStream input)
+	  {
+		return new GreekStemFilter(input);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemmer.cs
new file mode 100644
index 0000000..e9d98c5
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/El/GreekStemmer.cs
@@ -0,0 +1,799 @@
+namespace org.apache.lucene.analysis.el
+{
+
+	using CharArraySet = org.apache.lucene.analysis.util.CharArraySet;
+	using Version = org.apache.lucene.util.Version;
+
+	/*
+	 * 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>
+	/// A stemmer for Greek words, according to: <i>Development of a Stemmer for the
+	/// Greek Language.</i> Georgios Ntais
+	/// <para>
+	/// NOTE: Input is expected to be casefolded for Greek (including folding of final
+	/// sigma to sigma), and with diacritics removed. This can be achieved with 
+	/// either <seealso cref="GreekLowerCaseFilter"/> or ICUFoldingFilter.
+	/// @lucene.experimental
+	/// </para>
+	/// </summary>
+	public class GreekStemmer
+	{
+
+	 /// <summary>
+	 /// Stems a word contained in a leading portion of a char[] array.
+	 /// The word is passed through a number of rules that modify it's length.
+	 /// </summary>
+	 /// <param name="s"> A char[] array that contains the word to be stemmed. </param>
+	 /// <param name="len"> The length of the char[] array. </param>
+	 /// <returns> The new length of the stemmed word. </returns>
+	  public virtual int stem(char[] s, int len)
+	  {
+		if (len < 4) // too short
+		{
+		  return len;
+		}
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int origLen = len;
+		int origLen = len;
+		// "short rules": if it hits one of these, it skips the "long list"
+		len = rule0(s, len);
+		len = rule1(s, len);
+		len = rule2(s, len);
+		len = rule3(s, len);
+		len = rule4(s, len);
+		len = rule5(s, len);
+		len = rule6(s, len);
+		len = rule7(s, len);
+		len = rule8(s, len);
+		len = rule9(s, len);
+		len = rule10(s, len);
+		len = rule11(s, len);
+		len = rule12(s, len);
+		len = rule13(s, len);
+		len = rule14(s, len);
+		len = rule15(s, len);
+		len = rule16(s, len);
+		len = rule17(s, len);
+		len = rule18(s, len);
+		len = rule19(s, len);
+		len = rule20(s, len);
+		// "long list"
+		if (len == origLen)
+		{
+		  len = rule21(s, len);
+		}
+
+		return rule22(s, len);
+	  }
+
+	  private int rule0(char[] s, int len)
+	  {
+		if (len > 9 && (endsWith(s, len, "καθεστωτοσ") || endsWith(s, len, "καθεστωτων")))
+		{
+		  return len - 4;
+		}
+
+		if (len > 8 && (endsWith(s, len, "γεγονοτοσ") || endsWith(s, len, "γεγονοτων")))
+		{
+		  return len - 4;
+		}
+
+		if (len > 8 && endsWith(s, len, "καθεστωτα"))
+		{
+		  return len - 3;
+		}
+
+		if (len > 7 && (endsWith(s, len, "τατογιου") || endsWith(s, len, "τατογιων")))
+		{
+		  return len - 4;
+		}
+
+		if (len > 7 && endsWith(s, len, "γεγονοτα"))
+		{
+		  return len - 3;
+		}
+
+		if (len > 7 && endsWith(s, len, "καθεστωσ"))
+		{
+		  return len - 2;
+		}
+
+		if (len > 6 && (endsWith(s, len, "σκαγιου")) || endsWith(s, len, "σκαγιων") || endsWith(s, len, "ολογιου") || endsWith(s, len, "ολογιων") || endsWith(s, len, "κρεατοσ") || endsWith(s, len, "κρεατων") || endsWith(s, len, "περατοσ") || endsWith(s, len, "περατων") || endsWith(s, len, "τερατοσ") || endsWith(s, len, "τερατων"))
+		{
+		  return len - 4;
+		}
+
+		if (len > 6 && endsWith(s, len, "τατογια"))
+		{
+		  return len - 3;
+		}
+
+		if (len > 6 && endsWith(s, len, "γεγονοσ"))
+		{
+		  return len - 2;
+		}
+
+		if (len > 5 && (endsWith(s, len, "φαγιου") || endsWith(s, len, "φαγιων") || endsWith(s, len, "σογιου") || endsWith(s, len, "σογιων")))
+		{
+		  return len - 4;
+		}
+
+		if (len > 5 && (endsWith(s, len, "σκαγια") || endsWith(s, len, "ολογια") || endsWith(s, len, "κρεατα") || endsWith(s, len, "περατα") || endsWith(s, len, "τερατα")))
+		{
+		  return len - 3;
+		}
+
+		if (len > 4 && (endsWith(s, len, "φαγια") || endsWith(s, len, "σογια") || endsWith(s, len, "φωτοσ") || endsWith(s, len, "φωτων")))
+		{
+		  return len - 3;
+		}
+
+		if (len > 4 && (endsWith(s, len, "κρεασ") || endsWith(s, len, "περασ") || endsWith(s, len, "τερασ")))
+		{
+		  return len - 2;
+		}
+
+		if (len > 3 && endsWith(s, len, "φωτα"))
+		{
+		  return len - 2;
+		}
+
+		if (len > 2 && endsWith(s, len, "φωσ"))
+		{
+		  return len - 1;
+		}
+
+		return len;
+	  }
+
+	  private int rule1(char[] s, int len)
+	  {
+		if (len > 4 && (endsWith(s, len, "αδεσ") || endsWith(s, len, "αδων")))
+		{
+		  len -= 4;
+		  if (!(endsWith(s, len, "οκ") || endsWith(s, len, "μαμ") || endsWith(s, len, "μαν") || endsWith(s, len, "μπαμπ") || endsWith(s, len, "πατερ") || endsWith(s, len, "γιαγι") || endsWith(s, len, "νταντ") || endsWith(s, len, "κυρ") || endsWith(s, len, "θει") || endsWith(s, len, "πεθερ")))
+		  {
+			len += 2; // add back -αδ
+		  }
+		}
+		return len;
+	  }
+
+	  private int rule2(char[] s, int len)
+	  {
+		if (len > 4 && (endsWith(s, len, "εδεσ") || endsWith(s, len, "εδων")))
+		{
+		  len -= 4;
+		  if (endsWith(s, len, "οπ") || endsWith(s, len, "ιπ") || endsWith(s, len, "εμπ") || endsWith(s, len, "υπ") || endsWith(s, len, "γηπ") || endsWith(s, len, "δαπ") || endsWith(s, len, "κρασπ") || endsWith(s, len, "μιλ"))
+		  {
+			len += 2; // add back -εδ
+		  }
+		}
+		return len;
+	  }
+
+	  private int rule3(char[] s, int len)
+	  {
+		if (len > 5 && (endsWith(s, len, "ουδεσ") || endsWith(s, len, "ουδων")))
+		{
+		  len -= 5;
+		  if (endsWith(s, len, "αρκ") || endsWith(s, len, "καλιακ") || endsWith(s, len, "πεταλ") || endsWith(s, len, "λιχ") || endsWith(s, len, "πλεξ") || endsWith(s, len, "σκ") || endsWith(s, len, "σ") || endsWith(s, len, "φλ") || endsWith(s, len, "φρ") || endsWith(s, len, "βελ") || endsWith(s, len, "λουλ") || endsWith(s, len, "χν") || endsWith(s, len, "σπ") || endsWith(s, len, "τραγ") || endsWith(s, len, "φε"))
+		  {
+			len += 3; // add back -ουδ
+		  }
+		}
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc4 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("θ", "δ", "ελ", "γαλ", "ν", "π", "ιδ", "παρ"), false);
+
+	  private int rule4(char[] s, int len)
+	  {
+		if (len > 3 && (endsWith(s, len, "εωσ") || endsWith(s, len, "εων")))
+		{
+		  len -= 3;
+		  if (exc4.contains(s, 0, len))
+		  {
+			len++; // add back -ε
+		  }
+		}
+		return len;
+	  }
+
+	  private int rule5(char[] s, int len)
+	  {
+		if (len > 2 && endsWith(s, len, "ια"))
+		{
+		  len -= 2;
+		  if (endsWithVowel(s, len))
+		  {
+			len++; // add back -ι
+		  }
+		}
+		else if (len > 3 && (endsWith(s, len, "ιου") || endsWith(s, len, "ιων")))
+		{
+		  len -= 3;
+		  if (endsWithVowel(s, len))
+		  {
+			len++; // add back -ι
+		  }
+		}
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc6 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αλ", "αδ", "ενδ", "αμαν", "αμμοχαλ", "ηθ", "ανηθ", "αντιδ", "φυσ", "βρωμ", "γερ", "εξωδ", "καλπ", "καλλιν", "καταδ", "μουλ", "μπαν", "μπαγιατ", "μπολ", "μποσ", "νιτ", "ξικ", "συνομηλ", "πετσ", "πιτσ", "πικαντ", "πλιατσ", "ποστελν", "πρωτοδ", "σερτ", "συναδ", "τσαμ", "υποδ", "φιλον", "φυλοδ", "χασ"), false);
+
+	  private int rule6(char[] s, int len)
+	  {
+		bool removed = false;
+		if (len > 3 && (endsWith(s, len, "ικα") || endsWith(s, len, "ικο")))
+		{
+		  len -= 3;
+		  removed = true;
+		}
+		else if (len > 4 && (endsWith(s, len, "ικου") || endsWith(s, len, "ικων")))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+
+		if (removed)
+		{
+		  if (endsWithVowel(s, len) || exc6.contains(s, 0, len))
+		  {
+			len += 2; // add back -ικ
+		  }
+		}
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc7 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αναπ", "αποθ", "αποκ", "αποστ", "βουβ", "ξεθ", "ουλ", "πεθ", "πικρ", "ποτ", "σιχ", "χ"), false);
+
+	  private int rule7(char[] s, int len)
+	  {
+		if (len == 5 && endsWith(s, len, "αγαμε"))
+		{
+		  return len - 1;
+		}
+
+		if (len > 7 && endsWith(s, len, "ηθηκαμε"))
+		{
+		  len -= 7;
+		}
+		else if (len > 6 && endsWith(s, len, "ουσαμε"))
+		{
+		  len -= 6;
+		}
+		else if (len > 5 && (endsWith(s, len, "αγαμε") || endsWith(s, len, "ησαμε") || endsWith(s, len, "ηκαμε")))
+		{
+		  len -= 5;
+		}
+
+		if (len > 3 && endsWith(s, len, "αμε"))
+		{
+		  len -= 3;
+		  if (exc7.contains(s, 0, len))
+		  {
+			len += 2; // add back -αμ
+		  }
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc8a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("τρ", "τσ"), false);
+
+	  private static readonly CharArraySet exc8b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("βετερ", "βουλκ", "βραχμ", "γ", "δραδουμ", "θ", "καλπουζ", "καστελ", "κορμορ", "λαοπλ", "μωαμεθ", "μ", "μουσουλμ", "ν", "ουλ", "π", "πελεκ", "πλ", "πολισ", "πορτολ", "σαρακατσ", "σουλτ", "τσαρλατ", "ορφ", "τσιγγ", "τσοπ", "φωτοστεφ", "χ", "ψυχοπλ", "αγ", "ορφ", "γαλ", "γερ", "δεκ", "διπλ", "αμερικαν", "ουρ", "πιθ", "πουριτ", "σ", "ζωντ", "ικ", "καστ", "κοπ", "λιχ", "λουθηρ", "μαιντ", "μελ", "σιγ", "σπ", "στεγ", "τραγ", "τσαγ", "φ", "ερ", "αδαπ", "αθιγγ", "αμηχ", "ανικ", "ανοργ", "απηγ", "απιθ", "ατσιγγ", "βασ", "βασκ", "βαθυγαλ", "βιομηχ", "βραχυκ", "διατ", "διαφ", "ενοργ", "θυσ", "κα�
 �νοβιομηχ", "καταγαλ", "κλιβ", "κοιλαρφ", "λιβ", "μεγλοβιομηχ", "μικροβιομηχ", "νταβ", "ξηροκλιβ", "ολιγοδαμ", "ολογαλ", "πενταρφ", "περηφ", "περιτρ", "πλατ", "πολυδαπ", "πολυμηχ", "στεφ", "ταβ", "τετ", "υπερηφ", "υποκοπ", "χαμηλοδαπ", "ψηλοταβ"), false);
+
+	  private int rule8(char[] s, int len)
+	  {
+		bool removed = false;
+
+		if (len > 8 && endsWith(s, len, "ιουντανε"))
+		{
+		  len -= 8;
+		  removed = true;
+		}
+		else if (len > 7 && endsWith(s, len, "ιοντανε") || endsWith(s, len, "ουντανε") || endsWith(s, len, "ηθηκανε"))
+		{
+		  len -= 7;
+		  removed = true;
+		}
+		else if (len > 6 && endsWith(s, len, "ιοτανε") || endsWith(s, len, "οντανε") || endsWith(s, len, "ουσανε"))
+		{
+		  len -= 6;
+		  removed = true;
+		}
+		else if (len > 5 && endsWith(s, len, "αγανε") || endsWith(s, len, "ησανε") || endsWith(s, len, "οτανε") || endsWith(s, len, "ηκανε"))
+		{
+		  len -= 5;
+		  removed = true;
+		}
+
+		if (removed && exc8a.contains(s, 0, len))
+		{
+		  // add -αγαν (we removed > 4 chars so its safe)
+		  len += 4;
+		  s[len - 4] = 'α';
+		  s[len - 3] = 'γ';
+		  s[len - 2] = 'α';
+		  s[len - 1] = 'ν';
+		}
+
+		if (len > 3 && endsWith(s, len, "ανε"))
+		{
+		  len -= 3;
+		  if (endsWithVowelNoY(s, len) || exc8b.contains(s, 0, len))
+		  {
+			len += 2; // add back -αν
+		  }
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc9 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αβαρ", "βεν", "εναρ", "αβρ", "αδ", "αθ", "αν", "απλ", "βαρον", "ντρ", "σκ", "κοπ", "μπορ", "νιφ", "παγ", "παρακαλ", "σερπ", "σκελ", "συρφ", "τοκ", "υ", "δ", "εμ", "θαρρ", "θ"), false);
+
+	  private int rule9(char[] s, int len)
+	  {
+		if (len > 5 && endsWith(s, len, "ησετε"))
+		{
+		  len -= 5;
+		}
+
+		if (len > 3 && endsWith(s, len, "ετε"))
+		{
+		  len -= 3;
+		  if (exc9.contains(s, 0, len) || endsWithVowelNoY(s, len) || endsWith(s, len, "οδ") || endsWith(s, len, "αιρ") || endsWith(s, len, "φορ") || endsWith(s, len, "ταθ") || endsWith(s, len, "διαθ") || endsWith(s, len, "σχ") || endsWith(s, len, "ενδ") || endsWith(s, len, "ευρ") || endsWith(s, len, "τιθ") || endsWith(s, len, "υπερθ") || endsWith(s, len, "ραθ") || endsWith(s, len, "ενθ") || endsWith(s, len, "ροθ") || endsWith(s, len, "σθ") || endsWith(s, len, "πυρ") || endsWith(s, len, "αιν") || endsWith(s, len, "συνδ") || endsWith(s, len, "συν") || endsWith(s, len, "συνθ") || endsWith(s, len, "χωρ") || endsWith(s, len, "πον") || endsWith(s, len, "βρ") || endsWith(s, len, "καθ") || endsWith(s, len, "ευθ") || endsWith(s, len, "εκθ") || endsWith(s, len, "νετ") || endsWith(s, len, "ρον") || endsWith(s, len, "αρκ") || endsWith(s, len, "βαρ") || endsWith(s, len, "βολ") || endsWith(s, len, "ωφελ"))
+		  {
+			len += 2; // add back -ετ
+		  }
+		}
+
+		return len;
+	  }
+
+	  private int rule10(char[] s, int len)
+	  {
+		if (len > 5 && (endsWith(s, len, "οντασ") || endsWith(s, len, "ωντασ")))
+		{
+		  len -= 5;
+		  if (len == 3 && endsWith(s, len, "αρχ"))
+		  {
+			len += 3; // add back *ντ
+			s[len - 3] = 'ο';
+		  }
+		  if (endsWith(s, len, "κρε"))
+		  {
+			len += 3; // add back *ντ
+			s[len - 3] = 'ω';
+		  }
+		}
+
+		return len;
+	  }
+
+	  private int rule11(char[] s, int len)
+	  {
+		if (len > 6 && endsWith(s, len, "ομαστε"))
+		{
+		  len -= 6;
+		  if (len == 2 && endsWith(s, len, "ον"))
+		  {
+			len += 5; // add back -ομαστ
+		  }
+		}
+		else if (len > 7 && endsWith(s, len, "ιομαστε"))
+		{
+		  len -= 7;
+		  if (len == 2 && endsWith(s, len, "ον"))
+		  {
+			len += 5;
+			s[len - 5] = 'ο';
+			s[len - 4] = 'μ';
+			s[len - 3] = 'α';
+			s[len - 2] = 'σ';
+			s[len - 1] = 'τ';
+		  }
+		}
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc12a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("π", "απ", "συμπ", "ασυμπ", "ακαταπ", "αμεταμφ"), false);
+
+	  private static readonly CharArraySet exc12b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αλ", "αρ", "εκτελ", "ζ", "μ", "ξ", "παρακαλ", "αρ", "προ", "νισ"), false);
+
+	  private int rule12(char[] s, int len)
+	  {
+		if (len > 5 && endsWith(s, len, "ιεστε"))
+		{
+		  len -= 5;
+		  if (exc12a.contains(s, 0, len))
+		  {
+			len += 4; // add back -ιεστ
+		  }
+		}
+
+		if (len > 4 && endsWith(s, len, "εστε"))
+		{
+		  len -= 4;
+		  if (exc12b.contains(s, 0, len))
+		  {
+			len += 3; // add back -εστ
+		  }
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc13 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("διαθ", "θ", "παρακαταθ", "προσθ", "συνθ"), false);
+
+	  private int rule13(char[] s, int len)
+	  {
+		if (len > 6 && endsWith(s, len, "ηθηκεσ"))
+		{
+		  len -= 6;
+		}
+		else if (len > 5 && (endsWith(s, len, "ηθηκα") || endsWith(s, len, "ηθηκε")))
+		{
+		  len -= 5;
+		}
+
+		bool removed = false;
+
+		if (len > 4 && endsWith(s, len, "ηκεσ"))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+		else if (len > 3 && (endsWith(s, len, "ηκα") || endsWith(s, len, "ηκε")))
+		{
+		  len -= 3;
+		  removed = true;
+		}
+
+		if (removed && (exc13.contains(s, 0, len) || endsWith(s, len, "σκωλ") || endsWith(s, len, "σκουλ") || endsWith(s, len, "ναρθ") || endsWith(s, len, "σφ") || endsWith(s, len, "οθ") || endsWith(s, len, "πιθ")))
+		{
+		  len += 2; // add back the -ηκ
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc14 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("φαρμακ", "χαδ", "αγκ", "αναρρ", "βρομ", "εκλιπ", "λαμπιδ", "λεχ", "μ", "πατ", "ρ", "λ", "μεδ", "μεσαζ", "υποτειν", "αμ", "αιθ", "ανηκ", "δεσποζ", "ενδιαφερ", "δε", "δευτερευ", "καθαρευ", "πλε", "τσα"), false);
+
+	  private int rule14(char[] s, int len)
+	  {
+		bool removed = false;
+
+		if (len > 5 && endsWith(s, len, "ουσεσ"))
+		{
+		  len -= 5;
+		  removed = true;
+		}
+		else if (len > 4 && (endsWith(s, len, "ουσα") || endsWith(s, len, "ουσε")))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+
+		if (removed && (exc14.contains(s, 0, len) || endsWithVowel(s, len) || endsWith(s, len, "ποδαρ") || endsWith(s, len, "βλεπ") || endsWith(s, len, "πανταχ") || endsWith(s, len, "φρυδ") || endsWith(s, len, "μαντιλ") || endsWith(s, len, "μαλλ") || endsWith(s, len, "κυματ") || endsWith(s, len, "λαχ") || endsWith(s, len, "ληγ") || endsWith(s, len, "φαγ") || endsWith(s, len, "ομ") || endsWith(s, len, "πρωτ")))
+		{
+		  len += 3; // add back -ουσ
+		}
+
+	   return len;
+	  }
+
+	  private static readonly CharArraySet exc15a = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("αβαστ", "πολυφ", "αδηφ", "παμφ", "ρ", "ασπ", "αφ", "αμαλ", "αμαλλι", "ανυστ", "απερ", "ασπαρ", "αχαρ", "δερβεν", "δροσοπ", "ξεφ", "νεοπ", "νομοτ", "ολοπ", "ομοτ", "προστ", "προσωποπ", "συμπ", "συντ", "τ", "υποτ", "χαρ", "αειπ", "αιμοστ", "ανυπ", "αποτ", "αρτιπ", "διατ", "εν", "επιτ", "κροκαλοπ", "σιδηροπ", "λ", "ναυ", "ουλαμ", "ουρ", "π", "τρ", "μ"), false);
+
+	  private static readonly CharArraySet exc15b = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ψοφ", "ναυλοχ"), false);
+
+	  private int rule15(char[] s, int len)
+	  {
+		bool removed = false;
+		if (len > 4 && endsWith(s, len, "αγεσ"))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+		else if (len > 3 && (endsWith(s, len, "αγα") || endsWith(s, len, "αγε")))
+		{
+		  len -= 3;
+		  removed = true;
+		}
+
+		if (removed)
+		{
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final boolean cond1 = exc15a.contains(s, 0, len) || endsWith(s, len, "οφ") || endsWith(s, len, "πελ") || endsWith(s, len, "χορτ") || endsWith(s, len, "λλ") || endsWith(s, len, "σφ") || endsWith(s, len, "ρπ") || endsWith(s, len, "φρ") || endsWith(s, len, "πρ") || endsWith(s, len, "λοχ") || endsWith(s, len, "σμην");
+		  bool cond1 = exc15a.contains(s, 0, len) || endsWith(s, len, "οφ") || endsWith(s, len, "πελ") || endsWith(s, len, "χορτ") || endsWith(s, len, "λλ") || endsWith(s, len, "σφ") || endsWith(s, len, "ρπ") || endsWith(s, len, "φρ") || endsWith(s, len, "πρ") || endsWith(s, len, "λοχ") || endsWith(s, len, "σμην");
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final boolean cond2 = exc15b.contains(s, 0, len) || endsWith(s, len, "κολλ");
+		  bool cond2 = exc15b.contains(s, 0, len) || endsWith(s, len, "κολλ");
+
+		  if (cond1 && !cond2)
+		  {
+			len += 2; // add back -αγ
+		  }
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc16 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ν", "χερσον", "δωδεκαν", "ερημον", "μεγαλον", "επταν"), false);
+
+	  private int rule16(char[] s, int len)
+	  {
+		bool removed = false;
+		if (len > 4 && endsWith(s, len, "ησου"))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+		else if (len > 3 && (endsWith(s, len, "ησε") || endsWith(s, len, "ησα")))
+		{
+		  len -= 3;
+		  removed = true;
+		}
+
+		if (removed && exc16.contains(s, 0, len))
+		{
+		  len += 2; // add back -ησ
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc17 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ασβ", "σβ", "αχρ", "χρ", "απλ", "αειμν", "δυσχρ", "ευχρ", "κοινοχρ", "παλιμψ"), false);
+
+	  private int rule17(char[] s, int len)
+	  {
+		if (len > 4 && endsWith(s, len, "ηστε"))
+		{
+		  len -= 4;
+		  if (exc17.contains(s, 0, len))
+		  {
+			len += 3; // add back the -ηστ
+		  }
+		}
+
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc18 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("ν", "ρ", "σπι", "στραβομουτσ", "κακομουτσ", "εξων"), false);
+
+	  private int rule18(char[] s, int len)
+	  {
+		bool removed = false;
+
+		if (len > 6 && (endsWith(s, len, "ησουνε") || endsWith(s, len, "ηθουνε")))
+		{
+		  len -= 6;
+		  removed = true;
+		}
+		else if (len > 4 && endsWith(s, len, "ουνε"))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+
+		if (removed && exc18.contains(s, 0, len))
+		{
+		  len += 3;
+		  s[len - 3] = 'ο';
+		  s[len - 2] = 'υ';
+		  s[len - 1] = 'ν';
+		}
+		return len;
+	  }
+
+	  private static readonly CharArraySet exc19 = new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("παρασουσ", "φ", "χ", "ωριοπλ", "αζ", "αλλοσουσ", "ασουσ"), false);
+
+	  private int rule19(char[] s, int len)
+	  {
+		bool removed = false;
+
+		if (len > 6 && (endsWith(s, len, "ησουμε") || endsWith(s, len, "ηθουμε")))
+		{
+		  len -= 6;
+		  removed = true;
+		}
+		else if (len > 4 && endsWith(s, len, "ουμε"))
+		{
+		  len -= 4;
+		  removed = true;
+		}
+
+		if (removed && exc19.contains(s, 0, len))
+		{
+		  len += 3;
+		  s[len - 3] = 'ο';
+		  s[len - 2] = 'υ';
+		  s[len - 1] = 'μ';
+		}
+		return len;
+	  }
+
+	  private int rule20(char[] s, int len)
+	  {
+		if (len > 5 && (endsWith(s, len, "ματων") || endsWith(s, len, "ματοσ")))
+		{
+		  len -= 3;
+		}
+		else if (len > 4 && endsWith(s, len, "ματα"))
+		{
+		  len -= 2;
+		}
+		return len;
+	  }
+
+	  private int rule21(char[] s, int len)
+	  {
+		if (len > 9 && endsWith(s, len, "ιοντουσαν"))
+		{
+		  return len - 9;
+		}
+
+		if (len > 8 && (endsWith(s, len, "ιομασταν") || endsWith(s, len, "ιοσασταν") || endsWith(s, len, "ιουμαστε") || endsWith(s, len, "οντουσαν")))
+		{
+		  return len - 8;
+		}
+
+		if (len > 7 && (endsWith(s, len, "ιεμαστε") || endsWith(s, len, "ιεσαστε") || endsWith(s, len, "ιομουνα") || endsWith(s, len, "ιοσαστε") || endsWith(s, len, "ιοσουνα") || endsWith(s, len, "ιουνται") || endsWith(s, len, "ιουνταν") || endsWith(s, len, "ηθηκατε") || endsWith(s, len, "ομασταν") || endsWith(s, len, "οσασταν") || endsWith(s, len, "ουμαστε")))
+		{
+		  return len - 7;
+		}
+
+		if (len > 6 && (endsWith(s, len, "ιομουν") || endsWith(s, len, "ιονταν") || endsWith(s, len, "ιοσουν") || endsWith(s, len, "ηθειτε") || endsWith(s, len, "ηθηκαν") || endsWith(s, len, "ομουνα") || endsWith(s, len, "οσαστε") || endsWith(s, len, "οσουνα") || endsWith(s, len, "ουνται") || endsWith(s, len, "ουνταν") || endsWith(s, len, "ουσατε")))
+		{
+		  return len - 6;
+		}
+
+		if (len > 5 && (endsWith(s, len, "αγατε") || endsWith(s, len, "ιεμαι") || endsWith(s, len, "ιεται") || endsWith(s, len, "ιεσαι") || endsWith(s, len, "ιοταν") || endsWith(s, len, "ιουμα") || endsWith(s, len, "ηθεισ") || endsWith(s, len, "ηθουν") || endsWith(s, len, "ηκατε") || endsWith(s, len, "ησατε") || endsWith(s, len, "ησουν") || endsWith(s, len, "ομουν") || endsWith(s, len, "ονται") || endsWith(s, len, "ονταν") || endsWith(s, len, "οσουν") || endsWith(s, len, "ουμαι") || endsWith(s, len, "ουσαν")))
+		{
+		  return len - 5;
+		}
+
+		if (len > 4 && (endsWith(s, len, "αγαν") || endsWith(s, len, "αμαι") || endsWith(s, len, "ασαι") || endsWith(s, len, "αται") || endsWith(s, len, "ειτε") || endsWith(s, len, "εσαι") || endsWith(s, len, "εται") || endsWith(s, len, "ηδεσ") || endsWith(s, len, "ηδων") || endsWith(s, len, "ηθει") || endsWith(s, len, "ηκαν") || endsWith(s, len, "ησαν") || endsWith(s, len, "ησει") || endsWith(s, len, "ησεσ") || endsWith(s, len, "ομαι") || endsWith(s, len, "οταν")))
+		{
+		  return len - 4;
+		}
+
+		if (len > 3 && (endsWith(s, len, "αει") || endsWith(s, len, "εισ") || endsWith(s, len, "ηθω") || endsWith(s, len, "ησω") || endsWith(s, len, "ουν") || endsWith(s, len, "ουσ")))
+		{
+		  return len - 3;
+		}
+
+		if (len > 2 && (endsWith(s, len, "αν") || endsWith(s, len, "ασ") || endsWith(s, len, "αω") || endsWith(s, len, "ει") || endsWith(s, len, "εσ") || endsWith(s, len, "ησ") || endsWith(s, len, "οι") || endsWith(s, len, "οσ") || endsWith(s, len, "ου") || endsWith(s, len, "υσ") || endsWith(s, len, "ων")))
+		{
+		  return len - 2;
+		}
+
+		if (len > 1 && endsWithVowel(s, len))
+		{
+		  return len - 1;
+		}
+
+		return len;
+	  }
+
+	  private int rule22(char[] s, int len)
+	  {
+		if (endsWith(s, len, "εστερ") || endsWith(s, len, "εστατ"))
+		{
+		  return len - 5;
+		}
+
+		if (endsWith(s, len, "οτερ") || endsWith(s, len, "οτατ") || endsWith(s, len, "υτερ") || endsWith(s, len, "υτατ") || endsWith(s, len, "ωτερ") || endsWith(s, len, "ωτατ"))
+		{
+		  return len - 4;
+		}
+
+		return len;
+	  }
+
+	 /// <summary>
+	 /// Checks if the word contained in the leading portion of char[] array , 
+	 /// ends with the suffix given as parameter.
+	 /// </summary>
+	 /// <param name="s"> A char[] array that represents a word. </param>
+	 /// <param name="len"> The length of the char[] array. </param>
+	 /// <param name="suffix"> A <seealso cref="String"/> object to check if the word given ends with these characters. </param>
+	 /// <returns> True if the word ends with the suffix given , false otherwise. </returns>
+	  private bool EndsWith(char[] s, int len, string suffix)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int suffixLen = suffix.length();
+		int suffixLen = suffix.Length;
+		if (suffixLen > len)
+		{
+		  return false;
+		}
+		for (int i = suffixLen - 1; i >= 0; i--)
+		{
+		  if (s[len - (suffixLen - i)] != suffix[i])
+		  {
+			return false;
+		  }
+		}
+
+		return true;
+	  }
+
+	 /// <summary>
+	 /// Checks if the word contained in the leading portion of char[] array , 
+	 /// ends with a Greek vowel.
+	 /// </summary>
+	 /// <param name="s"> A char[] array that represents a word. </param>
+	 /// <param name="len"> The length of the char[] array. </param>
+	 /// <returns> True if the word contained in the leading portion of char[] array , 
+	 /// ends with a vowel , false otherwise. </returns>
+	  private bool endsWithVowel(char[] s, int len)
+	  {
+		if (len == 0)
+		{
+		  return false;
+		}
+		switch (s[len - 1])
+		{
+		  case 'α':
+		  case 'ε':
+		  case 'η':
+		  case 'ι':
+		  case 'ο':
+		  case 'υ':
+		  case 'ω':
+			return true;
+		  default:
+			return false;
+		}
+	  }
+
+	 /// <summary>
+	 /// Checks if the word contained in the leading portion of char[] array , 
+	 /// ends with a Greek vowel.
+	 /// </summary>
+	 /// <param name="s"> A char[] array that represents a word. </param>
+	 /// <param name="len"> The length of the char[] array. </param>
+	 /// <returns> True if the word contained in the leading portion of char[] array , 
+	 /// ends with a vowel , false otherwise. </returns>
+	  private bool endsWithVowelNoY(char[] s, int len)
+	  {
+		if (len == 0)
+		{
+		  return false;
+		}
+		switch (s[len - 1])
+		{
+		  case 'α':
+		  case 'ε':
+		  case 'η':
+		  case 'ι':
+		  case 'ο':
+		  case 'ω':
+			return true;
+		  default:
+			return false;
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishAnalyzer.cs
new file mode 100644
index 0000000..ec3c8bc
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishAnalyzer.cs
@@ -0,0 +1,121 @@
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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 LowerCaseFilter = org.apache.lucene.analysis.core.LowerCaseFilter;
+	using StopFilter = org.apache.lucene.analysis.core.StopFilter;
+	using SetKeywordMarkerFilter = org.apache.lucene.analysis.miscellaneous.SetKeywordMarkerFilter;
+	using StandardAnalyzer = org.apache.lucene.analysis.standard.StandardAnalyzer;
+	using StandardFilter = org.apache.lucene.analysis.standard.StandardFilter;
+	using StandardTokenizer = org.apache.lucene.analysis.standard.StandardTokenizer;
+	using CharArraySet = org.apache.lucene.analysis.util.CharArraySet;
+	using StopwordAnalyzerBase = org.apache.lucene.analysis.util.StopwordAnalyzerBase;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// <seealso cref="Analyzer"/> for English.
+	/// </summary>
+	public sealed class EnglishAnalyzer : StopwordAnalyzerBase
+	{
+	  private readonly CharArraySet stemExclusionSet;
+
+	  /// <summary>
+	  /// Returns an unmodifiable instance of the default stop words set. </summary>
+	  /// <returns> default stop words set. </returns>
+	  public static CharArraySet DefaultStopSet
+	  {
+		  get
+		  {
+			return DefaultSetHolder.DEFAULT_STOP_SET;
+		  }
+	  }
+
+	  /// <summary>
+	  /// Atomically loads the DEFAULT_STOP_SET in a lazy fashion once the outer class 
+	  /// accesses the static final set the first time.;
+	  /// </summary>
+	  private class DefaultSetHolder
+	  {
+		internal static readonly CharArraySet DEFAULT_STOP_SET = StandardAnalyzer.STOP_WORDS_SET;
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the default stop words: <seealso cref="#getDefaultStopSet"/>.
+	  /// </summary>
+	  public EnglishAnalyzer(Version matchVersion) : this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET)
+	  {
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the given stop words.
+	  /// </summary>
+	  /// <param name="matchVersion"> lucene compatibility version </param>
+	  /// <param name="stopwords"> a stopword set </param>
+	  public EnglishAnalyzer(Version matchVersion, CharArraySet stopwords) : this(matchVersion, stopwords, CharArraySet.EMPTY_SET)
+	  {
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the given stop words. If a non-empty stem exclusion set is
+	  /// provided this analyzer will add a <seealso cref="SetKeywordMarkerFilter"/> before
+	  /// stemming.
+	  /// </summary>
+	  /// <param name="matchVersion"> lucene compatibility version </param>
+	  /// <param name="stopwords"> a stopword set </param>
+	  /// <param name="stemExclusionSet"> a set of terms not to be stemmed </param>
+	  public EnglishAnalyzer(Version matchVersion, CharArraySet stopwords, CharArraySet stemExclusionSet) : base(matchVersion, stopwords)
+	  {
+		this.stemExclusionSet = CharArraySet.unmodifiableSet(CharArraySet.copy(matchVersion, stemExclusionSet));
+	  }
+
+	  /// <summary>
+	  /// Creates a
+	  /// <seealso cref="org.apache.lucene.analysis.Analyzer.TokenStreamComponents"/>
+	  /// which tokenizes all the text in the provided <seealso cref="Reader"/>.
+	  /// </summary>
+	  /// <returns> A
+	  ///         <seealso cref="org.apache.lucene.analysis.Analyzer.TokenStreamComponents"/>
+	  ///         built from an <seealso cref="StandardTokenizer"/> filtered with
+	  ///         <seealso cref="StandardFilter"/>, <seealso cref="EnglishPossessiveFilter"/>, 
+	  ///         <seealso cref="LowerCaseFilter"/>, <seealso cref="StopFilter"/>
+	  ///         , <seealso cref="SetKeywordMarkerFilter"/> if a stem exclusion set is
+	  ///         provided and <seealso cref="PorterStemFilter"/>. </returns>
+	  protected internal override TokenStreamComponents createComponents(string fieldName, Reader reader)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final org.apache.lucene.analysis.Tokenizer source = new org.apache.lucene.analysis.standard.StandardTokenizer(matchVersion, reader);
+		Tokenizer source = new StandardTokenizer(matchVersion, reader);
+		TokenStream result = new StandardFilter(matchVersion, source);
+		// prior to this we get the classic behavior, standardfilter does it for us.
+		if (matchVersion.onOrAfter(Version.LUCENE_31))
+		{
+		  result = new EnglishPossessiveFilter(matchVersion, result);
+		}
+		result = new LowerCaseFilter(matchVersion, result);
+		result = new StopFilter(matchVersion, result, stopwords);
+		if (!stemExclusionSet.Empty)
+		{
+		  result = new SetKeywordMarkerFilter(result, stemExclusionSet);
+		}
+		result = new PorterStemFilter(result);
+		return new TokenStreamComponents(source, result);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilter.cs
new file mode 100644
index 0000000..3e99c4c
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilter.cs
@@ -0,0 +1,66 @@
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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 SetKeywordMarkerFilter = org.apache.lucene.analysis.miscellaneous.SetKeywordMarkerFilter;
+	using CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+	using KeywordAttribute = org.apache.lucene.analysis.tokenattributes.KeywordAttribute;
+
+	/// <summary>
+	/// A <seealso cref="TokenFilter"/> that applies <seealso cref="EnglishMinimalStemmer"/> to stem 
+	/// English words.
+	/// <para>
+	/// To prevent terms from being stemmed use an instance of
+	/// <seealso cref="SetKeywordMarkerFilter"/> or a custom <seealso cref="TokenFilter"/> that sets
+	/// the <seealso cref="KeywordAttribute"/> before this <seealso cref="TokenStream"/>.
+	/// </para>
+	/// </summary>
+	public sealed class EnglishMinimalStemFilter : TokenFilter
+	{
+	  private readonly EnglishMinimalStemmer stemmer = new EnglishMinimalStemmer();
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAttr = addAttribute(typeof(KeywordAttribute));
+
+	  public EnglishMinimalStemFilter(TokenStream input) : base(input)
+	  {
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public boolean incrementToken() throws java.io.IOException
+	  public override bool incrementToken()
+	  {
+		if (input.incrementToken())
+		{
+		  if (!keywordAttr.Keyword)
+		  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int newlen = stemmer.stem(termAtt.buffer(), termAtt.length());
+			int newlen = stemmer.stem(termAtt.buffer(), termAtt.length());
+			termAtt.Length = newlen;
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilterFactory.cs
new file mode 100644
index 0000000..96d75e2
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemFilterFactory.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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 TokenFilterFactory = org.apache.lucene.analysis.util.TokenFilterFactory;
+
+	/// <summary>
+	/// Factory for <seealso cref="EnglishMinimalStemFilter"/>.
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_enminstem" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
+	///     &lt;filter class="solr.EnglishMinimalStemFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class EnglishMinimalStemFilterFactory : TokenFilterFactory
+	{
+
+	  /// <summary>
+	  /// Creates a new EnglishMinimalStemFilterFactory </summary>
+	  public EnglishMinimalStemFilterFactory(IDictionary<string, string> args) : base(args)
+	  {
+		if (args.Count > 0)
+		{
+		  throw new System.ArgumentException("Unknown parameters: " + args);
+		}
+	  }
+
+	  public override TokenStream create(TokenStream input)
+	  {
+		return new EnglishMinimalStemFilter(input);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemmer.cs
new file mode 100644
index 0000000..945c795
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishMinimalStemmer.cs
@@ -0,0 +1,61 @@
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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>
+	/// Minimal plural stemmer for English.
+	/// <para>
+	/// This stemmer implements the "S-Stemmer" from
+	/// <i>How Effective Is Suffixing?</i>
+	/// Donna Harman.
+	/// </para>
+	/// </summary>
+	public class EnglishMinimalStemmer
+	{
+//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
+//ORIGINAL LINE: @SuppressWarnings("fallthrough") public int stem(char s[] , int len)
+	  public virtual int stem(char[] s, int len)
+	  {
+		if (len < 3 || s[len - 1] != 's')
+		{
+		  return len;
+		}
+
+		switch (s[len - 2])
+		{
+		  case 'u':
+		  case 's':
+			  return len;
+		  case 'e':
+			if (len > 3 && s[len - 3] == 'i' && s[len - 4] != 'a' && s[len - 4] != 'e')
+			{
+			  s[len - 3] = 'y';
+			  return len - 2;
+			}
+			if (s[len - 3] == 'i' || s[len - 3] == 'a' || s[len - 3] == 'o' || s[len - 3] == 'e')
+			{
+			  return len; // intentional fallthrough
+			}
+		  default:
+			  return len - 1;
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilter.cs
new file mode 100644
index 0000000..aad7bb9
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilter.cs
@@ -0,0 +1,79 @@
+using System;
+
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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 CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// TokenFilter that removes possessives (trailing 's) from words.
+	/// <a name="version"/>
+	/// <para>You must specify the required <seealso cref="Version"/>
+	/// compatibility when creating EnglishPossessiveFilter:
+	/// <ul>
+	///    <li> As of 3.6, U+2019 RIGHT SINGLE QUOTATION MARK and 
+	///         U+FF07 FULLWIDTH APOSTROPHE are also treated as
+	///         quotation marks.
+	/// </ul>
+	/// </para>
+	/// </summary>
+	public sealed class EnglishPossessiveFilter : TokenFilter
+	{
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private Version matchVersion;
+
+	  /// @deprecated Use <seealso cref="#EnglishPossessiveFilter(Version, TokenStream)"/> instead. 
+	  [Obsolete("Use <seealso cref="#EnglishPossessiveFilter(org.apache.lucene.util.Version, org.apache.lucene.analysis.TokenStream)"/> instead.")]
+	  public EnglishPossessiveFilter(TokenStream input) : this(Version.LUCENE_35, input)
+	  {
+	  }
+
+	  public EnglishPossessiveFilter(Version version, TokenStream input) : base(input)
+	  {
+		this.matchVersion = version;
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public boolean incrementToken() throws java.io.IOException
+	  public override bool incrementToken()
+	  {
+		if (!input.incrementToken())
+		{
+		  return false;
+		}
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final char[] buffer = termAtt.buffer();
+		char[] buffer = termAtt.buffer();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int bufferLength = termAtt.length();
+		int bufferLength = termAtt.length();
+
+		if (bufferLength >= 2 && (buffer[bufferLength - 2] == '\'' || (matchVersion.onOrAfter(Version.LUCENE_36) && (buffer[bufferLength - 2] == '\u2019' || buffer[bufferLength - 2] == '\uFF07'))) && (buffer[bufferLength - 1] == 's' || buffer[bufferLength - 1] == 'S'))
+		{
+		  termAtt.Length = bufferLength - 2; // Strip last 2 characters off
+		}
+
+		return true;
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilterFactory.cs
new file mode 100644
index 0000000..632fd53
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/En/EnglishPossessiveFilterFactory.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.en
+{
+
+	/*
+	 * 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 TokenFilterFactory = org.apache.lucene.analysis.util.TokenFilterFactory;
+
+	/// <summary>
+	/// Factory for <seealso cref="EnglishPossessiveFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_enpossessive" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
+	///     &lt;filter class="solr.EnglishPossessiveFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class EnglishPossessiveFilterFactory : TokenFilterFactory
+	{
+
+	  /// <summary>
+	  /// Creates a new EnglishPossessiveFilterFactory </summary>
+	  public EnglishPossessiveFilterFactory(IDictionary<string, string> args) : base(args)
+	  {
+		assureMatchVersion();
+		if (args.Count > 0)
+		{
+		  throw new System.ArgumentException("Unknown parameters: " + args);
+		}
+	  }
+
+	  public override TokenStream create(TokenStream input)
+	  {
+		return new EnglishPossessiveFilter(luceneMatchVersion, input);
+	  }
+	}
+
+}
\ No newline at end of file