/**
   * The action has been activated. The argument of the method represents the 'real' action sitting
   * in the workbench UI.
   *
   * @see IWorkbenchWindowActionDelegate#run
   */
  public void run(IAction action) {
    Shell shell = window != null ? window.getShell() : MercurialEclipsePlugin.getActiveShell();
    if (!confirmRemove(shell)) {
      return;
    }
    List<IResource> resources = ResourceUtils.getResources(selection);
    Map<HgRoot, List<IResource>> byRoot = ResourceUtils.groupByRoot(resources);

    try {
      HgRemoveClient.removeResourcesLater(byRoot);
    } finally {
      for (Map.Entry<HgRoot, List<IResource>> mapEntry : byRoot.entrySet()) {
        HgRoot hgRoot = mapEntry.getKey();
        new RefreshStatusJob("Refreshing " + hgRoot.getName(), hgRoot).schedule();
      }
    }
  }
  /**
   * @return set with ALL projects managed by hg, <b>not only</b> projects for which we know remote
   *     repo locations
   * @throws HgException
   */
  private Map<HgRoot, List<IResource>> loadRepos() throws HgException {
    rootRepos.clear();
    List<IProject> projects = getAllProjects();
    Map<HgRoot, List<IResource>> roots = ResourceUtils.groupByRoot(projects);

    for (Entry<HgRoot, List<IResource>> entry : roots.entrySet()) {
      HgRoot hgRoot = entry.getKey();
      loadRepos(hgRoot);
    }
    return roots;
  }
  private void saveProjectRepos() {
    List<IProject> projects = getAllProjects();

    Map<HgRoot, List<IResource>> byRoot = ResourceUtils.groupByRoot(projects);
    Set<HgRoot> roots = byRoot.keySet();

    for (HgRoot hgRoot : roots) {
      String key = getRootKey(hgRoot);
      Set<IHgRepositoryLocation> repoSet = rootRepos.get(hgRoot);
      if (repoSet == null) {
        continue;
      }
      synchronized (entriesLock) {
        repoSet = new LinkedHashSet<IHgRepositoryLocation>(repoSet);
      }
      saveRepositories(key, repoSet);
    }
  }
 public void update(Observable o, Object arg) {
   if (hgRoot == null || !(arg instanceof Set<?>)) {
     return;
   }
   Set<?> set = (Set<?>) arg;
   Set<IProject> projects = ResourceUtils.getProjects(hgRoot);
   // create intersection of the root projects with the updated set
   projects.retainAll(set);
   // if the intersection contains common projects, we need update the view
   if (!projects.isEmpty()) {
     Display.getDefault()
         .asyncExec(
             new Runnable() {
               public void run() {
                 refresh(hgRoot);
               }
             });
   }
 }
  /**
   * @param repo non null repo location
   * @return a set of projects we know managed at given location, never null
   */
  public Set<IProject> getAllRepoLocationProjects(IHgRepositoryLocation repo) {
    Set<IProject> projects = new LinkedHashSet<IProject>();

    try {
      getProjectRepos();
    } catch (Exception e) {
      MercurialEclipsePlugin.logError(e);
    }

    Set<Entry<HgRoot, Set<IHgRepositoryLocation>>> entrySet = rootRepos.entrySet();
    for (Entry<HgRoot, Set<IHgRepositoryLocation>> entry : entrySet) {
      Set<IHgRepositoryLocation> set = entry.getValue();
      if (set != null && set.contains(repo)) {
        projects.addAll(ResourceUtils.getProjects(entry.getKey()));
      }
    }
    if (projects.isEmpty() && repo.isLocal()) {
      HgRoot hgRoot = repo.toHgRoot();
      if (hgRoot != null) {
        projects.addAll(MercurialTeamProvider.getKnownHgProjects(hgRoot));
      }
    }
    return projects;
  }