private @Nullable FList<TextRange> matchSkippingWords(@NotNull String name,
                                              final int patternIndex,
                                              int nameIndex,
                                              boolean allowSpecialChars,
                                              boolean isAsciiName) {
    int maxFoundLength = 0;
    while (nameIndex >= 0) {
      int fragmentLength = seemsLikeFragmentStart(name, patternIndex, nameIndex) ? maxMatchingFragment(name, patternIndex, nameIndex) : 0;

      // match the remaining pattern only if we haven't already seen fragment of the same (or bigger) length
      // because otherwise it means that we already tried to match remaining pattern letters after it with the remaining name and failed
      // but now we have the same remaining pattern letters and even less remaining name letters, and so will fail as well
      if (fragmentLength > maxFoundLength || nameIndex + fragmentLength == name.length() && isTrailingSpacePattern()) {
        if (!isMiddleMatch(name, patternIndex, nameIndex)) {
          maxFoundLength = fragmentLength;
        }
        FList<TextRange> ranges = matchInsideFragment(name, patternIndex, nameIndex, isAsciiName, fragmentLength);
        if (ranges != null) {
          return ranges;
        }
      }
      int next = findNextPatternCharOccurrence(name, nameIndex + 1, patternIndex, isAsciiName);
      nameIndex = allowSpecialChars ? next : checkForSpecialChars(name, nameIndex + 1, next, patternIndex);
    }
    return null;
  }
private @Nullable FList<TextRange> matchSkippingWords(@NotNull String name,
                                              final int patternIndex,
                                              int nameIndex,
                                              boolean allowSpecialChars,
                                              boolean isAsciiName)