public static long calculateEstimatedBuildTime(@NotNull ProjectDescriptor projectDescriptor, @NotNull Predicate<BuildTarget<?>> isAffected) {
    final BuildTargetsState targetsState = projectDescriptor.getTargetsState();
    // compute estimated times for dirty targets
    long estimatedBuildTime = 0L;

    final BuildTargetIndex targetIndex = projectDescriptor.getBuildTargetIndex();
    int affectedTargets = 0;
    for (BuildTarget<?> target : targetIndex.getAllTargets()) {
      if (!targetIndex.isDummy(target)) {
        final long avgTimeToBuild = targetsState.getAverageBuildTime(target.getTargetType());
        if (avgTimeToBuild > 0) {
          // 1. in general case this time should include dependency analysis and cache update times
          // 2. need to check isAffected() since some targets (like artifacts) may be unaffected even for rebuild
          if (targetsState.getTargetConfiguration(target).isTargetDirty(projectDescriptor) && isAffected.test(target)) {
            estimatedBuildTime += avgTimeToBuild;
            affectedTargets++;
          }
        }
      }
    }
    LOG.info("Affected build targets count: " + affectedTargets);
    return estimatedBuildTime;
  }
public static long calculateEstimatedBuildTime(@NotNull ProjectDescriptor projectDescriptor, @NotNull Predicate<BuildTarget<?>> isAffected)