class UnderlineSpacesFilter extends RuleFilter {

  /*
   * Underline the whitespaces before and/or after the marker in the pattern
   */
  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos,
                                   AnalyzedTokenReadings[] patternTokens, List<Integer> tokenPositions) throws IOException {<FILL_FUNCTION_BODY>}
}

    String underlineSpaces = getRequired("underlineSpaces", arguments); // before/after/both
    String sentence = match.getSentence().getText();
    if (underlineSpaces.equals("before") || underlineSpaces.equals("both")) {
      if (match.getFromPos() - 1 >= 0
        && StringTools.isWhitespace(sentence.substring(match.getFromPos() - 1, match.getFromPos()))) {
        match.setOffsetPosition(match.getFromPos() - 1, match.getToPos());
      }
    }
    if (underlineSpaces.equals("after") || underlineSpaces.equals("both")) {
      if (match.getToPos() + 1 < sentence.length()
        && StringTools.isWhitespace(sentence.substring(match.getToPos(), match.getToPos() + 1))) {
        match.setOffsetPosition(match.getFromPos(), match.getToPos() + 1);
      }
    }
    return match;
  
<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>