/**
  * Copies content of {@code fromDir} to {@code toDir}. It's equivalent to "cp -r fromDir/* toDir"
  * unix command.
  *
  * @param fromDir source directory
  * @param toDir destination directory
  * @throws IOException in case of any IO troubles
  */
 public static void copyDirContent(@NotNull File fromDir, @NotNull File toDir) throws IOException {
   File[] children = ObjectUtils.notNull(fromDir.listFiles(), ArrayUtil.EMPTY_FILE_ARRAY);
   for (File child : children) {
     File target = new File(toDir, child.getName());
     if (child.isFile()) {
       copy(child, target);
     } else {
       copyDir(child, target, true);
     }
   }
 }
 public GitLogProvider(
     @NotNull Project project,
     @NotNull GitRepositoryManager repositoryManager,
     @NotNull VcsLogObjectsFactory factory,
     @NotNull GitUserRegistry userRegistry) {
   myProject = project;
   myRepositoryManager = repositoryManager;
   myUserRegistry = userRegistry;
   myRefSorter = new GitRefManager(myRepositoryManager);
   myVcsObjectsFactory = factory;
   myVcs = ObjectUtils.assertNotNull(GitVcs.getInstance(project));
 }
    protected boolean isEnabled(CRaSHPlugin<?> plugin) {
      Assert.notNull(plugin, "Plugin must not be null");

      if (ObjectUtils.isEmpty(this.disabledPlugins)) {
        return true;
      }

      Set<Class<?>> pluginClasses = ClassUtils.getAllInterfacesAsSet(plugin);
      pluginClasses.add(plugin.getClass());

      for (Class<?> pluginClass : pluginClasses) {
        if (isEnabled(pluginClass)) {
          return true;
        }
      }
      return false;
    }
  @NotNull
  @Override
  public DetailedLogData readFirstBlock(
      @NotNull VirtualFile root, @NotNull Requirements requirements) throws VcsException {
    if (!isRepositoryReady(root)) {
      return LogDataImpl.empty();
    }
    GitRepository repository =
        ObjectUtils.assertNotNull(myRepositoryManager.getRepositoryForRoot(root));

    // need to query more to sort them manually; this doesn't affect performance: it is equal for
    // -1000 and -2000
    int commitCount = requirements.getCommitCount() * 2;

    String[] params =
        new String[] {"HEAD", "--branches", "--remotes", "--max-count=" + commitCount};
    // NB: not specifying --tags, because it introduces great slowdown if there are many tags,
    // but makes sense only if there are heads without branch or HEAD labels (rare case). Such cases
    // are partially handled below.

    boolean refresh =
        requirements instanceof VcsLogProviderRequirementsEx
            && ((VcsLogProviderRequirementsEx) requirements).isRefresh();

    DetailedLogData data = GitHistoryUtils.loadMetadata(myProject, root, true, params);

    Set<VcsRef> safeRefs = data.getRefs();
    Set<VcsRef> allRefs = new OpenTHashSet<VcsRef>(safeRefs, DONT_CONSIDER_SHA);
    Set<VcsRef> branches = readBranches(repository);
    addNewElements(allRefs, branches);

    Collection<VcsCommitMetadata> allDetails;
    Set<String> currentTagNames = null;
    DetailedLogData commitsFromTags = null;
    if (!refresh) {
      allDetails = data.getCommits();
    } else {
      // on refresh: get new tags, which point to commits not from the first block; then get
      // history, walking down just from these tags
      // on init: just ignore such tagged-only branches. The price for speed-up.
      VcsLogProviderRequirementsEx rex = (VcsLogProviderRequirementsEx) requirements;

      currentTagNames = readCurrentTagNames(root);
      addOldStillExistingTags(allRefs, currentTagNames, rex.getPreviousRefs());

      allDetails = newHashSet(data.getCommits());

      Set<String> previousTags =
          newHashSet(ContainerUtil.mapNotNull(rex.getPreviousRefs(), GET_TAG_NAME));
      Set<String> safeTags = newHashSet(ContainerUtil.mapNotNull(safeRefs, GET_TAG_NAME));
      Set<String> newUnmatchedTags = remove(currentTagNames, previousTags, safeTags);

      if (!newUnmatchedTags.isEmpty()) {
        commitsFromTags = loadSomeCommitsOnTaggedBranches(root, commitCount, newUnmatchedTags);
        addNewElements(allDetails, commitsFromTags.getCommits());
        addNewElements(allRefs, commitsFromTags.getRefs());
      }
    }

    StopWatch sw = StopWatch.start("sorting commits in " + root.getName());
    List<VcsCommitMetadata> sortedCommits = VcsLogSorter.sortByDateTopoOrder(allDetails);
    sortedCommits =
        sortedCommits.subList(0, Math.min(sortedCommits.size(), requirements.getCommitCount()));
    sw.report();

    if (LOG.isDebugEnabled()) {
      validateDataAndReportError(
          root, allRefs, sortedCommits, data, branches, currentTagNames, commitsFromTags);
    }

    return new LogDataImpl(allRefs, sortedCommits);
  }
  private void doImportAction(final DataContext dataContext) {
    final FileChooserDescriptor descriptor =
        new FileChooserDescriptor(true, false, true, false, true, false) {
          @Override
          public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
            return super.isFileVisible(file, showHiddenFiles)
                && (file.isDirectory()
                    || "xml".equals(file.getExtension())
                    || file.getFileType() == FileTypes.ARCHIVE);
          }

          @Override
          public boolean isFileSelectable(VirtualFile file) {
            return file.getFileType() == StdFileTypes.XML;
          }
        };
    descriptor.setDescription(
        "Please select the configuration file (usually named IntelliLang.xml) to import.");
    descriptor.setTitle("Import Configuration");

    descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, LangDataKeys.MODULE.getData(dataContext));

    final SplitterProportionsData splitterData = new SplitterProportionsDataImpl();
    splitterData.externalizeFromDimensionService(
        "IntelliLang.ImportSettingsKey.SplitterProportions");

    final VirtualFile file = FileChooser.chooseFile(descriptor, myProject, null);
    if (file == null) return;
    try {
      final Configuration cfg = Configuration.load(file.getInputStream());
      if (cfg == null) {
        Messages.showWarningDialog(
            myProject,
            "The selected file does not contain any importable configuration.",
            "Nothing to Import");
        return;
      }
      final CfgInfo info = getDefaultCfgInfo();
      final Map<String, Set<InjInfo>> currentMap =
          ContainerUtil.classify(
              info.injectionInfos.iterator(),
              new Convertor<InjInfo, String>() {
                public String convert(final InjInfo o) {
                  return o.injection.getSupportId();
                }
              });
      final List<BaseInjection> originalInjections = new ArrayList<BaseInjection>();
      final List<BaseInjection> newInjections = new ArrayList<BaseInjection>();
      //// remove duplicates
      // for (String supportId : InjectorUtils.getActiveInjectionSupportIds()) {
      //  final Set<BaseInjection> currentInjections = currentMap.get(supportId);
      //  if (currentInjections == null) continue;
      //  for (BaseInjection injection : currentInjections) {
      //    Configuration.importInjections(newInjections, Collections.singleton(injection),
      // originalInjections, newInjections);
      //  }
      // }
      // myInjections.clear();
      // myInjections.addAll(newInjections);

      for (String supportId : InjectorUtils.getActiveInjectionSupportIds()) {
        ArrayList<InjInfo> list =
            new ArrayList<InjInfo>(
                ObjectUtils.notNull(currentMap.get(supportId), Collections.<InjInfo>emptyList()));
        final List<BaseInjection> currentInjections = getInjectionList(list);
        final List<BaseInjection> importingInjections = cfg.getInjections(supportId);
        if (currentInjections == null) {
          newInjections.addAll(importingInjections);
        } else {
          Configuration.importInjections(
              currentInjections, importingInjections, originalInjections, newInjections);
        }
      }
      info.replace(originalInjections, newInjections);
      myInjectionsTable.getListTableModel().setItems(getInjInfoList(myInfos));
      final int n = newInjections.size();
      if (n > 1) {
        Messages.showInfoMessage(
            myProject, n + " entries have been successfully imported", "Import Successful");
      } else if (n == 1) {
        Messages.showInfoMessage(
            myProject, "One entry has been successfully imported", "Import Successful");
      } else {
        Messages.showInfoMessage(myProject, "No new entries have been imported", "Import");
      }
    } catch (Exception ex) {
      Configuration.LOG.error(ex);

      final String msg = ex.getLocalizedMessage();
      Messages.showErrorDialog(
          myProject, msg != null && msg.length() > 0 ? msg : ex.toString(), "Import Failed");
    }
  }