private String getDiffWindowTitle(final Change change) {
    if (change.isMoved() || change.isRenamed()) {
      final FilePath beforeFilePath = ChangesUtil.getBeforePath(change);
      final FilePath afterFilePath = ChangesUtil.getAfterPath(change);

      final String beforePath =
          beforeFilePath == null ? "" : beforeFilePath.getIOFile().getAbsolutePath();
      final String afterPath =
          afterFilePath == null ? "" : afterFilePath.getIOFile().getAbsolutePath();
      return SvnBundle.message(
          "action.Subversion.properties.difference.diff.for.move.title", beforePath, afterPath);
    } else {
      return SvnBundle.message(
          "action.Subversion.properties.difference.diff.title",
          ChangesUtil.getFilePath(change).getIOFile().getAbsolutePath());
    }
  }
 private static Pair<SVNRevision, SVNURL> createRemoteFolder(
     final SvnVcs17 vcs, final SVNURL parent, final String folderName) throws SVNException {
   SVNURL url = parent.appendPath(folderName, false);
   final String urlText = url.toString();
   final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
   if (indicator != null) {
     indicator.checkCanceled();
     indicator.setText(SvnBundle.message("share.directory.create.dir.progress.text", urlText));
   }
   final SVNCommitInfo info =
       vcs.createCommitClient()
           .doMkDir(
               new SVNURL[] {url},
               SvnBundle.message(
                   "share.directory.commit.message",
                   folderName,
                   ApplicationNamesInfo.getInstance().getFullProductName()));
   return new Pair<SVNRevision, SVNURL>(SVNRevision.create(info.getNewRevision()), url);
 }
 private CalculateAndShow(
     @Nullable final Project project, final Change change, final String errorTitle) {
   super(
       project,
       SvnBundle.message("fetching.properties.contents.progress.title"),
       true,
       Backgroundable.DEAF);
   myChange = change;
   myErrorTitle = errorTitle;
 }
  private static ISVNPropertyHandler createHandler(
      SVNRevision revision, final List<SVNPropertyData> lines) {
    final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
    if (indicator != null) {
      indicator.checkCanceled();
      indicator.setText(
          SvnBundle.message(
              "show.properties.diff.progress.text.revision.information", revision.toString()));
    }

    return new ISVNPropertyHandler() {
      public void handleProperty(final File path, final SVNPropertyData property)
          throws SVNException {
        if (indicator != null) {
          indicator.checkCanceled();
          indicator.setText2(
              SvnBundle.message(
                  "show.properties.diff.progress.text2.property.information", property.getName()));
        }
        lines.add(property);
      }

      public void handleProperty(final SVNURL url, final SVNPropertyData property)
          throws SVNException {
        if (indicator != null) {
          indicator.checkCanceled();
          indicator.setText2(
              SvnBundle.message(
                  "show.properties.diff.progress.text2.property.information", property.getName()));
        }
        lines.add(property);
      }

      public void handleProperty(final long revision, final SVNPropertyData property)
          throws SVNException {
        // revision properties here
      }
    };
  }
public class MergeInfoHolder {
  private final DecoratorManager myManager;
  private final Consumer<Boolean> myMixedRevisionsConsumer;
  private final SvnMergeInfoCache17 myMergeInfoCache;

