Program: 54902
Project: 54902
Buggy source:
private static void removeInfectedUnits(final TreeLogger logger,final Map<String,CompilationUnitDeclaration> cudsByFileName){
  final Set<String> pendingRemovals=new HashSet<String>();
  TypeRefVisitor trv=new TypeRefVisitor(){
    @Override protected void onTypeRef(    SourceTypeBinding referencedType,    CompilationUnitDeclaration unitOfReferrer){
      String referencedFn=String.valueOf(referencedType.getFileName());
      CompilationUnitDeclaration referencedCud=cudsByFileName.get(referencedFn);
      if (referencedCud == null) {
        String referrerFn=String.valueOf(unitOfReferrer.getFileName());
        if (cudsByFileName.containsKey(referrerFn) && !pendingRemovals.contains(referrerFn)) {
          TreeLogger branch=logger.branch(TreeLogger.TRACE,"String_Node_Str" + referrerFn + "String_Node_Str",null);
          final String badTypeName=CharOperation.toString(referencedType.compoundName);
          branch.branch(TreeLogger.TRACE,"String_Node_Str" + badTypeName,null);
          pendingRemovals.add(referrerFn);
        }
      }
    }
  }
;
  do {
    for (Iterator<String> iter=pendingRemovals.iterator(); iter.hasNext(); ) {
      String fnToRemove=iter.next();
      Object removed=cudsByFileName.remove(fnToRemove);
      assert(removed != null);
    }
    pendingRemovals.clear();
    for (Iterator<CompilationUnitDeclaration> iter=cudsByFileName.values().iterator(); iter.hasNext(); ) {
      CompilationUnitDeclaration cud=iter.next();
      cud.traverse(trv,cud.scope);
    }
  }
 while (!pendingRemovals.isEmpty());
}

Fixed version (ground truth):
private static void removeInfectedUnits(final TreeLogger logger,final Map<String,CompilationUnitDeclaration> changedCudsByFileName,final Map<String,CompilationUnitDeclaration> unchangedCudsByFileName){
  final Set<String> pendingRemovals=new HashSet<String>();
  TypeRefVisitor trv=new TypeRefVisitor(){
    @Override protected void onTypeRef(    SourceTypeBinding referencedType,    CompilationUnitDeclaration unitOfReferrer){
      String referencedFn=String.valueOf(referencedType.getFileName());
      if (!unchangedCudsByFileName.containsKey(referencedFn) && !changedCudsByFileName.containsKey(referencedFn)) {
        String referrerFn=String.valueOf(unitOfReferrer.getFileName());
        if (changedCudsByFileName.containsKey(referrerFn) && !pendingRemovals.contains(referrerFn)) {
          TreeLogger branch=logger.branch(TreeLogger.TRACE,"String_Node_Str" + referrerFn + "String_Node_Str",null);
          final String badTypeName=CharOperation.toString(referencedType.compoundName);
          branch.branch(TreeLogger.TRACE,"String_Node_Str" + badTypeName,null);
          pendingRemovals.add(referrerFn);
        }
      }
    }
  }
;
  do {
    for (Iterator<String> iter=pendingRemovals.iterator(); iter.hasNext(); ) {
      String fnToRemove=iter.next();
      Object removed=changedCudsByFileName.remove(fnToRemove);
      assert(removed != null);
    }
    pendingRemovals.clear();
    for (Iterator<CompilationUnitDeclaration> iter=changedCudsByFileName.values().iterator(); iter.hasNext(); ) {
      CompilationUnitDeclaration cud=iter.next();
      cud.traverse(trv,cud.scope);
    }
  }
 while (!pendingRemovals.isEmpty());
}