Program: 32790
Project: 32790
Buggy source:
/** 
 * {@inheritDoc} 
 */
public void listChanged(ListEvent listChanges){
  ListEvent firstPass=new ListEvent(listChanges);
  ListEvent secondPass=listChanges;
  LinkedList removedValues=new LinkedList();
  while (firstPass.next()) {
    int changeIndex=firstPass.getIndex();
    int changeType=firstPass.getType();
    if (changeType == ListEvent.INSERT) {
      duplicatesList.add(changeIndex,TEMP_UNIQUE);
    }
 else     if (changeType == ListEvent.UPDATE) {
      Object replaced=duplicatesList.get(changeIndex);
      if (replaced == UNIQUE) {
        if (changeIndex + 1 < duplicatesList.size() && duplicatesList.get(changeIndex + 1) == DUPLICATE) {
          duplicatesList.set(changeIndex,TEMP_UNIQUE);
          duplicatesList.set(changeIndex + 1,UNIQUE);
          replaced=null;
        }
      }
    }
 else     if (changeType == ListEvent.DELETE) {
      Object deleted=duplicatesList.remove(changeIndex);
      if (deleted == UNIQUE) {
        if (changeIndex < duplicatesList.size() && duplicatesList.get(changeIndex) == DUPLICATE) {
          duplicatesList.set(changeIndex,UNIQUE);
          deleted=null;
        }
      }
      removedValues.addLast(deleted);
    }
  }
  updates.beginEvent();
  while (secondPass.next()) {
    int changeIndex=secondPass.getIndex();
    int changeType=secondPass.getType();
    if (changeType == ListEvent.INSERT) {
      boolean hasNeighbour=handleOldNeighbour(changeIndex);
      if (hasNeighbour) {
        enqueueEvent(ListEvent.UPDATE,duplicatesList.getCompressedIndex(changeIndex,true),false);
      }
 else {
        enqueueEvent(ListEvent.INSERT,duplicatesList.getCompressedIndex(changeIndex),true);
      }
    }
 else     if (changeType == ListEvent.UPDATE) {
      boolean wasUnique=(duplicatesList.get(changeIndex) == UNIQUE);
      boolean hasNeighbour=handleOldNeighbour(changeIndex);
      if (hasNeighbour) {
        if (wasUnique) {
          enqueueEvent(ListEvent.DELETE,duplicatesList.getCompressedIndex(changeIndex,true),true);
        }
 else {
          enqueueEvent(ListEvent.UPDATE,duplicatesList.getCompressedIndex(changeIndex,true),false);
        }
      }
 else {
        if (wasUnique) {
          enqueueEvent(ListEvent.UPDATE,duplicatesList.getCompressedIndex(changeIndex),true);
        }
 else {
          enqueueEvent(ListEvent.INSERT,duplicatesList.getCompressedIndex(changeIndex),true);
        }
      }
    }
 else     if (changeType == ListEvent.DELETE) {
      boolean wasUnique=(removedValues.removeFirst() == UNIQUE);
      int deletedIndex=-1;
      if (changeIndex < duplicatesList.size())       deletedIndex=duplicatesList.getCompressedIndex(changeIndex,true);
 else       deletedIndex=duplicatesList.getCompressedList().size();
      if (wasUnique) {
        enqueueEvent(ListEvent.DELETE,deletedIndex,true);
      }
 else {
        enqueueEvent(ListEvent.UPDATE,deletedIndex,false);
      }
    }
  }
  flushEnqueuedEvents();
  updates.commitEvent();
}

Fixed version (ground truth):
/** 
 * {@inheritDoc} 
 */
