@Nullable
  DirectoryPathMatcher appendChar(char c) {
    String nextPattern = dirPattern + c;
    if (c == '*' || c == '/' || c == ' ') return new DirectoryPathMatcher(myModel, myFiles, nextPattern);

    List<Pair<VirtualFile, String>> files = getMatchingRoots();

    List<Pair<VirtualFile, String>> nextRoots = new ArrayList<>();
    MinusculeMatcher matcher = GotoFileItemProvider.getQualifiedNameMatcher(nextPattern);
    for (Pair<VirtualFile, String> pair : files) {
      if (containsChar(pair.second, c) && matcher.matches(pair.second)) {
        nextRoots.add(pair);
      } else {
        processProjectFilesUnder(pair.first, sub -> {
          if (!sub.isDirectory()) return false;
          if (!containsChar(sub.getNameSequence(), c)) return true; //go deeper

          String fullName = pair.second + '/' + VfsUtilCore.getRelativePath(sub, pair.first, '/');
          if (matcher.matches(fullName)) {
            nextRoots.add(Pair.create(sub, fullName));
            return false;
          }
          return true;
        });
      }
    }

    return nextRoots.isEmpty() ? null : new DirectoryPathMatcher(myModel, nextRoots, nextPattern);
  }
@Nullable
  DirectoryPathMatcher appendChar(char c)