@RequiresBackgroundThread
  private void checkAndUpdateRepositoryCollection(@Nullable VirtualFile checkedRoot) {
    myUpdateScheduled.set(false);

    if (MODIFY_LOCK.isHeldByCurrentThread()) {
      LOG.error(new Throwable("Recursive Repository initialization"));
      return;
    }

    MODIFY_LOCK.lock();
    try {
      Map<VirtualFile, Repository> repositories;

      REPO_LOCK.readLock().lock();
      try {
        repositories = new HashMap<>(myRepositories);
      }
      finally {
        REPO_LOCK.readLock().unlock();
      }

      if (checkedRoot != null && repositories.containsKey(checkedRoot)) return;

      BackgroundTaskUtil.runUnderDisposeAwareIndicator(this, () -> {
        Collection<VirtualFile> invalidRoots = findInvalidRoots(repositories.values());
        repositories.keySet().removeAll(invalidRoots);
        Map<VirtualFile, Repository> newRoots = findNewRoots(repositories.keySet());
        repositories.putAll(newRoots);
      });

      REPO_LOCK.writeLock().lock();
      try {
        if (!myDisposed) {
          for (VirtualFile file : myRepositories.keySet()) {
            Repository oldRepo = myRepositories.get(file);
            Repository newRepo = repositories.get(file);
            if (oldRepo != newRepo) {
              Disposer.dispose(oldRepo);
            }
          }

          myRepositories.clear();
          myRepositories.putAll(repositories);
        }

        updatePathToRootMap();
      }
      finally {
        REPO_LOCK.writeLock().unlock();
      }
    }
    finally {
      MODIFY_LOCK.unlock();
    }
    BackgroundTaskUtil.syncPublisher(myProject, VCS_REPOSITORY_MAPPING_UPDATED).mappingChanged();
  }
@RequiresBackgroundThread
  private void checkAndUpdateRepositoryCollection(@Nullable VirtualFile checkedRoot)