code: synchronized TaskInProgress findTaskToKill(List<TaskAttemptID> tasksToExclude) {
      TaskInProgress killMe = null;
      for (Iterator it = runningTasks.values().iterator(); it.hasNext();) {
        TaskInProgress tip = (TaskInProgress) it.next();
  
        if (tasksToExclude != null
            && tasksToExclude.contains(tip.getTask().getTaskID())) {
          // exclude this task
          continue;
        }
  
        if ((tip.getRunState() == TaskStatus.State.RUNNING ||
             tip.getRunState() == TaskStatus.State.COMMIT_PENDING) &&
            !tip.wasKilled) {
  
          if (killMe == null) {
            killMe = tip;
  
          } else if (!tip.getTask().isMapTask()) {
            //reduce task, give priority
            if (killMe.getTask().isMapTask() ||
                (tip.getTask().getProgress().get() <
                 killMe.getTask().getProgress().get())) {
  
              killMe = tip;
            }
  
          } else if (killMe.getTask().isMapTask() &&
                     tip.getTask().getProgress().get() <
                     killMe.getTask().getProgress().get()) {
            //map task, only add if the progress is lower
  
            killMe = tip;
          }
        }
      }
      return killMe;
    }
docs: Pick a task to kill to free up memory/disk-space
  @param tasksToExclude tasks that are to be excluded while trying to find a
  task to kill. If null, all runningTasks will be searched.
  @return the task to kill or null, if one wasn't found