public static void copyDir(
     @NotNull File fromDir, @NotNull File toDir, @Nullable final FileFilter filter)
     throws IOException {
   ensureExists(toDir);
   if (isAncestor(fromDir, toDir, true)) {
     LOG.error(fromDir.getAbsolutePath() + " is ancestor of " + toDir + ". Can't copy to itself.");
     return;
   }
   File[] files = fromDir.listFiles();
   if (files == null)
     throw new IOException(
         CommonBundle.message("exception.directory.is.invalid", fromDir.getPath()));
   if (!fromDir.canRead())
     throw new IOException(
         CommonBundle.message("exception.directory.is.not.readable", fromDir.getPath()));
   for (File file : files) {
     if (filter != null && !filter.accept(file)) {
       continue;
     }
     if (file.isDirectory()) {
       copyDir(file, new File(toDir, file.getName()), filter);
     } else {
       copy(file, new File(toDir, file.getName()));
     }
   }
 }
 private static FileOutputStream openOutputStream(@NotNull final File file) throws IOException {
   try {
     return new FileOutputStream(file);
   } catch (FileNotFoundException e) {
     final File parentFile = file.getParentFile();
     if (parentFile == null) {
       throw new IOException("Parent file is null for " + file.getPath(), e);
     }
     createParentDirs(file);
     return new FileOutputStream(file);
   }
 }
  private static void performCopy(
      @NotNull File fromFile, @NotNull File toFile, final boolean syncTimestamp)
      throws IOException {
    final FileOutputStream fos;
    try {
      fos = openOutputStream(toFile);
    } catch (IOException e) {
      if (SystemInfo.isWindows
          && e.getMessage() != null
          && e.getMessage().contains("denied")
          && WinUACTemporaryFix.nativeCopy(fromFile, toFile, syncTimestamp)) {
        return;
      }
      throw e;
    }

    try {
      final FileInputStream fis = new FileInputStream(fromFile);
      try {
        copy(fis, fos);
      } finally {
        fis.close();
      }
    } finally {
      fos.close();
    }

    if (syncTimestamp) {
      final long timeStamp = fromFile.lastModified();
      if (timeStamp < 0) {
        LOG.warn("Invalid timestamp " + timeStamp + " of '" + fromFile + "'");
      } else if (!toFile.setLastModified(timeStamp)) {
        LOG.warn("Unable to set timestamp " + timeStamp + " to '" + toFile + "'");
      }
    }

    if (SystemInfo.isUnix && fromFile.canExecute()) {
      FileSystemUtil.clonePermissions(fromFile.getPath(), toFile.getPath());
    }
  }
  /**
   * Returns empty string for empty path. First checks whether provided path is a path of a file
   * with sought-for name. Unless found, checks if provided file was a directory. In this case
   * checks existence of child files with given names in order "as provided". Finally checks
   * filename among brother-files of provided. Returns null if nothing found.
   *
   * @return path of the first of found files or empty string or null.
   */
  @Nullable
  public static String findFileInProvidedPath(String providedPath, String... fileNames) {
    if (StringUtil.isEmpty(providedPath)) {
      return "";
    }

    File providedFile = new File(providedPath);
    if (providedFile.exists()) {
      String name = providedFile.getName();
      for (String fileName : fileNames) {
        if (name.equals(fileName)) {
          return toSystemDependentName(providedFile.getPath());
        }
      }
    }

    if (providedFile.isDirectory()) { // user chose folder with file
      for (String fileName : fileNames) {
        File file = new File(providedFile, fileName);
        if (fileName.equals(file.getName()) && file.exists()) {
          return toSystemDependentName(file.getPath());
        }
      }
    }

    providedFile = providedFile.getParentFile(); // users chose wrong file in same directory
    if (providedFile != null && providedFile.exists()) {
      for (String fileName : fileNames) {
        File file = new File(providedFile, fileName);
        if (fileName.equals(file.getName()) && file.exists()) {
          return toSystemDependentName(file.getPath());
        }
      }
    }

    return null;
  }
  private static File getOldPath(
      final File oldInstallHome,
      final ConfigImportSettings settings,
      final String propertyName,
      final Function<String, String> fromPathSelector) {
    final File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome, settings);

    // custom config folder
    for (File candidate : launchFileCandidates) {
      if (candidate.exists()) {
        String configDir =
            PathManager.substituteVars(
                getPropertyFromLaxFile(candidate, propertyName), oldInstallHome.getPath());
        if (configDir != null) {
          File probableConfig = new File(configDir);
          if (probableConfig.exists()) return probableConfig;
        }
      }
    }

    // custom config folder not found - use paths selector
    for (File candidate : launchFileCandidates) {
      if (candidate.exists()) {
        final String pathsSelector =
            getPropertyFromLaxFile(candidate, PathManager.PROPERTY_PATHS_SELECTOR);
        if (pathsSelector != null) {
          final String configDir = fromPathSelector.fun(pathsSelector);
          final File probableConfig = new File(configDir);
          if (probableConfig.exists()) {
            return probableConfig;
          }
        }
      }
    }

    return null;
  }
 public static int fileHashCode(@Nullable File file) {
   return pathHashCode(file == null ? null : file.getPath());
 }
 public static int compareFiles(@Nullable File file1, @Nullable File file2) {
   return comparePaths(
       file1 == null ? null : file1.getPath(), file2 == null ? null : file2.getPath());
 }
 public static boolean filesEqual(@Nullable File file1, @Nullable File file2) {
   // on MacOS java.io.File.equals() is incorrectly case-sensitive
   return pathsEqual(
       file1 == null ? null : file1.getPath(), file2 == null ? null : file2.getPath());
 }
 public static void ensureExists(@NotNull File dir) throws IOException {
   if (!dir.exists() && !dir.mkdirs()) {
     throw new IOException(
         CommonBundle.message("exception.directory.can.not.create", dir.getPath()));
   }
 }
 public static boolean isRootPath(@NotNull File file) {
   return isRootPath(file.getPath());
 }
 public static void setLastModified(@NotNull File file, long timeStamp) throws IOException {
   if (!file.setLastModified(timeStamp)) {
     LOG.warn(file.getPath());
   }
 }
 /**
  * Check if the {@code ancestor} is an ancestor of {@code file}.
  *
  * @param ancestor supposed ancestor.
  * @param file supposed descendant.
  * @param strict if {@code false} then this method returns {@code true} if {@code ancestor} equals
  *     to {@code file}.
  * @return {@code true} if {@code ancestor} is parent of {@code file}; {@code false} otherwise.
  */
 public static boolean isAncestor(@NotNull File ancestor, @NotNull File file, boolean strict) {
   return isAncestor(ancestor.getPath(), file.getPath(), strict);
 }