class TokenHint {
    final boolean inflected;
    final String[] lowerCaseValues;
    final int tokenIndex;

    private TokenHint(boolean inflected, Set<String> possibleValues, int tokenIndex) {
      this.inflected = inflected;
      this.tokenIndex = tokenIndex;
      lowerCaseValues = possibleValues.stream().map(String::toLowerCase).distinct().toArray(String[]::new);
    }

    @Override
    public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public int hashCode() {
      return Objects.hash(inflected, tokenIndex, Arrays.hashCode(lowerCaseValues));
    }

    /**
     * @return all indices inside sentence's non-blank tokens where this token could possibly match
     */
    List<Integer> getPossibleIndices(AnalyzedSentence sentence) {
      boolean needMerge = false;
      List<Integer> result = null;
      for (String hint : lowerCaseValues) {
        List<Integer> hintIndices = getHintIndices(sentence, hint);
        if (hintIndices != null) {
          if (result == null) {
            result = hintIndices;
          } else {
            if (!needMerge) {
              result = new ArrayList<>(result);
              needMerge = true;
            }
            result.addAll(hintIndices);
          }
        }
      }
      if (result == null) return Collections.emptyList();
      return needMerge ? new ArrayList<>(new TreeSet<>(result)) : result;
    }

    private boolean canBeIgnoredFor(AnalyzedSentence sentence) {
      for (String hint : lowerCaseValues) {
        if (getHintIndices(sentence, hint) != null) {
          return false;
        }
      }
      return true;
    }

    @Nullable
    private List<Integer> getHintIndices(AnalyzedSentence sentence, String hint) {
      return inflected ? sentence.getLemmaOffsets(hint) : sentence.getTokenOffsets(hint);
    }
  }

      if (this == o) return true;
      if (!(o instanceof TokenHint)) return false;
      TokenHint tokenHint = (TokenHint) o;
      return inflected == tokenHint.inflected &&
             tokenIndex == tokenHint.tokenIndex &&
             Arrays.equals(lowerCaseValues, tokenHint.lowerCaseValues);
    
<methods>public void <init>(java.lang.String, java.lang.String, org.languagetool.Language, List<org.languagetool.rules.patterns.PatternToken>, boolean, java.lang.String) ,public void <init>(java.lang.String, java.lang.String, org.languagetool.Language, List<org.languagetool.rules.patterns.PatternToken>, boolean) ,public final void addSuggestionMatch(org.languagetool.rules.patterns.Match) ,public final void addSuggestionMatchOutMsg(org.languagetool.rules.patterns.Match) ,public final List<org.languagetool.tagging.disambiguation.rules.DisambiguationPatternRule> getAntiPatterns() ,public java.lang.String getDescription() ,public final int getEndPositionCorrection() ,public org.languagetool.rules.patterns.RuleFilter getFilter() ,public java.lang.String getFilterArguments() ,public java.lang.String getFullId() ,public java.lang.String getId() ,public final org.languagetool.Language getLanguage() ,public final java.lang.String getMessage() ,public org.languagetool.rules.patterns.PatternRuleId getPatternRuleId() ,public List<org.languagetool.rules.patterns.PatternToken> getPatternTokens() ,public java.lang.String getSourceFile() ,public final int getStartPositionCorrection() ,public final java.lang.String getSubId() ,public final java.lang.String getSuggestionsOutMsg() ,public org.languagetool.rules.RuleMatch.Type getType() ,public int getXmlLineNumber() ,public boolean isAdjustSuggestionCase() ,public boolean isGetUnified() ,public boolean isGroupsOrUnification() ,public boolean isSentStart() ,public boolean isTestUnification() ,public org.languagetool.rules.RuleMatch[] match(org.languagetool.AnalyzedSentence) throws java.io.IOException,public void setAdjustSuggestionCase(boolean) ,public void setAntiPatterns(List<org.languagetool.tagging.disambiguation.rules.DisambiguationPatternRule>) ,public final void setEndPositionCorrection(int) ,public void setFilter(org.languagetool.rules.patterns.RuleFilter) ,public void setFilterArguments(java.lang.String) ,public final void setMessage(java.lang.String) ,public final void setStartPositionCorrection(int) ,public final void setSubId(java.lang.String) ,public void setType(org.languagetool.rules.RuleMatch.Type) ,public void setXmlLineNumber(int) ,public boolean supportsLanguage(org.languagetool.Language) ,public java.lang.String toString() <variables>private boolean adjustSuggestionCase,protected List<org.languagetool.tagging.disambiguation.rules.DisambiguationPatternRule> antiPatterns,private final non-sealed java.lang.String description,protected int endPositionCorrection,protected org.languagetool.rules.patterns.RuleFilter filter,protected java.lang.String filterArgs,private final non-sealed boolean getUnified,private final non-sealed boolean groupsOrUnification,private final non-sealed java.lang.String id,protected final non-sealed org.languagetool.Language language,private int lineNumber,protected java.lang.String message,protected final non-sealed List<org.languagetool.rules.patterns.PatternToken> patternTokens,protected final non-sealed boolean sentStart,protected java.lang.String sourceFile,protected int startPositionCorrection,protected java.lang.String subId,protected List<org.languagetool.rules.patterns.Match> suggestionMatches,protected List<org.languagetool.rules.patterns.Match> suggestionMatchesOutMsg,protected java.lang.String suggestionsOutMsg,protected final non-sealed boolean testUnification,protected org.languagetool.rules.RuleMatch.Type type