public void listChanged(ListEvent listChanges){
  ListEvent firstPass=new ListEvent(listChanges);
  ListEvent secondPass=listChanges;
  LinkedList removedValues=new LinkedList();
  while (firstPass.next()) {
    int changeIndex=firstPass.getIndex();
    int changeType=firstPass.getType();
    if (changeType == ListEvent.INSERT) {
      duplicatesList.add(changeIndex,TEMP_UNIQUE);
    }
 else     if (changeType == ListEvent.UPDATE) {
      Object replaced=duplicatesList.get(changeIndex);
      if (replaced == UNIQUE) {
        if (changeIndex + 1 < duplicatesList.size() && duplicatesList.get(changeIndex + 1) == DUPLICATE) {
          duplicatesList.set(changeIndex,TEMP_UNIQUE);
          duplicatesList.set(changeIndex + 1,UNIQUE);
          replaced=null;
        }
      }
    }
 else     if (changeType == ListEvent.DELETE) {
      Object deleted=duplicatesList.remove(changeIndex);
      if (deleted == UNIQUE) {
        if (changeIndex < duplicatesList.size() && duplicatesList.get(changeIndex) == DUPLICATE) {
          duplicatesList.set(changeIndex,UNIQUE);
          deleted=TEMP_UNIQUE;
        }
      }
      removedValues.addLast(deleted);
    }
  }
  updates.beginEvent();
  while (secondPass.next()) {
    int changeIndex=secondPass.getIndex();
    int changeType=secondPass.getType();
    if (changeType == ListEvent.INSERT) {
      int hasNeighbour=handleOldNeighbour(changeIndex);
      if (hasNeighbour != 0) {
        enqueueEvent(ListEvent.UPDATE,duplicatesList.getCompressedIndex(changeIndex,true),false);
      }
 else {
        enqueueEvent(ListEvent.INSERT,duplicatesList.getCompressedIndex(changeIndex),true);
      }
    }
 else     if (changeType == ListEvent.UPDATE) {
      Object updated=duplicatesList.get(changeIndex);
      boolean hadDuplicateOnRight=(updated == TEMP_UNIQUE);
      boolean hadDuplicateOnLeft=(updated == DUPLICATE);
      boolean hadNoDuplicate=(updated == DUPLICATE);
      int hasNeighbour=handleOldNeighbour(changeIndex);
      boolean duplicateOnRight=(hasNeighbour == 1);
      boolean duplicateOnLeft=(hasNeighbour == -1);
      boolean noDuplicate=(hasNeighbour == 0);
      int compressedIndex=duplicatesList.getCompressedIndex(changeIndex,true);
      int rightNeighbourIndex=compressedIndex + 1;
      if (hadDuplicateOnLeft)       enqueueEvent(ListEvent.UPDATE,compressedIndex - 1,false);
      if (hasNeighbour != 0) {
        if (updated == UNIQUE) {
          enqueueEvent(ListEvent.DELETE,compressedIndex,true);
          rightNeighbourIndex--;
        }
 else {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
        }
      }
 else {
        if (updated == UNIQUE) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,true);
        }
 else {
          enqueueEvent(ListEvent.INSERT,compressedIndex,true);
        }
      }
      if (rightNeighbourIndex < duplicatesList.getCompressedList().size())       enqueueEvent(ListEvent.UPDATE,rightNeighbourIndex,false);
    }
 else     if (changeType == ListEvent.DELETE) {
      Object deleted=removedValues.removeFirst();
      int uncompressedIndex=-1;
      if (deleted == DUPLICATE)       uncompressedIndex=changeIndex - 1;
 else       uncompressedIndex=changeIndex;
      int deletedIndex=-1;
      if (uncompressedIndex < duplicatesList.size())       deletedIndex=duplicatesList.getCompressedIndex(uncompressedIndex,true);
 else       deletedIndex=duplicatesList.getCompressedList().size();
      if (deleted == UNIQUE) {
        enqueueEvent(ListEvent.DELETE,deletedIndex,true);
      }
 else {
        enqueueEvent(ListEvent.UPDATE,deletedIndex,false);
      }
    }
  }
  flushEnqueuedEvents();
  updates.commitEvent();
}