private @Nullable Pair<Long, Integer> estimateProjectBuildTime(BuildRunner buildRunner,
                                       List<CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope> scopes) {
    ProjectDescriptor projectDescriptor = null;
    try {
      long startTime = System.currentTimeMillis();
      BuildFSState fsState = new BuildFSState(false);
      final File dataStorageRoot = Utils.getDataStorageRoot(myProjectPath);
      if (!dataStorageRoot.exists() || !new File(dataStorageRoot, FS_STATE_FILE).exists()) {
        // invoked the very first time for this project
        buildRunner.setForceCleanCaches(true);
        LOG.info("Storage files are absent");
      }
      projectDescriptor = buildRunner.load(MessageHandler.DEAF, dataStorageRoot, fsState);
      long contextInitializationTime = System.currentTimeMillis() - startTime;
      LOG.info("Time spend to context initialization: " + contextInitializationTime);
      CompileScope compilationScope = buildRunner.createCompilationScope(projectDescriptor, scopes);
      long estimatedBuildTime = IncProjectBuilder.calculateEstimatedBuildTime(projectDescriptor, t -> compilationScope.isAffected(t));
      BuildTargetsState targetsState = projectDescriptor.getTargetsState();
      if (JavaBuilderUtil.isForcedRecompilationAllJavaModules(compilationScope)) {
        LOG.info("Project rebuild enabled, caches will not be download");
        return null;
      }
      Map<BuildTargetType<?>, Long> buildTargetTypeStatistic = new HashMap<>();
      for (BuildTargetType<?> type : TargetTypeRegistry.getInstance().getTargetTypes()) {
        buildTargetTypeStatistic.put(type,  targetsState.getAverageBuildTime(type));
      }
      myOriginalBuildStatistic = new ProjectBuildStatistic(targetsState.getLastSuccessfulRebuildDuration(), buildTargetTypeStatistic);
      long totalCalculationTime = System.currentTimeMillis() - startTime;
      LOG.info("Calculated build time: " + StringUtil.formatDuration(estimatedBuildTime));
      LOG.info("Time spend to context initialization and time calculation: " + totalCalculationTime);
      return Pair.create(estimatedBuildTime, projectDescriptor.getProject().getModules().size());
    }
    catch (Exception e) {
      LOG.warn("Exception at calculation approximate build time", e);
    }
    finally {
      if (projectDescriptor != null) projectDescriptor.release();
    }
    return null;
  }
private @Nullable Pair<Long, Integer> estimateProjectBuildTime(BuildRunner buildRunner,
                                       List<CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope> scopes)