class EnglishForL2SpeakersFalseFriendRule extends ConfusionProbabilityRule {

  private static final Map<Language, List<AbstractPatternRule>> motherTongue2rules = new HashMap<>();

  private final Language lang;
  private final Language motherTongue;

  public EnglishForL2SpeakersFalseFriendRule(ResourceBundle messages, LanguageModel languageModel, Language motherTongue, Language lang)  {
    super(messages, languageModel, lang, 3);
    this.lang = Objects.requireNonNull(lang);
    this.motherTongue = Objects.requireNonNull(motherTongue);
  }

  private List<AbstractPatternRule> getRules() {<FILL_FUNCTION_BODY>}

  @Override
  protected String getMessage(ConfusionString textString, ConfusionString suggestion) {
    for (AbstractPatternRule rule : getRules()) {
      List<PatternToken> patternTokens = rule.getPatternTokens();
      for (PatternToken patternToken : patternTokens) {
        if (textString.getString().equals(patternToken.getString()) || isBaseformMatch(textString, patternToken)) {
          return rule.getMessage();
        }
      }
    }
    return super.getMessage(textString, suggestion);
  }

  private boolean isBaseformMatch(ConfusionString textString, PatternToken patternToken) {
    if (patternToken.isInflected()) {
      try {
        List<AnalyzedTokenReadings> readings = lang.getTagger().tag(Collections.singletonList(textString.getString()));
        for (AnalyzedTokenReadings reading : readings) {
          if (reading.getReadings().stream().anyMatch(k -> k.getLemma() != null && k.getLemma().equals(patternToken.getString()))) {
            return true;
          }
        }
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    return false;
  }
}

    synchronized (this) {
      if (!motherTongue2rules.containsKey(motherTongue)) {
        FalseFriendRuleLoader loader = new FalseFriendRuleLoader("\"{0}\" ({1}) means {2} ({3}).", "Did you maybe mean {0}?");
        try (InputStream is = JLanguageTool.getDataBroker().getFromRulesDirAsStream(JLanguageTool.FALSE_FRIEND_FILE)) {
          motherTongue2rules.put(motherTongue, loader.getRules(is, lang, motherTongue));
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
    return motherTongue2rules.get(motherTongue);
  
<methods>public void <init>(java.util.ResourceBundle, org.languagetool.languagemodel.LanguageModel, org.languagetool.Language) ,public void <init>(java.util.ResourceBundle, org.languagetool.languagemodel.LanguageModel, org.languagetool.Language, int) ,public void <init>(java.util.ResourceBundle, org.languagetool.languagemodel.LanguageModel, org.languagetool.Language, int, List<java.lang.String>) ,public void <init>(java.util.ResourceBundle, org.languagetool.languagemodel.LanguageModel, org.languagetool.Language, int, List<java.lang.String>, List<List<org.languagetool.rules.patterns.PatternToken>>) ,public int estimateContextForSureMatch() ,public List<org.languagetool.tagging.disambiguation.rules.DisambiguationPatternRule> getAntiPatterns() ,public java.lang.String getDescription() ,public java.lang.String getId() ,public int getNGrams() ,public org.languagetool.rules.RuleMatch[] match(org.languagetool.AnalyzedSentence) ,public void setConfusionPair(org.languagetool.rules.ConfusionPair) <variables>private static final boolean DEBUG,public static final float MIN_COVERAGE,private static final double MIN_PROB,private static final java.util.regex.Pattern REAL_WORD,public static final java.lang.String RULE_ID,private final non-sealed List<org.languagetool.tagging.disambiguation.rules.DisambiguationPatternRule> antiPatterns,private static final LoadingCache<org.languagetool.rules.ngrams.ConfusionProbabilityRule.PathAndLanguage,Map<java.lang.String,List<org.languagetool.rules.ConfusionPair>>> confSetCache,private final non-sealed List<java.lang.String> exceptions,private final non-sealed int grams,private final non-sealed org.languagetool.Language language,private final non-sealed org.languagetool.languagemodel.LanguageModel lm,private final Map<java.lang.String,List<org.languagetool.rules.ConfusionPair>> wordToPairs