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

    String prefix = matchPrefix(text, path, caseSensitive);
    if (prefix == null) {
      return text;
    }

    //check that this is complete path (ends with "/" or "!/")
    // do not collapse partial paths, i.e., do not substitute "/a/b/cd" in paths like "/a/b/cdeFgh"
    int endOfOccurrence = prefix.length() + path.length();
    final boolean isWindowsRoot = path.endsWith(":/");
    if (!isWindowsRoot &&
        endOfOccurrence < text.length() &&
        text.charAt(endOfOccurrence) != '/' &&
        !(text.charAt(endOfOccurrence) == '!' && text.substring(endOfOccurrence).startsWith("!/"))) {
      return text;
    }

    String s = myMacroMap.get(path);
    if (text.length() > endOfOccurrence) {
      return prefix + s + text.substring(endOfOccurrence);
    }
    else {
      return prefix + s;
    }
  }
private @NotNull String replacePathMacro(@NotNull String text, final @NotNull String path, boolean caseSensitive)