Program: 91343
Project: 91343
Buggy source:
/** 
 * Does the three way merge between a common base and two sequences.
 * @param < S > type of sequence.
 * @param cmp comparison method for this execution.
 * @param base the common base sequence
 * @param ours the first sequence to be merged
 * @param theirs the second sequence to be merged
 * @return the resulting content
 */
public static <S extends Sequence>MergeResult<S> merge(SequenceComparator<S> cmp,S base,S ours,S theirs){
  List<S> sequences=new ArrayList<S>(3);
  sequences.add(base);
  sequences.add(ours);
  sequences.add(theirs);
  MergeResult result=new MergeResult<S>(sequences);
  EditList oursEdits=MyersDiff.INSTANCE.diff(cmp,base,ours);
  Iterator<Edit> baseToOurs=oursEdits.iterator();
  EditList theirsEdits=MyersDiff.INSTANCE.diff(cmp,base,theirs);
  Iterator<Edit> baseToTheirs=theirsEdits.iterator();
  int current=0;
  Edit oursEdit=nextEdit(baseToOurs);
  Edit theirsEdit=nextEdit(baseToTheirs);
  while (theirsEdit != END_EDIT || oursEdit != END_EDIT) {
    if (oursEdit.getEndA() <= theirsEdit.getBeginA()) {
      if (current != oursEdit.getBeginA()) {
        result.add(0,current,oursEdit.getBeginA(),ConflictState.NO_CONFLICT);
      }
      result.add(1,oursEdit.getBeginB(),oursEdit.getEndB(),ConflictState.NO_CONFLICT);
      current=oursEdit.getEndA();
      oursEdit=nextEdit(baseToOurs);
    }
 else     if (theirsEdit.getEndA() <= oursEdit.getBeginA()) {
      if (current != theirsEdit.getBeginA()) {
        result.add(0,current,theirsEdit.getBeginA(),ConflictState.NO_CONFLICT);
      }
      result.add(2,theirsEdit.getBeginB(),theirsEdit.getEndB(),ConflictState.NO_CONFLICT);
      current=theirsEdit.getEndA();
      theirsEdit=nextEdit(baseToTheirs);
    }
 else {
      if (oursEdit.getBeginA() != current && theirsEdit.getBeginA() != current) {
        result.add(0,current,Math.min(oursEdit.getBeginA(),theirsEdit.getBeginA()),ConflictState.NO_CONFLICT);
      }
      int oursBeginB=oursEdit.getBeginB();
      int theirsBeginB=theirsEdit.getBeginB();
      if (oursEdit.getBeginA() < theirsEdit.getBeginA()) {
        theirsBeginB-=theirsEdit.getBeginA() - oursEdit.getBeginA();
      }
 else {
        oursBeginB-=oursEdit.getBeginA() - theirsEdit.getBeginA();
      }
      Edit nextOursEdit=nextEdit(baseToOurs);
      Edit nextTheirsEdit=nextEdit(baseToTheirs);
      for (; ; ) {
        if (oursEdit.getEndA() > nextTheirsEdit.getBeginA()) {
          theirsEdit=nextTheirsEdit;
          nextTheirsEdit=nextEdit(baseToTheirs);
        }
 else         if (theirsEdit.getEndA() > nextOursEdit.getBeginA()) {
          oursEdit=nextOursEdit;
          nextOursEdit=nextEdit(baseToOurs);
        }
 else {
          break;
        }
      }
      int oursEndB=oursEdit.getEndB();
      int theirsEndB=theirsEdit.getEndB();
      if (oursEdit.getEndA() < theirsEdit.getEndA()) {
        oursEndB+=theirsEdit.getEndA() - oursEdit.getEndA();
      }
 else {
        theirsEndB+=oursEdit.getEndA() - theirsEdit.getEndA();
      }
      int conflictLen=Math.min(oursEndB - oursBeginB,theirsEndB - theirsBeginB);
      int commonPrefix=0;
      while (commonPrefix < conflictLen && cmp.equals(ours,oursBeginB + commonPrefix,theirs,theirsBeginB + commonPrefix))       commonPrefix++;
      conflictLen-=commonPrefix;
      int commonSuffix=0;
      while (commonSuffix < conflictLen && cmp.equals(ours,oursEndB - commonSuffix - 1,theirs,theirsEndB - commonSuffix - 1))       commonSuffix++;
      conflictLen-=commonSuffix;
      if (commonPrefix > 0)       result.add(1,oursBeginB,oursBeginB + commonPrefix,ConflictState.NO_CONFLICT);
      if (conflictLen > 0) {
        result.add(1,oursBeginB + commonPrefix,oursEndB - commonSuffix,ConflictState.FIRST_CONFLICTING_RANGE);
        result.add(2,theirsBeginB + commonPrefix,theirsEndB - commonSuffix,ConflictState.NEXT_CONFLICTING_RANGE);
      }
      if (commonSuffix > 0)       result.add(1,oursEndB - commonSuffix,oursEndB,ConflictState.NO_CONFLICT);
      current=Math.max(oursEdit.getEndA(),theirsEdit.getEndA());
      oursEdit=nextOursEdit;
      theirsEdit=nextTheirsEdit;
    }
  }
  if (current < base.size()) {
    result.add(0,current,base.size(),ConflictState.NO_CONFLICT);
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Does the three way merge between a common base and two sequences.
 * @param < S > type of sequence.
 * @param cmp comparison method for this execution.
 * @param base the common base sequence
 * @param ours the first sequence to be merged
 * @param theirs the second sequence to be merged
 * @return the resulting content
 */
public static <S extends Sequence>MergeResult<S> merge(SequenceComparator<S> cmp,S base,S ours,S theirs){
  List<S> sequences=new ArrayList<S>(3);
  sequences.add(base);
  sequences.add(ours);
  sequences.add(theirs);
  MergeResult result=new MergeResult<S>(sequences);
  EditList oursEdits=MyersDiff.INSTANCE.diff(cmp,base,ours);
  Iterator<Edit> baseToOurs=oursEdits.iterator();
  EditList theirsEdits=MyersDiff.INSTANCE.diff(cmp,base,theirs);
  Iterator<Edit> baseToTheirs=theirsEdits.iterator();
  int current=0;
  Edit oursEdit=nextEdit(baseToOurs);
  Edit theirsEdit=nextEdit(baseToTheirs);
  while (theirsEdit != END_EDIT || oursEdit != END_EDIT) {
    if (oursEdit.getEndA() <= theirsEdit.getBeginA()) {
      if (current != oursEdit.getBeginA()) {
        result.add(0,current,oursEdit.getBeginA(),ConflictState.NO_CONFLICT);
      }
      result.add(1,oursEdit.getBeginB(),oursEdit.getEndB(),ConflictState.NO_CONFLICT);
      current=oursEdit.getEndA();
      oursEdit=nextEdit(baseToOurs);
    }
 else     if (theirsEdit.getEndA() <= oursEdit.getBeginA()) {
      if (current != theirsEdit.getBeginA()) {
        result.add(0,current,theirsEdit.getBeginA(),ConflictState.NO_CONFLICT);
      }
      result.add(2,theirsEdit.getBeginB(),theirsEdit.getEndB(),ConflictState.NO_CONFLICT);
      current=theirsEdit.getEndA();
      theirsEdit=nextEdit(baseToTheirs);
    }
 else {
      if (oursEdit.getBeginA() != current && theirsEdit.getBeginA() != current) {
        result.add(0,current,Math.min(oursEdit.getBeginA(),theirsEdit.getBeginA()),ConflictState.NO_CONFLICT);
      }
      int oursBeginB=oursEdit.getBeginB();
      int theirsBeginB=theirsEdit.getBeginB();
      if (oursEdit.getBeginA() < theirsEdit.getBeginA()) {
        theirsBeginB-=theirsEdit.getBeginA() - oursEdit.getBeginA();
      }
 else {
        oursBeginB-=oursEdit.getBeginA() - theirsEdit.getBeginA();
      }
      Edit nextOursEdit=nextEdit(baseToOurs);
      Edit nextTheirsEdit=nextEdit(baseToTheirs);
      for (; ; ) {
        if (oursEdit.getEndA() > nextTheirsEdit.getBeginA()) {
          theirsEdit=nextTheirsEdit;
          nextTheirsEdit=nextEdit(baseToTheirs);
        }
 else         if (theirsEdit.getEndA() > nextOursEdit.getBeginA()) {
          oursEdit=nextOursEdit;
          nextOursEdit=nextEdit(baseToOurs);
        }
 else {
          break;
        }
      }
      int oursEndB=oursEdit.getEndB();
      int theirsEndB=theirsEdit.getEndB();
      if (oursEdit.getEndA() < theirsEdit.getEndA()) {
        oursEndB+=theirsEdit.getEndA() - oursEdit.getEndA();
      }
 else {
        theirsEndB+=oursEdit.getEndA() - theirsEdit.getEndA();
      }
      int minBSize=oursEndB - oursBeginB;
      int BSizeDelta=minBSize - (theirsEndB - theirsBeginB);
      if (BSizeDelta > 0)       minBSize-=BSizeDelta;
      int commonPrefix=0;
      while (commonPrefix < minBSize && cmp.equals(ours,oursBeginB + commonPrefix,theirs,theirsBeginB + commonPrefix))       commonPrefix++;
      minBSize-=commonPrefix;
      int commonSuffix=0;
      while (commonSuffix < minBSize && cmp.equals(ours,oursEndB - commonSuffix - 1,theirs,theirsEndB - commonSuffix - 1))       commonSuffix++;
      minBSize-=commonSuffix;
      if (commonPrefix > 0)       result.add(1,oursBeginB,oursBeginB + commonPrefix,ConflictState.NO_CONFLICT);
      if (minBSize > 0 || BSizeDelta != 0) {
        result.add(1,oursBeginB + commonPrefix,oursEndB - commonSuffix,ConflictState.FIRST_CONFLICTING_RANGE);
        result.add(2,theirsBeginB + commonPrefix,theirsEndB - commonSuffix,ConflictState.NEXT_CONFLICTING_RANGE);
      }
      if (commonSuffix > 0)       result.add(1,oursEndB - commonSuffix,oursEndB,ConflictState.NO_CONFLICT);
      current=Math.max(oursEdit.getEndA(),theirsEdit.getEndA());
      oursEdit=nextOursEdit;
      theirsEdit=nextTheirsEdit;
    }
  }
  if (current < base.size()) {
    result.add(0,current,base.size(),ConflictState.NO_CONFLICT);
  }
  return result;
}