// Path: src/main/java/eus/ixa/ixa/pipe/pos/Morpheme.java
// public class Morpheme {
// 
//   /**
//    * The surface form of the morpheme, e.g., the word.
//    */
//   private String word;
//   /**
//    * The morphological tag of the morpheme.
//    */
//   private String tag;
//   /**
//    * The lemma of the morpheme.
//    */
//   private String lemma;
// 
//   /**
//    * Create a new <code>Morpheme</code> with a null content (i.e., word).
//    */
//   public Morpheme() {
//   }
// 
//   /**
//    * Construct a morpheme object.
//    * 
//    * @param aWord
//    *          the word
//    * @param aTag
//    *          the tag
//    */
//   public Morpheme(final String aWord, final String aTag) {
//     this.word = aWord;
//     this.tag = aTag.toUpperCase();
//   }
// 
//   /**
//    * Construct a morpheme object with lemma.
//    * 
//    * @param aWord
//    *          the word
//    * @param aTag
//    *          the tag
//    * @param aLemma
//    *          the lemma
//    */
//   public Morpheme(final String aWord, final String aTag, final String aLemma) {
//     this.word = aWord;
//     this.tag = aTag.toUpperCase();
//     this.lemma = aLemma;
//   }
// 
//   /**
//    * Get the word.
//    * 
//    * @return the word
//    */
//   public final String getWord() {
//     return this.word;
//   }
// 
//   /**
//    * Get the morphological tag.
//    * 
//    * @return the morphological tag
//    */
//   public final String getTag() {
//     return this.tag;
//   }
// 
//   /**
//    * Get the lemma.
//    * 
//    * @return the lemma
//    */
//   public final String getLemma() {
//     return this.lemma;
//   }
// 
//   /**
//    * Set the value of the word.
//    * 
//    * @param aWord
//    *          the word
//    */
//   public final void setValue(final String aWord) {
//     this.word = aWord;
//   }
// 
//   /**
//    * Set the morphological tag.
//    * 
//    * @param aTag
//    *          the morphological tag
//    */
//   public final void setTag(final String aTag) {
//     this.tag = aTag.toUpperCase();
//   }
// 
//   /**
//    * Set the lemma.
//    * 
//    * @param aLemma
//    *          the lemma
//    */
//   public final void setLemma(final String aLemma) {
//     this.lemma = aLemma;
//   }
// 
// }
// 
// Path: src/main/java/eus/ixa/ixa/pipe/pos/MorphoFactory.java
// public class MorphoFactory {
// 
//   /**
//    * Construct morpheme object with word and morphological tag.
//    * 
//    * @param word
//    *          the word
//    * @param tag
//    *          the morphological tag
//    * @return the morpheme object
//    */
//   public final Morpheme createMorpheme(final String word, final String tag) {
//     final Morpheme morpheme = new Morpheme();
//     morpheme.setValue(word);
//     morpheme.setTag(tag);
//     return morpheme;
//   }
// 
//   /**
//    * Construct morpheme object with word, tag and lemma.
//    * 
//    * @param word
//    *          the word
//    * @param tag
//    *          the tag
//    * @param lemma
//    *          the lemma
//    * @return the morphological object
//    */
//   public final Morpheme createMorpheme(final String word, final String tag,
//       final String lemma) {
//     final Morpheme morpheme = new Morpheme();
//     morpheme.setValue(word);
//     morpheme.setTag(tag);
//     morpheme.setLemma(lemma);
//     return morpheme;
//   }
// 
// }


import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import eus.ixa.ixa.pipe.pos.Morpheme;
import eus.ixa.ixa.pipe.pos.MorphoFactory;
/*
 * Copyright 2016 Rodrigo Agerri

   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.
 */
package eus.ixa.ixa.pipe.lemma;




/**
 * Probabilistic lemmatizer.
 * 
 * @author ragerri
 * @version 2016-01-28
 */

public class StatisticalLemmatizer {

  /**
   * The lemmatizer.
   */
  private final LemmatizerME lemmatizer;
  /**
   * The models to use for every language. The keys of the hashmap are the language
   * codes, the values the models.
   */
  private final static ConcurrentHashMap<String, LemmatizerModel> lemmaModels = new ConcurrentHashMap<String, LemmatizerModel>();
  /**
   * The morpho factory.
   */
  private MorphoFactory morphoFactory;

  /**
   * Construct a statistical lemmatizer.
   * 
   * @param props
   *          the properties object
   */
  public StatisticalLemmatizer(final Properties props) {
    this(props, null);
  }

