private @Nullable Repository getRepositoryForRoot(@Nullable VirtualFile root, boolean updateIfNeeded) {
    if (root == null) return null;

    Application application = ApplicationManager.getApplication();
    if (updateIfNeeded && application.isDispatchThread() &&
        !application.isUnitTestMode() && !application.isHeadlessEnvironment()) {
      updateIfNeeded = false;
      LOG.error("Do not call synchronous repository update in EDT");
    }

    REPO_LOCK.readLock().lock();
    try {
      if (myDisposed) {
        throw new ProcessCanceledException();
      }
      Repository repo = myRepositories.get(root);
      if (repo != null) return repo;

      Repository externalRepo = myExternalRepositories.get(root);
      if (externalRepo != null) return externalRepo;
    }
    finally {
      REPO_LOCK.readLock().unlock();
    }

    // if we didn't find the appropriate repository, request update mappings if needed and try again
    // may be this should not be called from several places (for example, branch widget updating from edt).
    if (updateIfNeeded && ArrayUtil.contains(root, myVcsManager.getAllVersionedRoots())) {
      checkAndUpdateRepositoryCollection(root);

      REPO_LOCK.readLock().lock();
      try {
        return myRepositories.get(root);
      }
      finally {
        REPO_LOCK.readLock().unlock();
      }
    }
    else {
      return null;
    }
  }
private @Nullable Repository getRepositoryForRoot(@Nullable VirtualFile root, boolean updateIfNeeded)