class PossessiusRedundantsFilter extends RuleFilter {

  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos,
                                   AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) throws IOException {<FILL_FUNCTION_BODY>}
}

    AnalyzedTokenReadings[] tokens = match.getSentence().getTokensWithoutWhitespace();
    int posPossessive = patternTokenPos;
    while (posPossessive < tokens.length && !tokens[posPossessive].hasPartialPosTag("PX")) {
      posPossessive++;
    }
    String possessivePostag = tokens[posPossessive].readingWithTagRegex("PX.*").getPOSTag();
    String number = possessivePostag.substring(6,7);
    String persona = possessivePostag.substring(2,3);
    int posVerb = patternTokenPos - 1;
    while (posVerb > 0 && tokens[posVerb].getChunkTags().stream().anyMatch(x -> x.getChunkTag().equals("GV"))) {
      posVerb--;
    }
    posVerb++;
    boolean pronounFound = false;
    boolean hasSomePronoun = false;
    // pronom enrere
    int posPronoun = posVerb - 1;
    while (!pronounFound && posPronoun > 0 && tokens[posPronoun].hasPosTagStartingWith("P")) {
      hasSomePronoun = true;
      String pronounPostag = tokens[posPronoun].readingWithTagRegex("P.*").getPOSTag();
      pronounFound = pronounPostag.substring(2,3).equals(persona) && (number.equals("C") || pronounPostag.substring(4,5).equals(number));
      posPronoun--;
    }
    //pronom avant
    posPronoun = patternTokenPos + 1;
    while (!pronounFound && posPronoun < tokens.length && tokens[posPronoun].hasPosTagStartingWith("P")) {
      hasSomePronoun = true;
      String pronounPostag = tokens[posPronoun].readingWithTagRegex("P.*").getPOSTag();
      pronounFound = pronounPostag.substring(2,3).equals(persona) && (number.equals("C") || pronounPostag.substring(4,5).equals(number));
      posPronoun++;
    }
    // Cal apostrofar
    boolean apostropheNeeded = tokens[posPossessive-1].hasAnyPartialPosTag("DA0MS0", "DA0FS0")
      && pApostropheNeeded.matcher(tokens[posPossessive + 1].getToken()).matches();
    if (pronounFound) {
      if (apostropheNeeded) {
        match.setOffsetPosition(tokens[posPossessive-1].getStartPos(), tokens[posPossessive+1].getEndPos());
        match.setSuggestedReplacement("l'" + tokens[posPossessive+1].getToken());
      } else {
        match.setOffsetPosition(tokens[posPossessive].getStartPos(), tokens[posPossessive].getEndPos());
        match.setSuggestedReplacement("");
      }
      return match;
    }
    if (!hasSomePronoun) {
      StringBuilder suggestion = new StringBuilder();
      if (tokens[posVerb].hasAnyPartialPosTag("VMN", "VMG")) {
        String pronounSugg = transformDarrere(dativePronoun.get(persona + number), tokens[posVerb].getToken());
        suggestion.append(tokens[posVerb].getToken());
        suggestion.append(pronounSugg);
      } else {
        String pronounSugg = transformDavant(dativePronoun.get(persona + number), tokens[posVerb].getToken());
        suggestion.append(StringTools.preserveCase(pronounSugg, tokens[posVerb].getToken()));
        suggestion.append(tokens[posVerb].getToken().toLowerCase());
      }
      for (int i = posVerb + 1; i <= posPossessive - 2; i++) {
        if (tokens[i].isWhitespaceBefore()) {
          suggestion.append(" ");
        }
        suggestion.append(tokens[i].getToken().toLowerCase());
      }
      if (apostropheNeeded) {
        suggestion.append(" ");
        suggestion.append("l'" + tokens[posPossessive+1].getToken());
      } else {
        for (int i = posPossessive - 1; i <= posPossessive + 1; i++) {
          if (i == posPossessive) {
            continue;
          }
          if (tokens[i].isWhitespaceBefore()) {
            suggestion.append(" ");
          }
          suggestion.append(tokens[i].getToken());
        }
      }
      match.setOffsetPosition(tokens[posVerb].getStartPos(), tokens[posPossessive + 1].getEndPos());
      match.setSuggestedReplacement(suggestion.toString());
      return match;
    }
    return null;
  
<methods>public non-sealed void <init>() ,public abstract org.languagetool.rules.RuleMatch acceptRuleMatch(org.languagetool.rules.RuleMatch, Map<java.lang.String,java.lang.String>, int, org.languagetool.AnalyzedTokenReadings[], List<java.lang.Integer>) throws java.io.IOException,public boolean matches(Map<java.lang.String,java.lang.String>, org.languagetool.AnalyzedTokenReadings[], int, List<java.lang.Integer>) throws java.io.IOException<variables>