Program: 191315
Project: 191315
Buggy source:
/** 
 * Sets the focused task relative to the currently focused task.
 * @param forward whether to go to the next task in the stack (along the curve) or the previous
 * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, andif the currently focused task is not a stack task, will set the focus to the first visible stack task
 * @param animated determines whether to actually draw the highlight along with the change infocus.
 * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scrollhappens.
 * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
 */
public void setRelativeFocusedTask(boolean forward,boolean stackTasksOnly,boolean animated,boolean cancelWindowAnimations,int timerIndicatorDuration){
  int newIndex=mStack.indexOfStackTask(mFocusedTask);
  if (mFocusedTask != null) {
    if (stackTasksOnly) {
      List<Task> tasks=mStack.getStackTasks();
      if (mFocusedTask.isFreeformTask()) {
        TaskView tv=getFrontMostTaskView(stackTasksOnly);
        if (tv != null) {
          newIndex=mStack.indexOfStackTask(tv.getTask());
        }
      }
 else {
        int tmpNewIndex=newIndex + (forward ? -1 : 1);
        if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
          Task t=tasks.get(tmpNewIndex);
          if (!t.isFreeformTask()) {
            newIndex=tmpNewIndex;
          }
        }
      }
    }
 else {
      int taskCount=mStack.getTaskCount();
      newIndex=(newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
    }
  }
 else {
    float stackScroll=mStackScroller.getStackScroll();
    ArrayList<Task> tasks=mStack.getStackTasks();
    int taskCount=tasks.size();
    if (forward) {
      for (newIndex=taskCount - 1; newIndex >= 0; newIndex--) {
        float taskP=mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
        if (Float.compare(taskP,stackScroll) <= 0) {
          break;
        }
      }
    }
 else {
      for (newIndex=0; newIndex < taskCount; newIndex++) {
        float taskP=mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
        if (Float.compare(taskP,stackScroll) >= 0) {
          break;
        }
      }
    }
  }
  if (newIndex != -1) {
    boolean willScroll=setFocusedTask(newIndex,true,true,timerIndicatorDuration);
    if (willScroll && cancelWindowAnimations) {
      EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
    }
  }
}

Fixed version (ground truth):
/** 
 * Sets the focused task relative to the currently focused task.
 * @param forward whether to go to the next task in the stack (along the curve) or the previous
 * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, andif the currently focused task is not a stack task, will set the focus to the first visible stack task
 * @param animated determines whether to actually draw the highlight along with the change infocus.
 * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scrollhappens.
 * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
 */
public void setRelativeFocusedTask(boolean forward,boolean stackTasksOnly,boolean animated,boolean cancelWindowAnimations,int timerIndicatorDuration){
  Task focusedTask=getFocusedTask();
  int newIndex=mStack.indexOfStackTask(focusedTask);
  if (focusedTask != null) {
    if (stackTasksOnly) {
      List<Task> tasks=mStack.getStackTasks();
      if (focusedTask.isFreeformTask()) {
        TaskView tv=getFrontMostTaskView(stackTasksOnly);
        if (tv != null) {
          newIndex=mStack.indexOfStackTask(tv.getTask());
        }
      }
 else {
        int tmpNewIndex=newIndex + (forward ? -1 : 1);
        if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
          Task t=tasks.get(tmpNewIndex);
          if (!t.isFreeformTask()) {
            newIndex=tmpNewIndex;
          }
        }
      }
    }
 else {
      int taskCount=mStack.getTaskCount();
      newIndex=(newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
    }
  }
 else {
    float stackScroll=mStackScroller.getStackScroll();
    ArrayList<Task> tasks=mStack.getStackTasks();
    int taskCount=tasks.size();
    if (forward) {
      for (newIndex=taskCount - 1; newIndex >= 0; newIndex--) {
        float taskP=mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
        if (Float.compare(taskP,stackScroll) <= 0) {
          break;
        }
      }
    }
 else {
      for (newIndex=0; newIndex < taskCount; newIndex++) {
        float taskP=mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
        if (Float.compare(taskP,stackScroll) >= 0) {
          break;
        }
      }
    }
  }
  if (newIndex != -1) {
    boolean willScroll=setFocusedTask(newIndex,true,true,timerIndicatorDuration);
    if (willScroll && cancelWindowAnimations) {
      EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
    }
  }
}