package org.languagetool.synthesis;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import morfologik.stemming.Dictionary;
import morfologik.stemming.DictionaryLookup;
import morfologik.stemming.IStemmer;
import morfologik.stemming.WordData;

import org.languagetool.AnalyzedToken;
import org.languagetool.tools.Tools;

public class BaseSynthesizer implements Synthesizer {
 
  protected IStemmer synthesizer;

  private ArrayList<String> possibleTags;
  private final String tagFileName;
  private final String resourceFileName;
  
  public BaseSynthesizer(final String resourceFileName, final String tagFileName) {
    this.resourceFileName = resourceFileName;  
    this.tagFileName = tagFileName;
  }
  
  /**
   * Get a form of a given AnalyzedToken, where the form is defined by a
   * part-of-speech tag.
   * 
   * @param token
   *          AnalyzedToken to be inflected.
   * @param posTag
   *          The desired part-of-speech tag.
   * @return String value - inflected word.
   */
  @Override
  public String[] synthesize(final AnalyzedToken token, final String posTag) throws IOException {
    initSynthesizer();
    final List<WordData> wordData = synthesizer.lookup(token.getLemma() + "|" + posTag);
    final List<String> wordForms = new ArrayList<String>();
    for (WordData wd : wordData) {
      wordForms.add(wd.getStem().toString());
    }
    return wordForms.toArray(new String[wordForms.size()]);
  }
      
  @Override
  public String[] synthesize(final AnalyzedToken token, final String posTag,
      final boolean posTagRegExp) throws IOException {
    if (posTagRegExp) {
      if (possibleTags == null) {
        possibleTags = SynthesizerTools.loadWords(Tools.getStream(tagFileName));
      }
      initSynthesizer();
      final Pattern p = Pattern.compile(posTag);
      final ArrayList<String> results = new ArrayList<String>();
      for (final String tag : possibleTags) {
        final Matcher m = p.matcher(tag);
        if (m.matches()) {
          final List<WordData> wordForms = synthesizer.lookup(token.getLemma() + "|" + tag);
          for (WordData wd : wordForms) {
            results.add(wd.getStem().toString());
          }
        }
      }
      return results.toArray(new String[results.size()]);
    }
    return synthesize(token, posTag);
  }

  private void initSynthesizer() throws IOException {
    if (synthesizer == null) {
      final URL url = this.getClass().getResource(resourceFileName);
      synthesizer = new DictionaryLookup(Dictionary.read(url));
    }
  }

  @Override
  public String getPosTagCorrection(final String posTag) {
    return posTag;
  }

}

@@ -815,16 +815,508 @@
 ame;%0A  %7D
+%0A%0A  /**%0A   * Lookup the inflected forms of a lemma defined by a part-of-speech tag.%0A   * @param lemma the lemma to be inflected.%0A   * @param posTag the desired part-of-speech tag.%0A   * @param results the list to collect the inflected forms.%0A   */%0A  protected void lookup(String lemma, String posTag, List%3CString%3E results) %7B%0A    final List%3CWordData%3E wordForms = synthesizer.lookup(lemma + %22%7C%22 + posTag);%0A    for (WordData wd : wordForms) %7B%0A      results.add(wd.getStem().toString());%0A    %7D%0A  %7D
 %0A  %0A  /*
@@ -1751,228 +1751,101 @@
 ist%3C
-WordData%3E wordData = synthesizer.lookup(token.getLemma() + %22%7C%22 + posTag);%0A    final List%3CString%3E wordForms = new ArrayList%3CString%3E();%0A    for (WordData wd : wordData) %7B%0A      wordForms.add(wd.getStem().toString());%0A    %7D
+String%3E wordForms = new ArrayList%3CString%3E();%0A    lookup(token.getLemma(), posTag, wordForms);
 %0A   
@@ -2471,194 +2471,47 @@
     
-final List%3CWordData%3E wordForms = synthesizer.lookup(token.getLemma() + %22%7C%22 + tag);%0A          for (WordData wd : wordForms) %7B%0A            results.add(wd.getStem().toString());%0A          %7D
+lookup(token.getLemma(), tag, results);
 %0A   
@@ -2636,21 +2636,23 @@
  %7D%0A%0A  pr
-ivate
+otected
  void in

refactor BaseSynthesizer to allow extension . No functional change.