@Nullable
  private static File findOldConfigDir(
      @NotNull File configDir, @Nullable String customPathSelector) {
    final File selectorDir = CONFIG_RELATED_PATH.isEmpty() ? configDir : configDir.getParentFile();
    final File parent = selectorDir.getParentFile();
    if (parent == null || !parent.exists()) {
      return null;
    }
    File maxFile = null;
    long lastModified = 0;
    final String selector =
        PathManager.getPathsSelector() != null
            ? PathManager.getPathsSelector()
            : selectorDir.getName();

    final String prefix = getPrefixFromSelector(selector);
    final String customPrefix =
        customPathSelector != null ? getPrefixFromSelector(customPathSelector) : null;
    for (File file :
        parent.listFiles(
            new FilenameFilter() {
              @Override
              public boolean accept(@NotNull File file, @NotNull String name) {
                return StringUtil.startsWithIgnoreCase(name, prefix)
                    || customPrefix != null && StringUtil.startsWithIgnoreCase(name, customPrefix);
              }
            })) {
      File options = new File(file, CONFIG_RELATED_PATH + OPTIONS_XML);
      if (!options.exists()) {
        continue;
      }

      long modified = options.lastModified();
      if (modified > lastModified) {
        lastModified = modified;
        maxFile = file;
      }
    }
    return maxFile != null ? new File(maxFile, CONFIG_RELATED_PATH) : null;
  }
  public void load(String path) throws IOException, InvalidDataException {
    getStateStore().setOptionsPath(path);
    getStateStore().setConfigPath(PathManager.getConfigPath());
    myIsFiringLoadingEvent = true;
    try {
      fireBeforeApplicationLoaded();
    } finally {
      myIsFiringLoadingEvent = false;
    }

    loadComponentRoamingTypes();

    try {
      getStateStore().load();
    } catch (StateStorage.StateStorageException e) {
      throw new IOException(e.getMessage());
    }
  }
  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;
  }
  private static void copy(
      @NotNull File src,
      @NotNull File dest,
      ConfigImportSettings settings,
      File oldInstallationHome)
      throws IOException {
    src = src.getCanonicalFile();
    dest = dest.getCanonicalFile();
    if (!src.isDirectory()) {
      throw new IOException(
          ApplicationBundle.message(
              "config.import.invalid.directory.error", src.getAbsolutePath()));
    }
    if (!dest.isDirectory()) {
      throw new IOException(
          ApplicationBundle.message(
              "config.import.invalid.directory.error", dest.getAbsolutePath()));
    }
    if (FileUtil.filesEqual(src, dest)) {
      return;
    }

    FileUtil.ensureExists(dest);

    File[] childFiles =
        src.listFiles(
            new FilenameFilter() {
              @Override
              public boolean accept(@NotNull File dir, @NotNull String name) {
                // Don't copy plugins just imported. They're most probably incompatible with newer
                // idea version.
                return !StringUtil.startsWithChar(name, '.') && !name.equals(PLUGINS_PATH);
              }
            });

    if (childFiles == null || childFiles.length == 0) {
      return;
    }

    for (File from : childFiles) {
      File to = new File(dest, from.getName());
      if (from.isDirectory()) {
        FileUtil.copyDir(from, to, false);
      } else {
        FileUtil.copy(from, to);
      }
    }

    File plugins = new File(src, PLUGINS_PATH);
    if (!loadOldPlugins(plugins, dest) && SystemInfo.isMac) {
      File oldPluginsDir =
          getOldPath(
              oldInstallationHome,
              settings,
              PathManager.PROPERTY_PLUGINS_PATH,
              new Function<String, String>() {
                @Override
                public String fun(String pathSelector) {
                  return PathManager.getDefaultPluginPathFor(pathSelector);
                }
              });
      if (oldPluginsDir == null) {
        // e.g. installation home referred to config home. Try with default selector, same as config
        // name
        oldPluginsDir = new File(PathManager.getDefaultPluginPathFor(src.getName()));
      }
      loadOldPlugins(oldPluginsDir, dest);
    }
  }