private CharSequence replacePathMacroRecursively(@NotNull CharSequence text, @NotNull String path, boolean caseSensitive) {
    if ((text.length() < path.length()) || path.isEmpty()) {
      return text;
    }

    StringBuilder newText = new StringBuilder();
    boolean isWindowsRoot = path.endsWith(":/");
    int i = 0;
    while (i < text.length()) {
      int occurrenceOfPath = caseSensitive ? Strings.indexOf(text, path, i) : Strings.indexOfIgnoreCase(text, path, i);
      if (occurrenceOfPath >= 0) {
        int endOfOccurrence = occurrenceOfPath + path.length();
        if (!isWindowsRoot &&
            endOfOccurrence < text.length() &&
            text.charAt(endOfOccurrence) != '/' &&
            text.charAt(endOfOccurrence) != '\"' &&
            text.charAt(endOfOccurrence) != ' ' &&
            !Strings.startsWith(text, endOfOccurrence, "!/")) {
          newText.append(text, i, endOfOccurrence);
          i = endOfOccurrence;
          continue;
        }
        if (occurrenceOfPath > 0) {
          char prev = text.charAt(occurrenceOfPath - 1);
          if (Character.isLetterOrDigit(prev) || prev == '_') {
            newText.append(text, i, endOfOccurrence);
            i = endOfOccurrence;
            continue;
          }
        }
      }
      if (occurrenceOfPath < 0) {
        if (newText.isEmpty()) {
          return text;
        }
        newText.append(text, i, text.length());
        break;
      }
      else {
        newText.append(text, i, occurrenceOfPath);
        newText.append(myMacroMap.get(path));
        i = occurrenceOfPath + path.length();
      }
    }
    return newText;
  }
private CharSequence replacePathMacroRecursively(@NotNull CharSequence text, @NotNull String path, boolean caseSensitive)