public boolean closeProject( @NotNull final Project project, final boolean save, final boolean dispose, boolean checkCanClose) { if (isLight(project)) { throw new AssertionError("must not close light project"); } if (!isProjectOpened(project)) return true; if (checkCanClose && !canClose(project)) return false; final ShutDownTracker shutDownTracker = ShutDownTracker.getInstance(); shutDownTracker.registerStopperThread(Thread.currentThread()); try { if (save) { FileDocumentManager.getInstance().saveAllDocuments(); project.save(); } if (checkCanClose && !ensureCouldCloseIfUnableToSave(project)) { return false; } fireProjectClosing(project); // somebody can start progress here, do not wrap in write action ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { synchronized (myOpenProjects) { myOpenProjects.remove(project); cacheOpenProjects(); myTestProjects.remove(project); } myChangedProjectFiles.remove(project); fireProjectClosed(project); if (dispose) { Disposer.dispose(project); } } }); } finally { shutDownTracker.unregisterStopperThread(Thread.currentThread()); } return true; }