@Override
 @NotNull
 public Project[] getOpenProjects() {
   synchronized (myOpenProjects) {
     if (myOpenProjectsArrayCache.length != myOpenProjects.size()) {
       LOG.error(
           "Open projects: "
               + myOpenProjects
               + "; cache: "
               + Arrays.asList(myOpenProjectsArrayCache));
     }
     if (myOpenProjectsArrayCache.length > 0
         && myOpenProjectsArrayCache[0] != myOpenProjects.get(0)) {
       LOG.error(
           "Open projects cache corrupted. Open projects: "
               + myOpenProjects
               + "; cache: "
               + Arrays.asList(myOpenProjectsArrayCache));
     }
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       Project[] testProjects = myTestProjects.toArray(new Project[myTestProjects.size()]);
       for (Project testProject : testProjects) {
         assert !testProject.isDisposed() : testProject;
       }
       return ArrayUtil.mergeArrays(myOpenProjectsArrayCache, testProjects);
     }
     return myOpenProjectsArrayCache;
   }
 }
 @Override
 public Collection<Project> closeTestProject(@NotNull Project project) {
   synchronized (myOpenProjects) {
     assert ApplicationManager.getApplication().isUnitTestMode();
     myTestProjects.remove(project);
     return myTestProjects;
   }
 }
 @Override
 public void openTestProject(@NotNull final Project project) {
   synchronized (myOpenProjects) {
     assert ApplicationManager.getApplication().isUnitTestMode();
     assert !project.isDisposed() : "Must not open already disposed project";
     myTestProjects.add(project);
   }
 }
 @Override
 public boolean isProjectOpened(Project project) {
   synchronized (myOpenProjects) {
     return ApplicationManager.getApplication().isUnitTestMode()
             && myTestProjects.contains(project)
         || myOpenProjects.contains(project);
   }
 }
  private boolean shouldReloadProject(final Project project) {
    if (project.isDisposed()) return false;
    final HashSet<Pair<VirtualFile, StateStorage>> causes =
        new HashSet<Pair<VirtualFile, StateStorage>>();

    synchronized (myChangedProjectFiles) {
      final List<Pair<VirtualFile, StateStorage>> changes = myChangedProjectFiles.remove(project);
      if (changes != null) {
        causes.addAll(changes);
      }

      if (causes.isEmpty()) return false;
    }

    final boolean[] reloadOk = {false};

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                try {
                  LOG.debug("[RELOAD] Reloading project/components...");
                  reloadOk[0] = ((ProjectEx) project).getStateStore().reload(causes);
                } catch (StateStorageException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                } catch (IOException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                }
              }
            });
    if (reloadOk[0]) return false;

    String message;
    if (causes.size() == 1) {
      message =
          ProjectBundle.message(
              "project.reload.external.change.single",
              causes.iterator().next().first.getPresentableUrl());
    } else {
      StringBuilder filesBuilder = new StringBuilder();
      boolean first = true;
      Set<String> alreadyShown = new HashSet<String>();
      for (Pair<VirtualFile, StateStorage> cause : causes) {
        String url = cause.first.getPresentableUrl();
        if (!alreadyShown.contains(url)) {
          if (alreadyShown.size() > 10) {
            filesBuilder
                .append("\n" + "and ")
                .append(causes.size() - alreadyShown.size())
                .append(" more");
            break;
          }
          if (!first) filesBuilder.append("\n");
          first = false;
          filesBuilder.append(url);
          alreadyShown.add(url);
        }
      }
      message =
          ProjectBundle.message("project.reload.external.change.multiple", filesBuilder.toString());
    }

    return Messages.showTwoStepConfirmationDialog(
            message,
            ProjectBundle.message("project.reload.external.change.title"),
            "Reload project",
            Messages.getQuestionIcon())
        == 0;
  }