Program: 30676
Project: 30676
Buggy source:
/** 
 * Checks to see if there are clashes where different readers are using the same program group IDs. If they are then a new set of unique program group IDs are generated (across all program groups) otherwise the original program group headers are returned.
 * @param readers readers to combine
 * @return new list of program groups constructed from all the readers
 */
private List<SAMProgramRecord> mergeProgramGroups(final Collection<SAMFileReader> readers){
  final Map<String,SAMProgramRecord> seenGroupIds=new TreeMap<String,SAMProgramRecord>();
  int idx=0;
  for (  final SAMFileReader reader : readers) {
    final Map<String,String> groupIdTranslation=new HashMap<String,String>();
    samProgramGroupIdTranslation.put(reader,groupIdTranslation);
    for (    final SAMProgramRecord group : reader.getFileHeader().getProgramRecords()) {
      final String groupId=group.getProgramGroupId();
      final SAMProgramRecord seenGroup=seenGroupIds.get(groupId);
      if (seenGroup == null) {
        seenGroupIds.put(groupId,group);
        groupIdTranslation.put(groupId,groupId);
      }
 else       if (!group.equivalent(seenGroup)) {
        hasProgramGroupCollisions=true;
        String newGroupId;
        while (seenGroupIds.containsKey(newGroupId=Integer.toString(idx++)))         ;
        seenGroupIds.put(newGroupId,new SAMProgramRecord(newGroupId,group));
        groupIdTranslation.put(groupId,newGroupId);
      }
    }
  }
  return new ArrayList<SAMProgramRecord>(seenGroupIds.values());
}

Fixed version (ground truth):
/** 
 * Checks to see if there are clashes where different readers are using the same program group IDs. If yes, then those IDs that collided are remapped.
 * @param readers readers to combine
 * @return new list of program groups constructed from all the readers
 */
private List<SAMProgramRecord> mergeProgramGroups(final Collection<SAMFileReader> readers){
  final List<SAMProgramRecord> overallResult=new LinkedList<SAMProgramRecord>();
  final HashSet<String> idsThatAreAlreadyTaken=new HashSet<String>();
  List<HeaderRecordAndFileReader<SAMProgramRecord>> programGroupsLeftToProcess=new LinkedList<HeaderRecordAndFileReader<SAMProgramRecord>>();
  for (  final SAMFileReader reader : readers) {
    for (    final SAMProgramRecord programGroup : reader.getFileHeader().getProgramRecords()) {
      if (!idsThatAreAlreadyTaken.add(programGroup.getId()))       throw new PicardException("String_Node_Str" + reader + "String_Node_Str"+ programGroup.getId()+ "String_Node_Str");
      programGroupsLeftToProcess.add(new HeaderRecordAndFileReader<SAMProgramRecord>(programGroup,reader));
    }
    idsThatAreAlreadyTaken.clear();
  }
  List<HeaderRecordAndFileReader<SAMProgramRecord>> currentProgramGroups=new LinkedList<HeaderRecordAndFileReader<SAMProgramRecord>>();
  for (final Iterator<HeaderRecordAndFileReader<SAMProgramRecord>> programGroupsLeftToProcessIterator=programGroupsLeftToProcess.iterator(); programGroupsLeftToProcessIterator.hasNext(); ) {
    final HeaderRecordAndFileReader<SAMProgramRecord> pair=programGroupsLeftToProcessIterator.next();
    if (pair.getHeaderRecord().getAttribute(SAMProgramRecord.PREVIOUS_PROGRAM_GROUP_ID_TAG) == null) {
      programGroupsLeftToProcessIterator.remove();
      currentProgramGroups.add(pair);
    }
  }
  while (!currentProgramGroups.isEmpty()) {
    final List<SAMProgramRecord> currentResult=new LinkedList<SAMProgramRecord>();
    hasProgramGroupCollisions|=mergeHeaderRecords(currentProgramGroups,PROGRAM_RECORD_FACTORY,idsThatAreAlreadyTaken,samProgramGroupIdTranslation,currentResult);
    overallResult.addAll(currentResult);
    currentProgramGroups=translateIds(currentProgramGroups,samProgramGroupIdTranslation,false);
    programGroupsLeftToProcess=translateIds(programGroupsLeftToProcess,samProgramGroupIdTranslation,true);
    LinkedList<HeaderRecordAndFileReader<SAMProgramRecord>> programGroupsToProcessNext=new LinkedList<HeaderRecordAndFileReader<SAMProgramRecord>>();
    for (final Iterator<HeaderRecordAndFileReader<SAMProgramRecord>> programGroupsLeftToProcessIterator=programGroupsLeftToProcess.iterator(); programGroupsLeftToProcessIterator.hasNext(); ) {
      final HeaderRecordAndFileReader<SAMProgramRecord> pairLeftToProcess=programGroupsLeftToProcessIterator.next();
      final Object ppIdOfRecordLeftToProcess=pairLeftToProcess.getHeaderRecord().getAttribute(SAMProgramRecord.PREVIOUS_PROGRAM_GROUP_ID_TAG);
      for (      final HeaderRecordAndFileReader<SAMProgramRecord> justProcessedPair : currentProgramGroups) {
        String idJustProcessed=justProcessedPair.getHeaderRecord().getId();
        if (pairLeftToProcess.getFileReader() == justProcessedPair.getFileReader() && ppIdOfRecordLeftToProcess.equals(idJustProcessed)) {
          programGroupsLeftToProcessIterator.remove();
          programGroupsToProcessNext.add(pairLeftToProcess);
          break;
        }
      }
    }
    currentProgramGroups=programGroupsToProcessNext;
  }
  if (!programGroupsLeftToProcess.isEmpty()) {
    StringBuffer errorMsg=new StringBuffer(programGroupsLeftToProcess.size() + "String_Node_Str");
    for (    final HeaderRecordAndFileReader<SAMProgramRecord> pair : programGroupsLeftToProcess) {
      SAMProgramRecord record=pair.getHeaderRecord();
      errorMsg.append("String_Node_Str" + record.getProgramGroupId() + "String_Node_Str"+ record.getProgramName()+ "String_Node_Str"+ record.getPreviousProgramGroupId()+ "String_Node_Str");
    }
    throw new PicardException(errorMsg.toString());
  }
  Collections.sort(overallResult,RECORD_ID_COMPARATOR);
  return overallResult;
}