lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From synhers...@apache.org
Subject [21/34] lucenenet git commit: Raw porting of Lucene.Net.Analysis.Common
Date Fri, 07 Nov 2014 23:12:25 GMT
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchMinimalStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchMinimalStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchMinimalStemmer.cs
new file mode 100644
index 0000000..2ca0cce
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchMinimalStemmer.cs
@@ -0,0 +1,106 @@
+namespace org.apache.lucene.analysis.fr
+{
+
+	/*
+	 * 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.
+	 */
+
+	/* 
+	 * This algorithm is updated based on code located at:
+	 * http://members.unine.ch/jacques.savoy/clef/
+	 * 
+	 * Full copyright for that code follows:
+	 */
+
+	/*
+	 * Copyright (c) 2005, Jacques Savoy
+	 * All rights reserved.
+	 *
+	 * Redistribution and use in source and binary forms, with or without 
+	 * modification, are permitted provided that the following conditions are met:
+	 *
+	 * Redistributions of source code must retain the above copyright notice, this 
+	 * list of conditions and the following disclaimer. Redistributions in binary 
+	 * form must reproduce the above copyright notice, this list of conditions and
+	 * the following disclaimer in the documentation and/or other materials 
+	 * provided with the distribution. Neither the name of the author nor the names 
+	 * of its contributors may be used to endorse or promote products derived from 
+	 * this software without specific prior written permission.
+	 * 
+	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+	 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+	 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+	 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
+	 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+	 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+	 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+	 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+	 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+	 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+	 * POSSIBILITY OF SUCH DAMAGE.
+	 */
+
+	/// <summary>
+	/// Light Stemmer for French.
+	/// <para>
+	/// This stemmer implements the following algorithm:
+	/// <i>A Stemming procedure and stopword list for general French corpora.</i>
+	/// Jacques Savoy.
+	/// </para>
+	/// </summary>
+	public class FrenchMinimalStemmer
+	{
+	  public virtual int stem(char[] s, int len)
+	  {
+		if (len < 6)
+		{
+		  return len;
+		}
+
+		if (s[len - 1] == 'x')
+		{
+		  if (s[len - 3] == 'a' && s[len - 2] == 'u')
+		  {
+			s[len - 2] = 'l';
+		  }
+		  return len - 1;
+		}
+
+		if (s[len - 1] == 's')
+		{
+			len--;
+		}
+		if (s[len - 1] == 'r')
+		{
+			len--;
+		}
+		if (s[len - 1] == 'e')
+		{
+			len--;
+		}
+		if (s[len - 1] == 'é')
+		{
+			len--;
+		}
+		if (s[len - 1] == s[len - 2])
+		{
+			len--;
+		}
+		return len;
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemFilter.cs
new file mode 100644
index 0000000..8258dfb
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemFilter.cs
@@ -0,0 +1,102 @@
+using System;
+
+namespace org.apache.lucene.analysis.fr
+{
+
+	/*
+	 * 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 KeywordMarkerFilter = org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter; // for javadoc
+	using SnowballFilter = org.apache.lucene.analysis.snowball.SnowballFilter;
+	using KeywordAttribute = org.apache.lucene.analysis.tokenattributes.KeywordAttribute;
+	using CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+
+	/// <summary>
+	/// A <seealso cref="TokenFilter"/> that stems french words. 
+	/// <para>
+	/// The used stemmer can be changed at runtime after the
+	/// filter object is created (as long as it is a <seealso cref="FrenchStemmer"/>).
+	/// </para>
+	/// <para>
+	/// To prevent terms from being stemmed use an instance of
+	/// <seealso cref="KeywordMarkerFilter"/> or a custom <seealso cref="TokenFilter"/> that sets
+	/// the <seealso cref="KeywordAttribute"/> before this <seealso cref="TokenStream"/>.
+	/// </para> </summary>
+	/// <seealso cref= KeywordMarkerFilter </seealso>
+	/// @deprecated (3.1) Use <seealso cref="SnowballFilter"/> with 
+	/// <seealso cref="org.tartarus.snowball.ext.FrenchStemmer"/> instead, which has the
+	/// same functionality. This filter will be removed in Lucene 5.0 
+	[Obsolete("(3.1) Use <seealso cref="SnowballFilter"/> with")]
+	public sealed class FrenchStemFilter : TokenFilter
+	{
+
+	  /// <summary>
+	  /// The actual token in the input stream.
+	  /// </summary>
+	  private FrenchStemmer stemmer = new FrenchStemmer();
+
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAttr = addAttribute(typeof(KeywordAttribute));
+
+	  public FrenchStemFilter(TokenStream @in) : base(@in)
+	  {
+	  }
+
+	  /// <returns>  Returns true for the next token in the stream, or false at EOS </returns>
+//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())
+		{
+		  string term = termAtt.ToString();
+
+		  // Check the exclusion table
+		  if (!keywordAttr.Keyword)
+		  {
+			string s = stemmer.stem(term);
+			// If not stemmed, don't waste the time  adjusting the token.
+			if ((s != null) && !s.Equals(term))
+			{
+			  termAtt.setEmpty().append(s);
+			}
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+	  /// <summary>
+	  /// Set a alternative/custom <seealso cref="FrenchStemmer"/> for this filter.
+	  /// </summary>
+	  public FrenchStemmer Stemmer
+	  {
+		  set
+		  {
+			if (value != null)
+			{
+			  this.stemmer = value;
+			}
+		  }
+	  }
+	}
+
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemmer.cs
new file mode 100644
index 0000000..4657e29
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Fr/FrenchStemmer.cs
@@ -0,0 +1,785 @@
+using System;
+using System.Text;
+
+namespace org.apache.lucene.analysis.fr
+{
+
+	/*
+	 * 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 French words. 
+	/// <para>
+	/// The algorithm is based on the work of
+	/// Dr Martin Porter on his snowball project<br>
+	/// refer to http://snowball.sourceforge.net/french/stemmer.html<br>
+	/// (French stemming algorithm) for details
+	/// </para> </summary>
+	/// @deprecated Use <seealso cref="org.tartarus.snowball.ext.FrenchStemmer"/> instead, 
+	/// which has the same functionality. This filter will be removed in Lucene 4.0 
+	[Obsolete("Use <seealso cref="org.tartarus.snowball.ext.FrenchStemmer"/> instead,")]
+	public class FrenchStemmer
+	{
+	  private static readonly Locale locale = new Locale("fr", "FR");
+
+
+	  /// <summary>
+	  /// Buffer for the terms while stemming them.
+	  /// </summary>
+	  private StringBuilder sb = new StringBuilder();
+
+	  /// <summary>
+	  /// A temporary buffer, used to reconstruct R2
+	  /// </summary>
+	   private StringBuilder tb = new StringBuilder();
+
+	  /// <summary>
+	  /// Region R0 is equal to the whole buffer
+	  /// </summary>
+	  private string R0;
+
+	  /// <summary>
+	  /// Region RV
+	  /// "If the word begins with two vowels, RV is the region after the third letter,
+	  /// otherwise the region after the first vowel not at the beginning of the word,
+	  /// or the end of the word if these positions cannot be found."
+	  /// </summary>
+		private string RV;
+
+	  /// <summary>
+	  /// Region R1
+	  /// "R1 is the region after the first non-vowel following a vowel
+	  /// or is the null region at the end of the word if there is no such non-vowel"
+	  /// </summary>
+		private string R1;
+
+	  /// <summary>
+	  /// Region R2
+	  /// "R2 is the region after the first non-vowel in R1 following a vowel
+	  /// or is the null region at the end of the word if there is no such non-vowel"
+	  /// </summary>
+		private string R2;
+
+
+	  /// <summary>
+	  /// Set to true if we need to perform step 2
+	  /// </summary>
+		private bool suite;
+
+	  /// <summary>
+	  /// Set to true if the buffer was modified
+	  /// </summary>
+		private bool modified;
+
+
+		/// <summary>
+		/// Stems the given term to a unique <tt>discriminator</tt>.
+		/// </summary>
+		/// <param name="term">  java.langString The term that should be stemmed </param>
+		/// <returns> java.lang.String  Discriminator for <tt>term</tt> </returns>
+		protected internal virtual string stem(string term)
+		{
+		if (!isStemmable(term))
+		{
+		  return term;
+		}
+
+		// Use lowercase for medium stemming.
+		term = term.ToLower(locale);
+
+		// Reset the StringBuilder.
+		sb.Remove(0, sb.Length);
+		sb.Insert(0, term);
+
+		// reset the booleans
+		modified = false;
+		suite = false;
+
+		sb = treatVowels(sb);
+
+		setStrings();
+
+		step1();
+
+		if (!modified || suite)
+		{
+		  if (RV != null)
+		  {
+			suite = step2a();
+			if (!suite)
+			{
+			  step2b();
+			}
+		  }
+		}
+
+		if (modified || suite)
+		{
+		  step3();
+		}
+		else
+		{
+		  step4();
+		}
+
+		step5();
+
+		step6();
+
+		return sb.ToString();
+		}
+
+	  /// <summary>
+	  /// Sets the search region Strings<br>
+	  /// it needs to be done each time the buffer was modified
+	  /// </summary>
+	  private void setStrings()
+	  {
+		// set the strings
+		R0 = sb.ToString();
+		RV = retrieveRV(sb);
+		R1 = retrieveR(sb);
+		if (R1 != null)
+		{
+		  tb.Remove(0, tb.Length);
+		  tb.Insert(0, R1);
+		  R2 = retrieveR(tb);
+		}
+		else
+		{
+		  R2 = null;
+		}
+	  }
+
+	  /// <summary>
+	  /// First step of the Porter Algorithm<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step1()
+	  {
+		string[] suffix = new string[] {"ances", "iqUes", "ismes", "ables", "istes", "ance", "iqUe", "isme", "able", "iste"};
+		deleteFrom(R2, suffix);
+
+		replaceFrom(R2, new string[] {"logies", "logie"}, "log");
+		replaceFrom(R2, new string[] {"usions", "utions", "usion", "ution"}, "u");
+		replaceFrom(R2, new string[] {"ences", "ence"}, "ent");
+
+		string[] search = new string[] {"atrices", "ateurs", "ations", "atrice", "ateur", "ation"};
+		deleteButSuffixFromElseReplace(R2, search, "ic", true, R0, "iqU");
+
+		deleteButSuffixFromElseReplace(R2, new string[] {"ements", "ement"}, "eus", false, R0, "eux");
+		deleteButSuffixFrom(R2, new string[] {"ements", "ement"}, "ativ", false);
+		deleteButSuffixFrom(R2, new string[] {"ements", "ement"}, "iv", false);
+		deleteButSuffixFrom(R2, new string[] {"ements", "ement"}, "abl", false);
+		deleteButSuffixFrom(R2, new string[] {"ements", "ement"}, "iqU", false);
+
+		deleteFromIfTestVowelBeforeIn(R1, new string[] {"issements", "issement"}, false, R0);
+		deleteFrom(RV, new string[] {"ements", "ement"});
+
+		deleteButSuffixFromElseReplace(R2, new string[] {"ités", "ité"}, "abil", false, R0, "abl");
+		deleteButSuffixFromElseReplace(R2, new string[] {"ités", "ité"}, "ic", false, R0, "iqU");
+		deleteButSuffixFrom(R2, new string[] {"ités", "ité"}, "iv", true);
+
+		string[] autre = new string[] {"ifs", "ives", "if", "ive"};
+		deleteButSuffixFromElseReplace(R2, autre, "icat", false, R0, "iqU");
+		deleteButSuffixFromElseReplace(R2, autre, "at", true, R2, "iqU");
+
+		replaceFrom(R0, new string[] {"eaux"}, "eau");
+
+		replaceFrom(R1, new string[] {"aux"}, "al");
+
+		deleteButSuffixFromElseReplace(R2, new string[] {"euses", "euse"}, "", true, R1, "eux");
+
+		deleteFrom(R2, new string[] {"eux"});
+
+		// if one of the next steps is performed, we will need to perform step2a
+		bool temp = false;
+		temp = replaceFrom(RV, new string[] {"amment"}, "ant");
+		if (temp == true)
+		{
+		  suite = true;
+		}
+		temp = replaceFrom(RV, new string[] {"emment"}, "ent");
+		if (temp == true)
+		{
+		  suite = true;
+		}
+		temp = deleteFromIfTestVowelBeforeIn(RV, new string[] {"ments", "ment"}, true, RV);
+		if (temp == true)
+		{
+		  suite = true;
+		}
+
+	  }
+
+	  /// <summary>
+	  /// Second step (A) of the Porter Algorithm<br>
+	  /// Will be performed if nothing changed from the first step
+	  /// or changed were done in the amment, emment, ments or ment suffixes<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  /// <returns> boolean - true if something changed in the StringBuilder </returns>
+	  private bool step2a()
+	  {
+		string[] search = new string[] {"îmes", "îtes", "iraIent", "irait", "irais", "irai", "iras", "ira", "irent", "iriez", "irez", "irions", "irons", "iront", "issaIent", "issais", "issantes", "issante", "issants", "issant", "issait", "issais", "issions", "issons", "issiez", "issez", "issent", "isses", "isse", "ir", "is", "ît", "it", "ies", "ie", "i"};
+		return deleteFromIfTestVowelBeforeIn(RV, search, false, RV);
+	  }
+
+	  /// <summary>
+	  /// Second step (B) of the Porter Algorithm<br>
+	  /// Will be performed if step 2 A was performed unsuccessfully<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step2b()
+	  {
+		string[] suffix = new string[] {"eraIent", "erais", "erait", "erai", "eras", "erions", "eriez", "erons", "eront","erez", "èrent", "era", "ées", "iez", "ée", "és", "er", "ez", "é"};
+		deleteFrom(RV, suffix);
+
+		string[] search = new string[] {"assions", "assiez", "assent", "asses", "asse", "aIent", "antes", "aIent", "Aient", "ante", "âmes", "âtes", "ants", "ant", "ait", "aît", "ais", "Ait", "Aît", "Ais", "ât", "as", "ai", "Ai", "a"};
+		deleteButSuffixFrom(RV, search, "e", true);
+
+		deleteFrom(R2, new string[] {"ions"});
+	  }
+
+	  /// <summary>
+	  /// Third step of the Porter Algorithm<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step3()
+	  {
+		if (sb.Length > 0)
+		{
+		  char ch = sb[sb.Length - 1];
+		  if (ch == 'Y')
+		  {
+			sb[sb.Length - 1] = 'i';
+			setStrings();
+		  }
+		  else if (ch == 'ç')
+		  {
+			sb[sb.Length - 1] = 'c';
+			setStrings();
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Fourth step of the Porter Algorithm<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step4()
+	  {
+		if (sb.Length > 1)
+		{
+		  char ch = sb[sb.Length - 1];
+		  if (ch == 's')
+		  {
+			char b = sb[sb.Length - 2];
+			if (b != 'a' && b != 'i' && b != 'o' && b != 'u' && b != 'è' && b != 's')
+			{
+			  sb.Remove(sb.Length - 1, sb.Length - sb.Length - 1);
+			  setStrings();
+			}
+		  }
+		}
+		bool found = deleteFromIfPrecededIn(R2, new string[] {"ion"}, RV, "s");
+		if (!found)
+		{
+		found = deleteFromIfPrecededIn(R2, new string[] {"ion"}, RV, "t");
+		}
+
+		replaceFrom(RV, new string[] {"Ière", "ière", "Ier", "ier"}, "i");
+		deleteFrom(RV, new string[] {"e"});
+		deleteFromIfPrecededIn(RV, new string[] {"ë"}, R0, "gu");
+	  }
+
+	  /// <summary>
+	  /// Fifth step of the Porter Algorithm<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step5()
+	  {
+		if (R0 != null)
+		{
+		  if (R0.EndsWith("enn", StringComparison.Ordinal) || R0.EndsWith("onn", StringComparison.Ordinal) || R0.EndsWith("ett", StringComparison.Ordinal) || R0.EndsWith("ell", StringComparison.Ordinal) || R0.EndsWith("eill", StringComparison.Ordinal))
+		  {
+			sb.Remove(sb.Length - 1, sb.Length - sb.Length - 1);
+			setStrings();
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Sixth (and last!) step of the Porter Algorithm<br>
+	  /// refer to http://snowball.sourceforge.net/french/stemmer.html for an explanation
+	  /// </summary>
+	  private void step6()
+	  {
+		if (R0 != null && R0.Length > 0)
+		{
+		  bool seenVowel = false;
+		  bool seenConson = false;
+		  int pos = -1;
+		  for (int i = R0.Length - 1; i > -1; i--)
+		  {
+			char ch = R0[i];
+			if (isVowel(ch))
+			{
+			  if (!seenVowel)
+			  {
+				if (ch == 'é' || ch == 'è')
+				{
+				  pos = i;
+				  break;
+				}
+			  }
+			  seenVowel = true;
+			}
+			else
+			{
+			  if (seenVowel)
+			  {
+				break;
+			  }
+			  else
+			  {
+				seenConson = true;
+			  }
+			}
+		  }
+		  if (pos > -1 && seenConson && !seenVowel)
+		  {
+			sb[pos] = 'e';
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Delete a suffix searched in zone "source" if zone "from" contains prefix + search string
+	  /// </summary>
+	  /// <param name="source"> java.lang.String - the primary source zone for search </param>
+	  /// <param name="search"> java.lang.String[] - the strings to search for suppression </param>
+	  /// <param name="from"> java.lang.String - the secondary source zone for search </param>
+	  /// <param name="prefix"> java.lang.String - the prefix to add to the search string to test </param>
+	  /// <returns> boolean - true if modified </returns>
+	  private bool deleteFromIfPrecededIn(string source, string[] search, string from, string prefix)
+	  {
+		bool found = false;
+		if (source != null)
+		{
+		  for (int i = 0; i < search.Length; i++)
+		  {
+			if (source.EndsWith(search[i], StringComparison.Ordinal))
+			{
+			  if (from != null && from.EndsWith(prefix + search[i], StringComparison.Ordinal))
+			  {
+				sb.Remove(sb.Length - search[i].Length, sb.Length - sb.Length - search[i].Length);
+				found = true;
+				setStrings();
+				break;
+			  }
+			}
+		  }
+		}
+		return found;
+	  }
+
+	  /// <summary>
+	  /// Delete a suffix searched in zone "source" if the preceding letter is (or isn't) a vowel
+	  /// </summary>
+	  /// <param name="source"> java.lang.String - the primary source zone for search </param>
+	  /// <param name="search"> java.lang.String[] - the strings to search for suppression </param>
+	  /// <param name="vowel"> boolean - true if we need a vowel before the search string </param>
+	  /// <param name="from"> java.lang.String - the secondary source zone for search (where vowel could be) </param>
+	  /// <returns> boolean - true if modified </returns>
+	  private bool deleteFromIfTestVowelBeforeIn(string source, string[] search, bool vowel, string from)
+	  {
+		bool found = false;
+		if (source != null && from != null)
+		{
+		  for (int i = 0; i < search.Length; i++)
+		  {
+			if (source.EndsWith(search[i], StringComparison.Ordinal))
+			{
+			  if ((search[i].Length + 1) <= from.Length)
+			  {
+				bool test = isVowel(sb[sb.Length - (search[i].Length + 1)]);
+				if (test == vowel)
+				{
+				  sb.Remove(sb.Length - search[i].Length, sb.Length - sb.Length - search[i].Length);
+				  modified = true;
+				  found = true;
+				  setStrings();
+				  break;
+				}
+			  }
+			}
+		  }
+		}
+		return found;
+	  }
+
+	  /// <summary>
+	  /// Delete a suffix searched in zone "source" if preceded by the prefix
+	  /// </summary>
+	  /// <param name="source"> java.lang.String - the primary source zone for search </param>
+	  /// <param name="search"> java.lang.String[] - the strings to search for suppression </param>
+	  /// <param name="prefix"> java.lang.String - the prefix to add to the search string to test </param>
+	  /// <param name="without"> boolean - true if it will be deleted even without prefix found </param>
+	  private void deleteButSuffixFrom(string source, string[] search, string prefix, bool without)
+	  {
+		if (source != null)
+		{
+		  for (int i = 0; i < search.Length; i++)
+		  {
+			if (source.EndsWith(prefix + search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - (prefix.Length + search[i].Length), sb.Length - sb.Length - (prefix.Length + search[i].Length));
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+			else if (without && source.EndsWith(search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - search[i].Length, sb.Length - sb.Length - search[i].Length);
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Delete a suffix searched in zone "source" if preceded by prefix<br>
+	  /// or replace it with the replace string if preceded by the prefix in the zone "from"<br>
+	  /// or delete the suffix if specified
+	  /// </summary>
+	  /// <param name="source"> java.lang.String - the primary source zone for search </param>
+	  /// <param name="search"> java.lang.String[] - the strings to search for suppression </param>
+	  /// <param name="prefix"> java.lang.String - the prefix to add to the search string to test </param>
+	  /// <param name="without"> boolean - true if it will be deleted even without prefix found </param>
+	  private void deleteButSuffixFromElseReplace(string source, string[] search, string prefix, bool without, string from, string replace)
+	  {
+		if (source != null)
+		{
+		  for (int i = 0; i < search.Length; i++)
+		  {
+			if (source.EndsWith(prefix + search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - (prefix.Length + search[i].Length), sb.Length - sb.Length - (prefix.Length + search[i].Length));
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+			else if (from != null && from.EndsWith(prefix + search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - (prefix.Length + search[i].Length), sb.Length - sb.Length - (prefix.Length + search[i].Length)).Insert(sb.Length - (prefix.Length + search[i].Length), replace);
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+			else if (without && source.EndsWith(search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - search[i].Length, sb.Length - sb.Length - search[i].Length);
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Replace a search string with another within the source zone
+	  /// </summary>
+	  /// <param name="source"> java.lang.String - the source zone for search </param>
+	  /// <param name="search"> java.lang.String[] - the strings to search for replacement </param>
+	  /// <param name="replace"> java.lang.String - the replacement string </param>
+	  private bool replaceFrom(string source, string[] search, string replace)
+	  {
+		bool found = false;
+		if (source != null)
+		{
+		  for (int i = 0; i < search.Length; i++)
+		  {
+			if (source.EndsWith(search[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - search[i].Length, sb.Length - sb.Length - search[i].Length).Insert(sb.Length - search[i].Length, replace);
+			  modified = true;
+			  found = true;
+			  setStrings();
+			  break;
+			}
+		  }
+		}
+		return found;
+	  }
+
+	  /// <summary>
+	  /// Delete a search string within the source zone
+	  /// </summary>
+	  /// <param name="source"> the source zone for search </param>
+	  /// <param name="suffix"> the strings to search for suppression </param>
+	  private void deleteFrom(string source, string[] suffix)
+	  {
+		if (source != null)
+		{
+		  for (int i = 0; i < suffix.Length; i++)
+		  {
+			if (source.EndsWith(suffix[i], StringComparison.Ordinal))
+			{
+			  sb.Remove(sb.Length - suffix[i].Length, sb.Length - sb.Length - suffix[i].Length);
+			  modified = true;
+			  setStrings();
+			  break;
+			}
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Test if a char is a french vowel, including accentuated ones
+	  /// </summary>
+	  /// <param name="ch"> the char to test </param>
+	  /// <returns> boolean - true if the char is a vowel </returns>
+	  private bool isVowel(char ch)
+	  {
+		switch (ch)
+		{
+		  case 'a':
+		  case 'e':
+		  case 'i':
+		  case 'o':
+		  case 'u':
+		  case 'y':
+		  case 'â':
+		  case 'à':
+		  case 'ë':
+		  case 'é':
+		  case 'ê':
+		  case 'è':
+		  case 'ï':
+		  case 'î':
+		  case 'ô':
+		  case 'ü':
+		  case 'ù':
+		  case 'û':
+			return true;
+		  default:
+			return false;
+		}
+	  }
+
+	  /// <summary>
+	  /// Retrieve the "R zone" (1 or 2 depending on the buffer) and return the corresponding string<br>
+	  /// "R is the region after the first non-vowel following a vowel
+	  /// or is the null region at the end of the word if there is no such non-vowel"<br> </summary>
+	  /// <param name="buffer"> java.lang.StringBuilder - the in buffer </param>
+	  /// <returns> java.lang.String - the resulting string </returns>
+	  private string retrieveR(StringBuilder buffer)
+	  {
+		int len = buffer.Length;
+		int pos = -1;
+		for (int c = 0; c < len; c++)
+		{
+		  if (isVowel(buffer[c]))
+		  {
+			pos = c;
+			break;
+		  }
+		}
+		if (pos > -1)
+		{
+		  int consonne = -1;
+		  for (int c = pos; c < len; c++)
+		  {
+			if (!isVowel(buffer[c]))
+			{
+			  consonne = c;
+			  break;
+			}
+		  }
+		  if (consonne > -1 && (consonne+1) < len)
+		  {
+			return StringHelperClass.SubstringSpecial(buffer, consonne+1, len);
+		  }
+		  else
+		  {
+			return null;
+		  }
+		}
+		else
+		{
+		  return null;
+		}
+	  }
+
+	  /// <summary>
+	  /// Retrieve the "RV zone" from a buffer an return the corresponding string<br>
+	  /// "If the word begins with two vowels, RV is the region after the third letter,
+	  /// otherwise the region after the first vowel not at the beginning of the word,
+	  /// or the end of the word if these positions cannot be found."<br> </summary>
+	  /// <param name="buffer"> java.lang.StringBuilder - the in buffer </param>
+	  /// <returns> java.lang.String - the resulting string </returns>
+	  private string retrieveRV(StringBuilder buffer)
+	  {
+		int len = buffer.Length;
+		if (buffer.Length > 3)
+		{
+		  if (isVowel(buffer[0]) && isVowel(buffer[1]))
+		  {
+			return buffer.Substring(3, len - 3);
+		  }
+		  else
+		  {
+			int pos = 0;
+			for (int c = 1; c < len; c++)
+			{
+			  if (isVowel(buffer[c]))
+			  {
+				pos = c;
+				break;
+			  }
+			}
+			if (pos + 1 < len)
+			{
+			  return StringHelperClass.SubstringSpecial(buffer, pos + 1, len);
+			}
+			else
+			{
+			  return null;
+			}
+		  }
+		}
+		else
+		{
+		  return null;
+		}
+	  }
+
+
+
+		/// <summary>
+		/// Turns u and i preceded AND followed by a vowel to UpperCase<br>
+		/// Turns y preceded OR followed by a vowel to UpperCase<br>
+		/// Turns u preceded by q to UpperCase<br>
+		/// </summary>
+		/// <param name="buffer"> java.util.StringBuilder - the buffer to treat </param>
+		/// <returns> java.util.StringBuilder - the treated buffer </returns>
+		private StringBuilder treatVowels(StringBuilder buffer)
+		{
+		for (int c = 0; c < buffer.Length; c++)
+		{
+		  char ch = buffer[c];
+
+		  if (c == 0) // first char
+		  {
+			if (buffer.Length > 1)
+			{
+			  if (ch == 'y' && isVowel(buffer[c + 1]))
+			  {
+				buffer[c] = 'Y';
+			  }
+			}
+		  }
+		  else if (c == buffer.Length - 1) // last char
+		  {
+			if (ch == 'u' && buffer[c - 1] == 'q')
+			{
+			  buffer[c] = 'U';
+			}
+			if (ch == 'y' && isVowel(buffer[c - 1]))
+			{
+			  buffer[c] = 'Y';
+			}
+		  }
+		  else // other cases
+		  {
+			if (ch == 'u')
+			{
+			  if (buffer[c - 1] == 'q')
+			  {
+				buffer[c] = 'U';
+			  }
+			  else if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1]))
+			  {
+				buffer[c] = 'U';
+			  }
+			}
+			if (ch == 'i')
+			{
+			  if (isVowel(buffer[c - 1]) && isVowel(buffer[c + 1]))
+			  {
+				buffer[c] = 'I';
+			  }
+			}
+			if (ch == 'y')
+			{
+			  if (isVowel(buffer[c - 1]) || isVowel(buffer[c + 1]))
+			  {
+				buffer[c] = 'Y';
+			  }
+			}
+		  }
+		}
+
+		return buffer;
+		}
+
+		/// <summary>
+		/// Checks a term if it can be processed correctly.
+		/// </summary>
+		/// <returns> boolean - true if, and only if, the given term consists in letters. </returns>
+		private bool isStemmable(string term)
+		{
+		bool upper = false;
+		int first = -1;
+		for (int c = 0; c < term.Length; c++)
+		{
+		  // Discard terms that contain non-letter characters.
+		  if (!char.IsLetter(term[c]))
+		  {
+			return false;
+		  }
+		  // Discard terms that contain multiple uppercase letters.
+		  if (char.IsUpper(term[c]))
+		  {
+			if (upper)
+			{
+			  return false;
+			}
+		  // First encountered uppercase letter, set flag and save
+		  // position.
+			else
+			{
+			  first = c;
+			  upper = true;
+			}
+		  }
+		}
+		// Discard the term if it contains a single uppercase letter that
+		// is not starting the term.
+		if (first > 0)
+		{
+		  return false;
+		}
+		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/Ga/IrishAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishAnalyzer.cs
new file mode 100644
index 0000000..1222998
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishAnalyzer.cs
@@ -0,0 +1,153 @@
+using System;
+
+namespace org.apache.lucene.analysis.ga
+{
+
+	/*
+	 * 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 StopFilter = org.apache.lucene.analysis.core.StopFilter;
+	using SetKeywordMarkerFilter = org.apache.lucene.analysis.miscellaneous.SetKeywordMarkerFilter;
+	using SnowballFilter = org.apache.lucene.analysis.snowball.SnowballFilter;
+	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 ElisionFilter = org.apache.lucene.analysis.util.ElisionFilter;
+	using StopwordAnalyzerBase = org.apache.lucene.analysis.util.StopwordAnalyzerBase;
+	using Version = org.apache.lucene.util.Version;
+	using IrishStemmer = org.tartarus.snowball.ext.IrishStemmer;
+
+	/// <summary>
+	/// <seealso cref="Analyzer"/> for Irish.
+	/// </summary>
+	public sealed class IrishAnalyzer : StopwordAnalyzerBase
+	{
+	  private readonly CharArraySet stemExclusionSet;
+
+	  /// <summary>
+	  /// File containing default Irish stopwords. </summary>
+	  public const string DEFAULT_STOPWORD_FILE = "stopwords.txt";
+
+	  private static readonly CharArraySet DEFAULT_ARTICLES = CharArraySet.unmodifiableSet(new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("d", "m", "b"), true));
+
+	  /// <summary>
+	  /// When StandardTokenizer splits t‑athair into {t, athair}, we don't
+	  /// want to cause a position increment, otherwise there will be problems
+	  /// with phrase queries versus tAthair (which would not have a gap).
+	  /// </summary>
+	  private static readonly CharArraySet HYPHENATIONS = CharArraySet.unmodifiableSet(new CharArraySet(Version.LUCENE_CURRENT, Arrays.asList("h", "n", "t"), true));
+
+	  /// <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;
+
+		static DefaultSetHolder()
+		{
+		  try
+		  {
+			DEFAULT_STOP_SET = loadStopwordSet(false, typeof(IrishAnalyzer), DEFAULT_STOPWORD_FILE, "#");
+		  }
+		  catch (IOException)
+		  {
+			// default set should always be present as it is part of the
+			// distribution (JAR)
+			throw new Exception("Unable to load default stopword set");
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the default stop words: <seealso cref="#DEFAULT_STOPWORD_FILE"/>.
+	  /// </summary>
+	  public IrishAnalyzer(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 IrishAnalyzer(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 IrishAnalyzer(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="IrishLowerCaseFilter"/>, <seealso cref="StopFilter"/>
+	  ///         , <seealso cref="SetKeywordMarkerFilter"/> if a stem exclusion set is
+	  ///         provided and <seealso cref="SnowballFilter"/>. </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);
+		StopFilter s = new StopFilter(matchVersion, result, HYPHENATIONS);
+		if (!matchVersion.onOrAfter(Version.LUCENE_44))
+		{
+		  s.EnablePositionIncrements = false;
+		}
+		result = s;
+		result = new ElisionFilter(result, DEFAULT_ARTICLES);
+		result = new IrishLowerCaseFilter(result);
+		result = new StopFilter(matchVersion, result, stopwords);
+		if (!stemExclusionSet.Empty)
+		{
+		  result = new SetKeywordMarkerFilter(result, stemExclusionSet);
+		}
+		result = new SnowballFilter(result, new IrishStemmer());
+		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/Ga/IrishLowerCaseFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilter.cs
new file mode 100644
index 0000000..52b342b
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilter.cs
@@ -0,0 +1,95 @@
+namespace org.apache.lucene.analysis.ga
+{
+
+	/*
+	 * 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;
+
+	/// <summary>
+	/// Normalises token text to lower case, handling t-prothesis
+	/// and n-eclipsis (i.e., that 'nAthair' should become 'n-athair')
+	/// </summary>
+	public sealed class IrishLowerCaseFilter : TokenFilter
+	{
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+
+	  /// <summary>
+	  /// Create an IrishLowerCaseFilter that normalises Irish token text.
+	  /// </summary>
+	  public IrishLowerCaseFilter(TokenStream @in) : base(@in)
+	  {
+	  }
+
+//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();
+		  int idx = 0;
+
+		  if (chLen > 1 && (chArray[0] == 'n' || chArray[0] == 't') && isUpperVowel(chArray[1]))
+		  {
+			chArray = termAtt.resizeBuffer(chLen + 1);
+			for (int i = chLen; i > 1; i--)
+			{
+			  chArray[i] = chArray[i - 1];
+			}
+			chArray[1] = '-';
+			termAtt.Length = chLen + 1;
+			idx = 2;
+			chLen = chLen + 1;
+		  }
+
+		  for (int i = idx; i < chLen;)
+		  {
+			i += char.toChars(char.ToLower(chArray[i]), chArray, i);
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+
+	  private bool isUpperVowel(int v)
+	  {
+		switch (v)
+		{
+		  case 'A':
+		  case 'E':
+		  case 'I':
+		  case 'O':
+		  case 'U':
+		  // vowels with acute accent (fada)
+		  case '\u00c1':
+		  case '\u00c9':
+		  case '\u00cd':
+		  case '\u00d3':
+		  case '\u00da':
+			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/Ga/IrishLowerCaseFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilterFactory.cs
new file mode 100644
index 0000000..83183ce
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Ga/IrishLowerCaseFilterFactory.cs
@@ -0,0 +1,65 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.ga
+{
+
+	/*
+	 * 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="IrishLowerCaseFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_ga" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.IrishLowerCaseFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class IrishLowerCaseFilterFactory : TokenFilterFactory, MultiTermAwareComponent
+	{
+
+	  /// <summary>
+	  /// Creates a new IrishLowerCaseFilterFactory </summary>
+	  public IrishLowerCaseFilterFactory(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 IrishLowerCaseFilter(input);
+	  }
+
+	  // this will 'mostly work', except for special cases, just like most other filters
+	  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/Gl/GalicianAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianAnalyzer.cs
new file mode 100644
index 0000000..5b1f540
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianAnalyzer.cs
@@ -0,0 +1,137 @@
+using System;
+
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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 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 WordlistLoader = org.apache.lucene.analysis.util.WordlistLoader;
+	using IOUtils = org.apache.lucene.util.IOUtils;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// <seealso cref="Analyzer"/> for Galician.
+	/// </summary>
+	public sealed class GalicianAnalyzer : StopwordAnalyzerBase
+	{
+	  private readonly CharArraySet stemExclusionSet;
+
+	  /// <summary>
+	  /// File containing default Galician stopwords. </summary>
+	  public const string DEFAULT_STOPWORD_FILE = "stopwords.txt";
+
+	  /// <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;
+
+		static DefaultSetHolder()
+		{
+		  try
+		  {
+			DEFAULT_STOP_SET = WordlistLoader.getWordSet(IOUtils.getDecodingReader(typeof(GalicianAnalyzer), DEFAULT_STOPWORD_FILE, StandardCharsets.UTF_8), Version.LUCENE_CURRENT);
+		  }
+		  catch (IOException ex)
+		  {
+			// default set should always be present as it is part of the
+			// distribution (JAR)
+			throw new Exception("Unable to load default stopword set", ex);
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the default stop words: <seealso cref="#DEFAULT_STOPWORD_FILE"/>.
+	  /// </summary>
+	  public GalicianAnalyzer(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 GalicianAnalyzer(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 GalicianAnalyzer(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="LowerCaseFilter"/>, <seealso cref="StopFilter"/>
+	  ///         , <seealso cref="SetKeywordMarkerFilter"/> if a stem exclusion set is
+	  ///         provided and <seealso cref="GalicianStemFilter"/>. </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);
+		result = new LowerCaseFilter(matchVersion, result);
+		result = new StopFilter(matchVersion, result, stopwords);
+		if (!stemExclusionSet.Empty)
+		{
+		  result = new SetKeywordMarkerFilter(result, stemExclusionSet);
+		}
+		result = new GalicianStemFilter(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/Gl/GalicianMinimalStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilter.cs
new file mode 100644
index 0000000..77dc426
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilter.cs
@@ -0,0 +1,66 @@
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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="GalicianMinimalStemmer"/> to stem 
+	/// Galician 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 GalicianMinimalStemFilter : TokenFilter
+	{
+	  private readonly GalicianMinimalStemmer stemmer = new GalicianMinimalStemmer();
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAttr = addAttribute(typeof(KeywordAttribute));
+
+	  public GalicianMinimalStemFilter(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/Gl/GalicianMinimalStemFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilterFactory.cs
new file mode 100644
index 0000000..3bf12e7
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemFilterFactory.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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="GalicianMinimalStemFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_glplural" 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.GalicianMinimalStemFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class GalicianMinimalStemFilterFactory : TokenFilterFactory
+	{
+
+	  /// <summary>
+	  /// Creates a new GalicianMinimalStemFilterFactory </summary>
+	  public GalicianMinimalStemFilterFactory(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 GalicianMinimalStemFilter(input);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemmer.cs
new file mode 100644
index 0000000..dff283b
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianMinimalStemmer.cs
@@ -0,0 +1,43 @@
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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 RSLPStemmerBase = org.apache.lucene.analysis.pt.RSLPStemmerBase;
+
+	/// <summary>
+	/// Minimal Stemmer for Galician
+	/// <para>
+	/// This follows the "RSLP-S" algorithm, but modified for Galician.
+	/// Hence this stemmer only applies the plural reduction step of:
+	/// "Regras do lematizador para o galego"
+	/// </para>
+	/// </summary>
+	/// <seealso cref= RSLPStemmerBase </seealso>
+	public class GalicianMinimalStemmer : RSLPStemmerBase
+	{
+
+	  private static readonly Step pluralStep = parse(typeof(GalicianMinimalStemmer), "galician.rslp")["Plural"];
+
+	  public virtual int stem(char[] s, int len)
+	  {
+		return pluralStep.apply(s, len);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilter.cs
new file mode 100644
index 0000000..9cff9c6
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilter.cs
@@ -0,0 +1,70 @@
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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="GalicianStemmer"/> to stem 
+	/// Galician 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 GalicianStemFilter : TokenFilter
+	{
+	  private readonly GalicianStemmer stemmer = new GalicianStemmer();
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAttr = addAttribute(typeof(KeywordAttribute));
+
+	  public GalicianStemFilter(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)
+		  {
+			// this stemmer increases word length by 1: worst case '*çom' -> '*ción'
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int len = termAtt.length();
+			int len = termAtt.length();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int newlen = stemmer.stem(termAtt.resizeBuffer(len+1), len);
+			int newlen = stemmer.stem(termAtt.resizeBuffer(len + 1), len);
+			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/Gl/GalicianStemFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilterFactory.cs
new file mode 100644
index 0000000..3e3c393
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemFilterFactory.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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="GalicianStemFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_glstem" 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.GalicianStemFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class GalicianStemFilterFactory : TokenFilterFactory
+	{
+
+	  /// <summary>
+	  /// Creates a new GalicianStemFilterFactory </summary>
+	  public GalicianStemFilterFactory(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 GalicianStemFilter(input);
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemmer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemmer.cs
new file mode 100644
index 0000000..f435318
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Gl/GalicianStemmer.cs
@@ -0,0 +1,102 @@
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.gl
+{
+
+	/*
+	 * 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 RSLPStemmerBase = org.apache.lucene.analysis.pt.RSLPStemmerBase;
+
+	/// <summary>
+	/// Galician stemmer implementing "Regras do lematizador para o galego".
+	/// </summary>
+	/// <seealso cref= RSLPStemmerBase </seealso>
+	/// <seealso cref= <a href="http://bvg.udc.es/recursos_lingua/stemming.jsp">Description of rules</a> </seealso>
+	public class GalicianStemmer : RSLPStemmerBase
+	{
+	  private static readonly Step plural, unification, adverb, augmentative, noun, verb, vowel;
+
+	  static GalicianStemmer()
+	  {
+		IDictionary<string, Step> steps = parse(typeof(GalicianStemmer), "galician.rslp");
+		plural = steps["Plural"];
+		unification = steps["Unification"];
+		adverb = steps["Adverb"];
+		augmentative = steps["Augmentative"];
+		noun = steps["Noun"];
+		verb = steps["Verb"];
+		vowel = steps["Vowel"];
+	  }
+
+	  /// <param name="s"> buffer, oversized to at least <code>len+1</code> </param>
+	  /// <param name="len"> initial valid length of buffer </param>
+	  /// <returns> new valid length, stemmed </returns>
+	  public virtual int stem(char[] s, int len)
+	  {
+		Debug.Assert(s.Length >= len + 1, "this stemmer requires an oversized array of at least 1");
+
+		len = plural.apply(s, len);
+		len = unification.apply(s, len);
+		len = adverb.apply(s, len);
+
+		int oldlen;
+		do
+		{
+		  oldlen = len;
+		  len = augmentative.apply(s, len);
+		} while (len != oldlen);
+
+		oldlen = len;
+		len = noun.apply(s, len);
+		if (len == oldlen) // suffix not removed
+		{
+		  len = verb.apply(s, len);
+		}
+
+		len = vowel.apply(s, len);
+
+		// RSLG accent removal
+		for (int i = 0; i < len; i++)
+		{
+		  switch (s[i])
+		  {
+			case 'á':
+				s[i] = 'a';
+				break;
+			case 'é':
+			case 'ê':
+				s[i] = 'e';
+				break;
+			case 'í':
+				s[i] = 'i';
+				break;
+			case 'ó':
+				s[i] = 'o';
+				break;
+			case 'ú':
+				s[i] = 'u';
+				break;
+		  }
+		}
+
+		return len;
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiAnalyzer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiAnalyzer.cs
new file mode 100644
index 0000000..c5f2b97
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiAnalyzer.cs
@@ -0,0 +1,158 @@
+using System;
+
+namespace org.apache.lucene.analysis.hi
+{
+
+	/*
+	 * 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 StandardTokenizer = org.apache.lucene.analysis.standard.StandardTokenizer;
+	using CharArraySet = org.apache.lucene.analysis.util.CharArraySet;
+	using StopwordAnalyzerBase = org.apache.lucene.analysis.util.StopwordAnalyzerBase;
+	using LowerCaseFilter = org.apache.lucene.analysis.core.LowerCaseFilter;
+	using StopFilter = org.apache.lucene.analysis.core.StopFilter;
+	using IndicNormalizationFilter = org.apache.lucene.analysis.@in.IndicNormalizationFilter;
+	using IndicTokenizer = org.apache.lucene.analysis.@in.IndicTokenizer;
+	using Version = org.apache.lucene.util.Version;
+
+	/// <summary>
+	/// Analyzer for Hindi.
+	/// <para>
+	/// <a name="version"/>
+	/// </para>
+	/// <para>You must specify the required <seealso cref="Version"/>
+	/// compatibility when creating HindiAnalyzer:
+	/// <ul>
+	///   <li> As of 3.6, StandardTokenizer is used for tokenization
+	/// </ul>
+	/// </para>
+	/// </summary>
+	public sealed class HindiAnalyzer : StopwordAnalyzerBase
+	{
+	  private readonly CharArraySet stemExclusionSet;
+
+	  /// <summary>
+	  /// File containing default Hindi stopwords.
+	  /// 
+	  /// Default stopword list is from http://members.unine.ch/jacques.savoy/clef/index.html
+	  /// The stopword list is BSD-Licensed.
+	  /// </summary>
+	  public const string DEFAULT_STOPWORD_FILE = "stopwords.txt";
+	  private const string STOPWORDS_COMMENT = "#";
+
+	  /// <summary>
+	  /// Returns an unmodifiable instance of the default stop-words set. </summary>
+	  /// <returns> an unmodifiable instance of the 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;
+
+		static DefaultSetHolder()
+		{
+		  try
+		  {
+			DEFAULT_STOP_SET = loadStopwordSet(false, typeof(HindiAnalyzer), DEFAULT_STOPWORD_FILE, STOPWORDS_COMMENT);
+		  }
+		  catch (IOException)
+		  {
+			// default set should always be present as it is part of the
+			// distribution (JAR)
+			throw new Exception("Unable to load default stopword set");
+		  }
+		}
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the given stop words
+	  /// </summary>
+	  /// <param name="version"> lucene compatibility version </param>
+	  /// <param name="stopwords"> a stopword set </param>
+	  /// <param name="stemExclusionSet"> a stemming exclusion set </param>
+	  public HindiAnalyzer(Version version, CharArraySet stopwords, CharArraySet stemExclusionSet) : base(version, stopwords)
+	  {
+		this.stemExclusionSet = CharArraySet.unmodifiableSet(CharArraySet.copy(matchVersion, stemExclusionSet));
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the given stop words 
+	  /// </summary>
+	  /// <param name="version"> lucene compatibility version </param>
+	  /// <param name="stopwords"> a stopword set </param>
+	  public HindiAnalyzer(Version version, CharArraySet stopwords) : this(version, stopwords, CharArraySet.EMPTY_SET)
+	  {
+	  }
+
+	  /// <summary>
+	  /// Builds an analyzer with the default stop words:
+	  /// <seealso cref="#DEFAULT_STOPWORD_FILE"/>.
+	  /// </summary>
+	  public HindiAnalyzer(Version version) : this(version, DefaultSetHolder.DEFAULT_STOP_SET)
+	  {
+	  }
+
+	  /// <summary>
+	  /// Creates
+	  /// <seealso cref="org.apache.lucene.analysis.Analyzer.TokenStreamComponents"/>
+	  /// used to tokenize all the text in the provided <seealso cref="Reader"/>.
+	  /// </summary>
+	  /// <returns> <seealso cref="org.apache.lucene.analysis.Analyzer.TokenStreamComponents"/>
+	  ///         built from a <seealso cref="StandardTokenizer"/> filtered with
+	  ///         <seealso cref="LowerCaseFilter"/>, <seealso cref="IndicNormalizationFilter"/>,
+	  ///         <seealso cref="HindiNormalizationFilter"/>, <seealso cref="SetKeywordMarkerFilter"/>
+	  ///         if a stem exclusion set is provided, <seealso cref="HindiStemFilter"/>, and
+	  ///         Hindi Stop words </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;
+		Tokenizer source;
+		if (matchVersion.onOrAfter(Version.LUCENE_36))
+		{
+		  source = new StandardTokenizer(matchVersion, reader);
+		}
+		else
+		{
+		  source = new IndicTokenizer(matchVersion, reader);
+		}
+		TokenStream result = new LowerCaseFilter(matchVersion, source);
+		if (!stemExclusionSet.Empty)
+		{
+		  result = new SetKeywordMarkerFilter(result, stemExclusionSet);
+		}
+		result = new IndicNormalizationFilter(result);
+		result = new HindiNormalizationFilter(result);
+		result = new StopFilter(matchVersion, result, stopwords);
+		result = new HindiStemFilter(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/Hi/HindiNormalizationFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilter.cs
new file mode 100644
index 0000000..2d31f1d
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilter.cs
@@ -0,0 +1,62 @@
+namespace org.apache.lucene.analysis.hi
+{
+
+	/*
+	 * 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; // javadoc @link
+	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="HindiNormalizer"/> to normalize the
+	/// orthography.
+	/// <para>
+	/// In some cases the normalization may cause unrelated terms to conflate, so
+	/// to prevent terms from being normalized 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>
+	/// <seealso cref= HindiNormalizer </seealso>
+	public sealed class HindiNormalizationFilter : TokenFilter
+	{
+
+	  private readonly HindiNormalizer normalizer = new HindiNormalizer();
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAtt = addAttribute(typeof(KeywordAttribute));
+
+	  public HindiNormalizationFilter(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 (!keywordAtt.Keyword)
+		  {
+			termAtt.Length = normalizer.normalize(termAtt.buffer(), termAtt.length());
+		  }
+		  return true;
+		}
+		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/Hi/HindiNormalizationFilterFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilterFactory.cs
new file mode 100644
index 0000000..f18c199
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizationFilterFactory.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+
+namespace org.apache.lucene.analysis.hi
+{
+
+	/*
+	 * 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="HindiNormalizationFilter"/>. 
+	/// <pre class="prettyprint">
+	/// &lt;fieldType name="text_hinormal" class="solr.TextField" positionIncrementGap="100"&gt;
+	///   &lt;analyzer&gt;
+	///     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+	///     &lt;filter class="solr.HindiNormalizationFilterFactory"/&gt;
+	///   &lt;/analyzer&gt;
+	/// &lt;/fieldType&gt;</pre>
+	/// </summary>
+	public class HindiNormalizationFilterFactory : TokenFilterFactory, MultiTermAwareComponent
+	{
+
+	  /// <summary>
+	  /// Creates a new HindiNormalizationFilterFactory </summary>
+	  public HindiNormalizationFilterFactory(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 HindiNormalizationFilter(input);
+	  }
+
+	  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/Hi/HindiNormalizer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizer.cs
new file mode 100644
index 0000000..ebd674b
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiNormalizer.cs
@@ -0,0 +1,193 @@
+namespace org.apache.lucene.analysis.hi
+{
+
+	/*
+	 * 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 org.apache.lucene.analysis.util;
+//JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to C#:
+//	import static org.apache.lucene.analysis.util.StemmerUtil.*;
+
+	/// <summary>
+	/// Normalizer for Hindi.
+	/// <para>
+	/// Normalizes text to remove some differences in spelling variations.
+	/// </para>
+	/// <para>
+	/// Implements the Hindi-language specific algorithm specified in:
+	/// <i>Word normalization in Indian languages</i>
+	/// Prasad Pingali and Vasudeva Varma.
+	/// http://web2py.iiit.ac.in/publications/default/download/inproceedings.pdf.3fe5b38c-02ee-41ce-9a8f-3e745670be32.pdf
+	/// </para>
+	/// <para>
+	/// with the following additions from <i>Hindi CLIR in Thirty Days</i>
+	/// Leah S. Larkey, Margaret E. Connell, and Nasreen AbdulJaleel.
+	/// http://maroo.cs.umass.edu/pub/web/getpdf.php?id=454:
+	/// <ul>
+	///  <li>Internal Zero-width joiner and Zero-width non-joiners are removed
+	///  <li>In addition to chandrabindu, NA+halant is normalized to anusvara
+	/// </ul>
+	/// 
+	/// </para>
+	/// </summary>
+	public class HindiNormalizer
+	{
+	  /// <summary>
+	  /// Normalize an input buffer of Hindi text
+	  /// </summary>
+	  /// <param name="s"> input buffer </param>
+	  /// <param name="len"> length of input buffer </param>
+	  /// <returns> length of input buffer after normalization </returns>
+	  public virtual int normalize(char[] s, int len)
+	  {
+
+		for (int i = 0; i < len; i++)
+		{
+		  switch (s[i])
+		  {
+			// dead n -> bindu
+		  case '\u0928':
+			if (i + 1 < len && s[i + 1] == '\u094D')
+			{
+			  s[i] = '\u0902';
+			  len = StemmerUtil.delete(s, i + 1, len);
+			}
+			break;
+		  // candrabindu -> bindu
+		  case '\u0901':
+			s[i] = '\u0902';
+			break;
+		  // nukta deletions
+		  case '\u093C':
+			len = StemmerUtil.delete(s, i, len);
+			i--;
+			break;
+		  case '\u0929':
+			s[i] = '\u0928';
+			break;
+		  case '\u0931':
+			s[i] = '\u0930';
+			break;
+		  case '\u0934':
+			s[i] = '\u0933';
+			break;
+		  case '\u0958':
+			s[i] = '\u0915';
+			break;
+		  case '\u0959':
+			s[i] = '\u0916';
+			break;
+		  case '\u095A':
+			s[i] = '\u0917';
+			break;
+		  case '\u095B':
+			s[i] = '\u091C';
+			break;
+		  case '\u095C':
+			s[i] = '\u0921';
+			break;
+		  case '\u095D':
+			s[i] = '\u0922';
+			break;
+		  case '\u095E':
+			s[i] = '\u092B';
+			break;
+		  case '\u095F':
+			s[i] = '\u092F';
+			break;
+			// zwj/zwnj -> delete
+		  case '\u200D':
+		  case '\u200C':
+			len = StemmerUtil.delete(s, i, len);
+			i--;
+			break;
+			// virama -> delete
+		  case '\u094D':
+			len = StemmerUtil.delete(s, i, len);
+			i--;
+			break;
+			// chandra/short -> replace
+		  case '\u0945':
+		  case '\u0946':
+			s[i] = '\u0947';
+			break;
+		  case '\u0949':
+		  case '\u094A':
+			s[i] = '\u094B';
+			break;
+		  case '\u090D':
+		  case '\u090E':
+			s[i] = '\u090F';
+			break;
+		  case '\u0911':
+		  case '\u0912':
+			s[i] = '\u0913';
+			break;
+		  case '\u0972':
+			s[i] = '\u0905';
+			break;
+			// long -> short ind. vowels
+		  case '\u0906':
+			s[i] = '\u0905';
+			break;
+		  case '\u0908':
+			s[i] = '\u0907';
+			break;
+		  case '\u090A':
+			s[i] = '\u0909';
+			break;
+		  case '\u0960':
+			s[i] = '\u090B';
+			break;
+		  case '\u0961':
+			s[i] = '\u090C';
+			break;
+		  case '\u0910':
+			s[i] = '\u090F';
+			break;
+		  case '\u0914':
+			s[i] = '\u0913';
+			break;
+			// long -> short dep. vowels
+		  case '\u0940':
+			s[i] = '\u093F';
+			break;
+		  case '\u0942':
+			s[i] = '\u0941';
+			break;
+		  case '\u0944':
+			s[i] = '\u0943';
+			break;
+		  case '\u0963':
+			s[i] = '\u0962';
+			break;
+		  case '\u0948':
+			s[i] = '\u0947';
+			break;
+		  case '\u094C':
+			s[i] = '\u094B';
+			break;
+		  default:
+			break;
+		  }
+		}
+
+		return len;
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/99717176/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiStemFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiStemFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiStemFilter.cs
new file mode 100644
index 0000000..9098b66
--- /dev/null
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hi/HindiStemFilter.cs
@@ -0,0 +1,56 @@
+namespace org.apache.lucene.analysis.hi
+{
+
+	/*
+	 * 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 KeywordAttribute = org.apache.lucene.analysis.tokenattributes.KeywordAttribute;
+	using CharTermAttribute = org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+
+	/// <summary>
+	/// A <seealso cref="TokenFilter"/> that applies <seealso cref="HindiStemmer"/> to stem Hindi words.
+	/// </summary>
+	public sealed class HindiStemFilter : TokenFilter
+	{
+	  private readonly CharTermAttribute termAtt = addAttribute(typeof(CharTermAttribute));
+	  private readonly KeywordAttribute keywordAtt = addAttribute(typeof(KeywordAttribute));
+	  private readonly HindiStemmer stemmer = new HindiStemmer();
+
+	  public HindiStemFilter(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 (!keywordAtt.Keyword)
+		  {
+			termAtt.Length = stemmer.stem(termAtt.buffer(), termAtt.length());
+		  }
+		  return true;
+		}
+		else
+		{
+		  return false;
+		}
+	  }
+	}
+
+}
\ No newline at end of file


Mime
View raw message