  private static final String ourIntegratedText =
      SvnBundle.message("committed.changes.merge.status.integrated.text");
  private static final String ourNotIntegratedText =
      SvnBundle.message("committed.changes.merge.status.not.integrated.text");
  private static final SimpleTextAttributes ourNotIntegratedAttributes =
      new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Color.RED);
  private static final SimpleTextAttributes ourIntegratedAttributes =
      new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Color.GREEN);
  private static final SimpleTextAttributes ourRefreshAttributes =
      new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, Color.GRAY);

  // used ONLY when refresh is triggered
  private final Map<Pair<String, String>, MergeinfoCached> myCachedMap;

  private final Getter<WCInfoWithBranches> myRootGetter;
  private final Getter<WCInfoWithBranches.Branch> myBranchGetter;
  private final Getter<String> myWcPathGetter;
  private final Getter<Boolean> myEnabledHolder;
  private final MyDecorator myDecorator;

  public MergeInfoHolder(
      final Project project,
      final DecoratorManager manager,
      final Getter<WCInfoWithBranches> rootGetter,
      final Getter<WCInfoWithBranches.Branch> branchGetter,
      final Getter<String> wcPathGetter,
      Getter<Boolean> enabledHolder,
      final Consumer<Boolean> mixedRevisionsConsumer) {
    myRootGetter = rootGetter;
    myBranchGetter = branchGetter;
    myWcPathGetter = wcPathGetter;
    myEnabledHolder = enabledHolder;
    myManager = manager;
    myMixedRevisionsConsumer = mixedRevisionsConsumer;
    myMergeInfoCache = SvnMergeInfoCache17.getInstance(project);
    myCachedMap = new HashMap<Pair<String, String>, MergeinfoCached>();

    myDecorator = new MyDecorator();
  }

  private MergeinfoCached getCurrentCache() {
    return myCachedMap.get(createKey(myRootGetter.get(), myBranchGetter.get()));
  }

  private boolean enabledAndGettersFilled(final boolean ignoreEnabled) {
    if ((!ignoreEnabled) && (!Boolean.TRUE.equals(myEnabledHolder.get()))) {
      return false;
    }
    return (myRootGetter.get() != null)
        && (myBranchGetter.get() != null)
        && (myWcPathGetter.get() != null);
  }

  public boolean refreshEnabled(final boolean ignoreEnabled) {
    return enabledAndGettersFilled(ignoreEnabled) && (getCurrentCache() == null);
  }

  private static Pair<String, String> createKey(
      final WCPaths root, final WCInfoWithBranches.Branch branch) {
    return new Pair<String, String>(root.getPath(), branch.getUrl());
  }

  public void refresh(final boolean ignoreEnabled) {
    final CommittedChangeListsListener refresher = createRefresher(ignoreEnabled);
    if (refresher != null) {
      myManager.reportLoadedLists(new MyRefresher());
    }
    myManager.repaintTree();
  }

  @Nullable
  public CommittedChangeListsListener createRefresher(final boolean ignoreEnabled) {
    if (refreshEnabled(ignoreEnabled)) {
      // on awt thread
      final MergeinfoCached state =
          myMergeInfoCache.getCachedState(myRootGetter.get(), myWcPathGetter.get());
      myCachedMap.put(
          createKey(myRootGetter.get(), myBranchGetter.get()),
          (state == null)
              ? new MergeinfoCached()
              : new MergeinfoCached(
                  new HashMap<Long, SvnMergeInfoCache17.MergeCheckResult>(state.getMap()),
                  state.getCopyRevision()));
      myMergeInfoCache.clear(myRootGetter.get(), myWcPathGetter.get());

      return new MyRefresher();
    }
    return null;
  }

  private class MyRefresher implements CommittedChangeListsListener {
    private final WCInfoWithBranches myRefreshedRoot;
    private final WCInfoWithBranches.Branch myRefreshedBranch;
    private final String myBranchPath;

    private MyRefresher() {
      myRefreshedRoot = myRootGetter.get();
      myRefreshedBranch = myBranchGetter.get();
      myBranchPath = myWcPathGetter.get();
    }

    public void onBeforeStartReport() {}

    public boolean report(final CommittedChangeList list) {
      if (list instanceof SvnChangeList) {
        final SvnChangeList svnList = (SvnChangeList) list;
        final String wcPath = svnList.getWcPath() + File.separator;
        // todo check if this needed
        /*if (! myRefreshedRoot.getPath().equals(wcPath)) {
          return true;
        } */

        // prepare state. must be in non awt thread
        final SvnMergeInfoCache17.MergeCheckResult checkState =
            myMergeInfoCache.getState(
                myRefreshedRoot, (SvnChangeList) list, myRefreshedBranch, myBranchPath);
        // todo make batches - by 10
        final long number = list.getNumber();
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  public void run() {
                    final MergeinfoCached cachedState =
                        myCachedMap.get(createKey(myRefreshedRoot, myRefreshedBranch));
                    if (cachedState != null) {
                      cachedState.getMap().put(number, checkState);
                    }
                    myManager.repaintTree();
                  }
                });
      }
      return true;
    }

    public void onAfterEndReport() {
      ApplicationManager.getApplication()
          .invokeLater(
              new Runnable() {
                public void run() {
                  myCachedMap.remove(createKey(myRefreshedRoot, myRefreshedBranch));
                  updateMixedRevisionsForPanel();
                  myManager.repaintTree();
                }
              });
    }
  }

  public static enum ListMergeStatus {
    COMMON(IconLoader.getIcon("/icons/Common.png")),
    MERGED(IconLoader.getIcon("/icons/Integrated.png")),
    NOT_MERGED(IconLoader.getIcon("/icons/Notintegrated.png")),
    // ALIEN(IconLoader.getIcon("/icons/OnDefault.png")),
    ALIEN(null),
    REFRESHING(IconLoader.getIcon("/icons/IntegrationStatusUnknown.png"));

    private final Icon myIcon;

    private ListMergeStatus(final Icon icon) {
      myIcon = icon;
    }

    public Icon getIcon() {
      return myIcon;
    }
  }

  public static interface ListChecker {
    ListMergeStatus check(final CommittedChangeList list, final boolean ignoreEnabled);
  }

  class MyDecorator implements ListChecker {
    private ListMergeStatus convert(
        SvnMergeInfoCache17.MergeCheckResult result, final boolean refreshing) {
      if (result != null) {
        if (SvnMergeInfoCache17.MergeCheckResult.MERGED.equals(result)) {
          return ListMergeStatus.MERGED;
        } else if (SvnMergeInfoCache17.MergeCheckResult.COMMON.equals(result)) {
          return ListMergeStatus.COMMON;
        } else {
          return ListMergeStatus.NOT_MERGED;
        }
      }
      if (refreshing) {
        return ListMergeStatus.REFRESHING;
      }
      return ListMergeStatus.ALIEN;
    }

    public ListMergeStatus check(final CommittedChangeList list, final boolean ignoreEnabled) {
      if (!enabledAndGettersFilled(ignoreEnabled)) {
        return ListMergeStatus.ALIEN;
      }

      if (!(list instanceof SvnChangeList)) {
        return ListMergeStatus.ALIEN;
      }

      final MergeinfoCached cachedState = getCurrentCache();
      if (cachedState != null) {
        if (cachedState.getCopyRevision() != -1
            && cachedState.getCopyRevision() >= list.getNumber()) {
          return ListMergeStatus.COMMON;
        }
        final SvnMergeInfoCache17.MergeCheckResult result =
            cachedState.getMap().get(list.getNumber());
        return convert(result, true);
      } else {
        final MergeinfoCached state =
            myMergeInfoCache.getCachedState(myRootGetter.get(), myWcPathGetter.get());
        if (state == null) {
          refresh(ignoreEnabled);
          return ListMergeStatus.REFRESHING;
        } else {
          if (state.getCopyRevision() != -1 && state.getCopyRevision() >= list.getNumber()) {
            return ListMergeStatus.COMMON;
          }
          return convert(state.getMap().get(list.getNumber()), false);
        }
      }
    }
  }

  public ListChecker getDecorator() {
    return myDecorator;
  }

  public void updateMixedRevisionsForPanel() {
    myMixedRevisionsConsumer.consume(
        myMergeInfoCache.isMixedRevisions(myRootGetter.get(), myWcPathGetter.get()));
  }
}
 protected String getActionName(AbstractVcs vcs) {
   return SvnBundle.message("share.directory.action");
 }
  private static boolean performImpl(
      final Project project, final SvnVcs17 activeVcs, final VirtualFile file) throws VcsException {
    final ShareDialog shareDialog = new ShareDialog(project, file.getName());
    shareDialog.show();

    final String parent = shareDialog.getSelectedURL();
    if (shareDialog.isOK() && parent != null) {
      final Ref<Boolean> actionStarted = new Ref<Boolean>(Boolean.TRUE);
      final SVNException[] error = new SVNException[1];

      final ShareDialog.ShareTarget shareTarget = shareDialog.getShareTarget();
      final ProgressManager progressManager = ProgressManager.getInstance();

      if (ShareDialog.ShareTarget.useSelected.equals(shareTarget)) {
        final boolean folderEmpty = checkRemoteFolder(project, activeVcs, parent, progressManager);

        if (!folderEmpty) {
          final int promptAnswer =
              Messages.showYesNoDialog(
                  project,
                  "Remote folder \""
                      + parent
                      + "\" is not empty.\nDo you want to continue sharing?",
                  "Share directory",
                  Messages.getWarningIcon());
          if (DialogWrapper.OK_EXIT_CODE != promptAnswer) return false;
        }
      }

      ExclusiveBackgroundVcsAction.run(
          project,
          new Runnable() {
            public void run() {
              progressManager.runProcessWithProgressSynchronously(
                  new Runnable() {
                    public void run() {
                      try {
                        final ProgressIndicator indicator =
                            ProgressManager.getInstance().getProgressIndicator();

                        final File path = new File(file.getPath());
                        if (!SvnCheckoutProvider.promptForWCFormatAndSelect(path, project)) {
                          // action cancelled
                          actionStarted.set(Boolean.FALSE);
                          return;
                        }
                        final SVNURL parenUrl = SVNURL.parseURIEncoded(parent);
                        final SVNURL checkoutUrl;
                        final SVNRevision revision;

                        if (ShareDialog.ShareTarget.useSelected.equals(shareTarget)) {
                          checkoutUrl = parenUrl;
                          revision = SVNRevision.HEAD;
                        } else if (ShareDialog.ShareTarget.useProjectName.equals(shareTarget)) {
                          final Pair<SVNRevision, SVNURL> pair =
                              createRemoteFolder(activeVcs, parenUrl, file.getName());
                          revision = pair.getFirst();
                          checkoutUrl = pair.getSecond();
                        } else {
                          final Pair<SVNRevision, SVNURL> pair =
                              createRemoteFolder(activeVcs, parenUrl, file.getName());
                          final Pair<SVNRevision, SVNURL> trunkPair =
                              createRemoteFolder(activeVcs, pair.getSecond(), "trunk");
                          checkoutUrl = trunkPair.getSecond();
                          revision = trunkPair.getFirst();

                          if (shareDialog.createStandardStructure()) {
                            createRemoteFolder(activeVcs, pair.getSecond(), "branches");
                            createRemoteFolder(activeVcs, pair.getSecond(), "tags");
                          }
                        }

                        if (indicator != null) {
                          indicator.checkCanceled();
                          indicator.setText(
                              SvnBundle.message(
                                  "share.directory.checkout.back.progress.text",
                                  checkoutUrl.toString()));
                        }
                        activeVcs
                            .createUpdateClient()
                            .doCheckout(checkoutUrl, path, SVNRevision.UNDEFINED, revision, true);
                        SvnWorkingCopyFormatHolder.setPresetFormat(null);

                        addRecursively(activeVcs, file);
                      } catch (SVNException e) {
                        error[0] = e;
                      } finally {
                        activeVcs.invokeRefreshSvnRoots(true);
                        SvnWorkingCopyFormatHolder.setPresetFormat(null);
                      }
                    }
                  },
                  SvnBundle.message("share.directory.title"),
                  true,
                  project);
            }
          });

      if (Boolean.TRUE.equals(actionStarted.get())) {
        if (error[0] != null) {
          throw new VcsException(error[0].getMessage());
        }
        Messages.showInfoMessage(
            project,
            SvnBundle.message("share.directory.info.message", file.getName()),
            SvnBundle.message("share.directory.title"));
      }
      return true;
    }
    return false;
  }
 protected String getActionName(AbstractVcs vcs) {
   return SvnBundle.message("action.Subversion.Unlock.description");
 }