public static HostRoleStatus calculateStageStatus(List <HostRoleCommand> hostRoleCommands, Map<HostRoleStatus, Integer> counters, Map<Role, Float> successFactors,
                                                    boolean skippable) {

    // when there are 0 tasks, return COMPLETED
    int total = hostRoleCommands.size();
    if (total == 0) {
      return HostRoleStatus.COMPLETED;
    }

    if (counters.get(HostRoleStatus.PENDING) == total) {
      return HostRoleStatus.PENDING;
    }

    // By definition, any tasks in a future stage must be held in a PENDING status.
    if (counters.get(HostRoleStatus.HOLDING) > 0 || counters.get(HostRoleStatus.HOLDING_FAILED) > 0 || counters.get(HostRoleStatus.HOLDING_TIMEDOUT) > 0) {
      return counters.get(HostRoleStatus.HOLDING) > 0 ? HostRoleStatus.HOLDING :
          counters.get(HostRoleStatus.HOLDING_FAILED) > 0 ? HostRoleStatus.HOLDING_FAILED :
              HostRoleStatus.HOLDING_TIMEDOUT;
    }


    if (counters.get(HostRoleStatus.FAILED) > 0 && !skippable) {
      Set<Role> rolesWithFailedTasks = getRolesOfFailedTasks(hostRoleCommands);
      Boolean didStageFailed = didStageFailed(hostRoleCommands, rolesWithFailedTasks, successFactors);
      if (didStageFailed) return HostRoleStatus.FAILED;
    }


    if (counters.get(HostRoleStatus.TIMEDOUT) > 0  && !skippable) {
      Set<Role> rolesWithTimedOutTasks = getRolesOfTimedOutTasks(hostRoleCommands);
      Boolean didStageFailed = didStageFailed(hostRoleCommands, rolesWithTimedOutTasks, successFactors);
      if (didStageFailed) return HostRoleStatus.TIMEDOUT;
    }

    int numActiveTasks = counters.get(HostRoleStatus.PENDING) + counters.get(HostRoleStatus.QUEUED) + counters.get(HostRoleStatus.IN_PROGRESS);

    if (numActiveTasks > 0) {
      return HostRoleStatus.IN_PROGRESS;
    } else if (counters.get(HostRoleStatus.ABORTED) > 0) {
      Set<Role> rolesWithTimedOutTasks = getRolesOfAbortedTasks(hostRoleCommands);
      Boolean didStageFailed = didStageFailed(hostRoleCommands, rolesWithTimedOutTasks, successFactors);
      if (didStageFailed) return HostRoleStatus.ABORTED;
    }

    return HostRoleStatus.COMPLETED;
  }
@param hostRoleCommands list of {@link HostRoleCommand} for a stage
@param counters counts of resources that are in various states
@param successFactors Map of roles to their successfactor for a stage
@param skippable {Boolean} <code>TRUE<code/> if failure of any of the task should not fail the stage
@return {@link HostRoleStatus} based on success factor
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CalculatedStatus.java