Program: 32780
Project: 32780
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=TEMP_UNIQUE;
        }
      }
      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) {
      Object updated=duplicatesList.get(changeIndex);
      boolean wasDuplicate=(updated == DUPLICATE);
      boolean hadDuplicate=(updated == TEMP_UNIQUE);
      boolean wasUnique=(updated == UNIQUE);
      boolean isUnique=!handleOldNeighbour(changeIndex);
      int compressedIndex=duplicatesList.getCompressedIndex(changeIndex,true);
      if (isUnique) {
        if (wasUnique) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,true);
        }
 else {
          if (wasDuplicate)           enqueueEvent(ListEvent.UPDATE,compressedIndex - 1,false);
          enqueueEvent(ListEvent.INSERT,compressedIndex,true);
          if (hadDuplicate)           enqueueEvent(ListEvent.UPDATE,compressedIndex + 1,false);
        }
      }
 else {
        if (wasUnique) {
          enqueueEvent(ListEvent.DELETE,compressedIndex,true);
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
        }
 else {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
          if (compressedIndex + 1 < duplicatesList.getCompressedList().size())           enqueueEvent(ListEvent.UPDATE,compressedIndex + 1,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();
}

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 neighbourSide=handleOldNeighbour(changeIndex);
      if (neighbourSide != NEIGHBOUR_NONE) {
        enqueueEvent(ListEvent.UPDATE,duplicatesList.getCompressedIndex(changeIndex,true),false);
      }
 else {
        enqueueEvent(ListEvent.INSERT,duplicatesList.getCompressedIndex(changeIndex),true);
      }
    }
 else     if (changeType == ListEvent.UPDATE) {
      int oldNeighbourSide=0;
      Object updated=duplicatesList.get(changeIndex);
      if (updated == DUPLICATE)       oldNeighbourSide=NEIGHBOUR_LEFT;
 else       if (updated == TEMP_UNIQUE)       oldNeighbourSide=NEIGHBOUR_RIGHT;
 else       if (updated == UNIQUE)       oldNeighbourSide=NEIGHBOUR_NONE;
      int newNeighbourSide=handleOldNeighbour(changeIndex);
      int compressedIndex=duplicatesList.getCompressedIndex(changeIndex,true);
      if (newNeighbourSide == NEIGHBOUR_NONE) {
        if (oldNeighbourSide == NEIGHBOUR_NONE) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,true);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_LEFT) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex - 1,false);
          enqueueEvent(ListEvent.INSERT,compressedIndex,true);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_RIGHT) {
          enqueueEvent(ListEvent.INSERT,compressedIndex,true);
          enqueueEvent(ListEvent.UPDATE,compressedIndex + 1,false);
        }
      }
 else       if (newNeighbourSide == NEIGHBOUR_LEFT) {
        if (oldNeighbourSide == NEIGHBOUR_NONE) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
          enqueueEvent(ListEvent.DELETE,compressedIndex + 1,true);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_LEFT) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_RIGHT) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
          if (compressedIndex + 1 < duplicatesList.getCompressedList().size())           enqueueEvent(ListEvent.UPDATE,compressedIndex + 1,false);
        }
      }
 else       if (newNeighbourSide == NEIGHBOUR_RIGHT) {
        if (oldNeighbourSide == NEIGHBOUR_NONE) {
          enqueueEvent(ListEvent.DELETE,compressedIndex,true);
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_LEFT) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,false);
        }
 else         if (oldNeighbourSide == NEIGHBOUR_RIGHT) {
          enqueueEvent(ListEvent.UPDATE,compressedIndex,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();
}