@ApiStatus.Experimental
  public static boolean isAncestorOrSelf(@NotNull @SystemIndependent String ancestorPath, @NotNull VirtualFile file) {
    ancestorPath = FileUtil.toCanonicalPath(ancestorPath);
    if (ancestorPath.isEmpty()) {
      return true;
    }
    List<VirtualFile> hierarchy = getHierarchy(file);
    int i = 0;
    boolean result = false;
    int j;
    for (j = hierarchy.size() - 1; j >= 0; j--) {
      VirtualFile part = hierarchy.get(j);
      String name = part.getName();
      boolean matches = part.isCaseSensitive() ? StringUtil.startsWith(ancestorPath, i, name) :
                        StringUtilRt.startsWithIgnoreCase(ancestorPath, i, name);
      if (!matches) {
        break;
      }
      i += name.length();
      if (!name.endsWith("/")) {
        if (i != ancestorPath.length() && ancestorPath.charAt(i) != '/') {
          break;
        }
        i++;
      }
      if (i >= ancestorPath.length()) {
        result = true;
        break;
      }
    }
    return result;
  }
@ApiStatus.Experimental
  public static boolean isAncestorOrSelf(@NotNull @SystemIndependent String ancestorPath, @NotNull VirtualFile file)