  /**
   * Construct a statistical lemmatizer with {@code MorphoFactory}.
   * 
   * @param props
   *          the properties object
   * @param aMorphoFactory
   *          the morpho factory
   */
// Path: src/main/java/eus/ixa/ixa/pipe/pos/Morpheme.java
// public class Morpheme {
// 
//   /**
//    * The surface form of the morpheme, e.g., the word.
//    */
//   private String word;
//   /**
//    * The morphological tag of the morpheme.
//    */
//   private String tag;
//   /**
//    * The lemma of the morpheme.
//    */
//   private String lemma;
// 
//   /**
//    * Create a new <code>Morpheme</code> with a null content (i.e., word).
//    */
//   public Morpheme() {
//   }
// 
//   /**
//    * Construct a morpheme object.
//    * 
//    * @param aWord
//    *          the word
//    * @param aTag
//    *          the tag
//    */
//   public Morpheme(final String aWord, final String aTag) {
//     this.word = aWord;
//     this.tag = aTag.toUpperCase();
//   }
// 
//   /**
//    * Construct a morpheme object with lemma.
//    * 
//    * @param aWord
//    *          the word
//    * @param aTag
//    *          the tag
//    * @param aLemma
//    *          the lemma
//    */
//   public Morpheme(final String aWord, final String aTag, final String aLemma) {
//     this.word = aWord;
//     this.tag = aTag.toUpperCase();
//     this.lemma = aLemma;
//   }
// 
//   /**
//    * Get the word.
//    * 
//    * @return the word
//    */
//   public final String getWord() {
//     return this.word;
//   }
// 
//   /**
//    * Get the morphological tag.
//    * 
//    * @return the morphological tag
//    */
//   public final String getTag() {
//     return this.tag;
//   }
// 
//   /**
//    * Get the lemma.
//    * 
//    * @return the lemma
//    */
//   public final String getLemma() {
//     return this.lemma;
//   }
// 
//   /**
//    * Set the value of the word.
//    * 
//    * @param aWord
//    *          the word
//    */
//   public final void setValue(final String aWord) {
//     this.word = aWord;
//   }
// 
//   /**
//    * Set the morphological tag.
//    * 
//    * @param aTag
//    *          the morphological tag
//    */
//   public final void setTag(final String aTag) {
//     this.tag = aTag.toUpperCase();
//   }
// 
//   /**
//    * Set the lemma.
//    * 
//    * @param aLemma
//    *          the lemma
//    */
//   public final void setLemma(final String aLemma) {
//     this.lemma = aLemma;
//   }
// 
// }
// 
// Path: src/main/java/eus/ixa/ixa/pipe/pos/MorphoFactory.java
// public class MorphoFactory {
// 
//   /**
//    * Construct morpheme object with word and morphological tag.
//    * 
//    * @param word
//    *          the word
//    * @param tag
//    *          the morphological tag
//    * @return the morpheme object
//    */
//   public final Morpheme createMorpheme(final String word, final String tag) {
//     final Morpheme morpheme = new Morpheme();
//     morpheme.setValue(word);
//     morpheme.setTag(tag);
//     return morpheme;
//   }
// 
//   /**
//    * Construct morpheme object with word, tag and lemma.
//    * 
//    * @param word
//    *          the word
//    * @param tag
//    *          the tag
//    * @param lemma
//    *          the lemma
//    * @return the morphological object
//    */
//   public final Morpheme createMorpheme(final String word, final String tag,
//       final String lemma) {
//     final Morpheme morpheme = new Morpheme();
//     morpheme.setValue(word);
//     morpheme.setTag(tag);
//     morpheme.setLemma(lemma);
//     return morpheme;
//   }
// 
// }


// Path: src/main/java/eus/ixa/ixa/pipe/lemma/StatisticalLemmatizer.java
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import eus.ixa.ixa.pipe.pos.Morpheme;
import eus.ixa.ixa.pipe.pos.MorphoFactory;

/*
 * Copyright 2016 Rodrigo Agerri

   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.
 */
package eus.ixa.ixa.pipe.lemma;




/**
 * Probabilistic lemmatizer.
 * 
 * @author ragerri
 * @version 2016-01-28
 */

public class StatisticalLemmatizer {

  /**
   * The lemmatizer.
   */
  private final LemmatizerME lemmatizer;
  /**
   * The models to use for every language. The keys of the hashmap are the language
   * codes, the values the models.
   */
  private final static ConcurrentHashMap<String, LemmatizerModel> lemmaModels = new ConcurrentHashMap<String, LemmatizerModel>();
  /**
   * The morpho factory.
   */
  private MorphoFactory morphoFactory;

  /**
   * Construct a statistical lemmatizer.
   * 
   * @param props
   *          the properties object
   */
  public StatisticalLemmatizer(final Properties props) {
    this(props, null);
  }

  /**
   * Construct a statistical lemmatizer with {@code MorphoFactory}.
   * 
   * @param props
   *          the properties object
   * @param aMorphoFactory
   *          the morpho factory
   */
  public StatisticalLemmatizer(final Properties props, final MorphoFactory aMorphoFactory) {