private @Nullable FList<TextRange> matchSkippingWords(int patternIndex,
                                            int nameIndex,
                                            boolean allowSpecialChars,
                                            @NotNull ErrorState errorState) {
      boolean wordStartsOnly = !isPatternChar(patternIndex - 1, '*', errorState) && !isWordSeparator(patternIndex, errorState);

      int maxFoundLength = 0;
      while (true) {
        nameIndex = findNextPatternCharOccurrence(nameIndex, patternIndex, allowSpecialChars, wordStartsOnly, errorState);
        if (nameIndex < 0) {
          return null;
        }
        Fragment fragment = seemsLikeFragmentStart(patternIndex, nameIndex, errorState) ? maxMatchingFragment(patternIndex, nameIndex, errorState) : null;
        if (fragment == null) continue;

        // 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
        int fragmentLength = fragment.getLength();
        if (fragmentLength > maxFoundLength || nameIndex + fragmentLength == myName.length() && isTrailingSpacePattern(errorState)) {
          if (!isMiddleMatch(patternIndex, nameIndex, errorState)) {
            maxFoundLength = fragmentLength;
          }
          FList<TextRange> ranges = matchInsideFragment(patternIndex, nameIndex, fragment);
          if (ranges != null) {
            return ranges;
          }
        }
      }
    }
private @Nullable FList<TextRange> matchSkippingWords(int patternIndex,
                                            int nameIndex,
                                            boolean allowSpecialChars,
                                            @NotNull ErrorState errorState)