@Override
    public void runActivity(@NotNull Project project) {
      MessageBusConnection connection = project.getMessageBus().connect();
      connection.subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionListener() {
        @Override
        public void processStarting(@NotNull String executorId, @NotNull ExecutionEnvironment env) {
          getInstance().cancelAutoMakeTasks(env.getProject()); // make sure to cancel all automake requests waiting in the build queue
        }

        @Override
        public void processStarted(@NotNull String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) {
          // make sure to cancel all automake requests added to the build queue after processStaring and before this event
          getInstance().cancelAutoMakeTasks(env.getProject());
        }

        @Override
        public void processNotStarted(@NotNull String executorId, @NotNull ExecutionEnvironment env) {
          // augmenting reaction to `processTerminated()`: in case any automake requests were canceled before the process start
          getInstance().scheduleAutoMake();
        }

        @Override
        public void processTerminated(@NotNull String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler, int exitCode) {
          getInstance().scheduleAutoMake();
        }
      });
      connection.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusListener() {
        private final Set<String> myRootsToRefresh = CollectionFactory.createFilePathSet();

        @Override
        public void automakeCompilationFinished(int errors, int warnings, @NotNull CompileContext compileContext) {
          if (!compileContext.getProgressIndicator().isCanceled()) {
            refreshSources(compileContext);
          }
        }

        @Override
        public void compilationFinished(boolean aborted, int errors, int warnings, @NotNull CompileContext compileContext) {
          refreshSources(compileContext);
        }

        private void refreshSources(CompileContext compileContext) {
          if (project.isDisposed()) {
            return;
          }
          final Set<String> candidates = CollectionFactory.createFilePathSet();
          synchronized (myRootsToRefresh) {
            candidates.addAll(myRootsToRefresh);
            myRootsToRefresh.clear();
          }

          if (candidates.isEmpty() && !compileContext.isAnnotationProcessorsEnabled()) {
            return;
          }

          BackgroundTaskUtil.submitTask(ProjectDisposableService.getInstance(project), () -> {
            if (project.isDisposed()) {
              return;
            }

            if (compileContext.isAnnotationProcessorsEnabled()) {
              // annotation processors may have re-generated code
              final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
              try {
                for (Module module : ReadAction.nonBlocking(() -> compileContext.getCompileScope().getAffectedModules()).executeSynchronously()) {
                  if (project.isDisposed()) {
                    return;
                  }
                  if (module.isDisposed()) {
                    continue;
                  }
                  if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
                    final String productionPath = CompilerPaths.getAnnotationProcessorsGenerationPath(module, false);
                    if (productionPath != null) {
                      candidates.add(productionPath);
                    }
                    final String testsPath = CompilerPaths.getAnnotationProcessorsGenerationPath(module, true);
                    if (testsPath != null) {
                      candidates.add(testsPath);
                    }
                  }
                }
              }
              catch (ProcessCanceledException ignored) {
              }
              catch (Throwable e) {
                LOG.info(e);
              }
            }

            if (candidates.isEmpty()) {
              return;
            }

            CompilerUtil.refreshOutputRoots(candidates);

            LocalFileSystem lfs = LocalFileSystem.getInstance();
            try {
              Collection<VirtualFile> toRefresh = ReadAction.nonBlocking(() -> {
                if (project.isDisposed()) {
                  return Collections.<VirtualFile>emptySet();
                }
                ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
                return candidates.stream().map(lfs::findFileByPath).filter(root -> root != null && fileIndex.isInSourceContent(root)).collect(Collectors.toSet());

              }).executeSynchronously();

              if (!toRefresh.isEmpty()) {
                lfs.refreshFiles(toRefresh, true, true, null);
              }
            }
            catch (ProcessCanceledException ignored) {
            }
            catch (Throwable e) {
              LOG.info(e);
            }
          });
        }

        @Override
        public void fileGenerated(@NotNull String outputRoot, @NotNull String relativePath) {
          synchronized (myRootsToRefresh) {
            myRootsToRefresh.add(outputRoot);
          }
        }
      });

      String projectPath = getProjectPath(project);
      Disposer.register(ProjectDisposableService.getInstance(project), () -> {
        BuildManager buildManager = getInstance();
        buildManager.cancelPreloadedBuilds(projectPath);
        buildManager.myProjectDataMap.remove(projectPath);
      });

      BuildProcessParametersProvider.EP_NAME.addChangeListener(project, () -> getInstance().cancelAllPreloadedBuilds(), null);

      getInstance().runCommand(() -> {
        try {
          BackgroundTaskUtil
            .submitTask(ProjectDisposableService.getInstance(project), () -> {
              updateUsageFile(project, getInstance().getProjectSystemDirectory(project));
            })
            .awaitCompletion();
        }
        catch (java.util.concurrent.ExecutionException e) {
          ExceptionUtil.rethrowAllAsUnchecked(e.getCause());
        }
      });
      // run automake after a project opened
      getInstance().scheduleAutoMake();
    }
@Override
    public void runActivity(@NotNull Project project)