private void merge(
     @NotNull String title,
     @NotNull MergerFactory mergerFactory,
     @Nullable List<SvnChangeList> changeLists) {
   runInEdt(
       new LocalChangesPromptTask(
           this,
           changeLists,
           () ->
               runInEdt(
                   new MergeTask(this, () -> newIntegrateTask(title, mergerFactory).queue()))));
 }
  @CalledInAwt
  public void execute() {
    FileDocumentManager.getInstance().saveAllDocuments();

    mySemaphore.down();
    runInEdt(
        () -> {
          if (areInSameHierarchy(
              createUrl(myMergeContext.getSourceUrl()), myMergeContext.getWcInfo().getUrl())) {
            end("Cannot merge from self", true);
          } else if (!hasSwitchedRoots() || myInteraction.shouldContinueSwitchedRootFound()) {
            runInBackground(
                "Checking repository capabilities",
                indicator -> {
                  if (supportsMergeInfo()) {
                    runInEdt(this::selectMergeVariant);
                  } else {
                    mergeAll(false);
                  }
                });
          }
        });
  }
 private void mergeAll(boolean supportsMergeInfo) {
   // merge info is not supported - branch copy point is used to make first sync merge successful
   // (without unnecessary tree conflicts)
   // merge info is supported and svn client < 1.8 - branch copy point is used to determine if sync
   // or reintegrate merge should be performed
   // merge info is supported and svn client >= 1.8 - branch copy point is not used - svn
   // automatically detects if reintegrate is necessary
   if (supportsMergeInfo && is18()) {
     runInEdt(() -> checkReintegrateIsAllowedAndMergeAll(null, true));
   } else {
     runInBackground(
         "Looking for branch origin",
         new LookForBranchOriginTask(
             this,
             true,
             copyPoint ->
                 runInEdt(
                     () -> checkReintegrateIsAllowedAndMergeAll(copyPoint, supportsMergeInfo))));
   }
 }