Program: 16519
Project: 16519
Buggy source:
/** 
 * Returns the full sequence of the Atom records of a parent with X instead of HETATMSs. The advantage of this is that it allows us to also align HETATM groups back to the SEQRES.
 * @param groups the list of groups in a parent
 * @param positionIndex a Map to keep track of which group is at which sequence position
 * @return string representations
 */
public static String getFullAtomSequence(List<Group> groups,Map<Integer,Integer> positionIndex){
  StringBuffer sequence=new StringBuffer();
  int seqIndex=0;
  for (int i=0; i < groups.size(); i++) {
    Group g=groups.get(i);
    if (g instanceof AminoAcid) {
      AminoAcid a=(AminoAcid)g;
      char oneLetter=a.getAminoType();
      if (oneLetter == '?')       oneLetter='X';
      positionIndex.put(seqIndex,i);
      sequence.append(oneLetter);
      seqIndex++;
    }
 else {
      if (g.isWater())       continue;
      if (g.size() == 1) {
        Atom a=g.getAtom(0);
        if (a == null)         continue;
        if (a.getElement().isMetal())         continue;
      }
      ChemComp cc=g.getChemComp();
      if (cc == null) {
        logger.debug("String_Node_Str",g.toString());
        continue;
      }
      if (ResidueType.lPeptideLinking.equals(cc.getResidueType()) || PolymerType.PROTEIN_ONLY.contains(cc.getPolymerType()) || PolymerType.POLYNUCLEOTIDE_ONLY.contains(cc.getPolymerType())) {
        String c=cc.getOne_letter_code();
        if (c.equals("String_Node_Str"))         c="String_Node_Str";
        if (c.length() > 1) {
          logger.info("String_Node_Str",g.toString(),c);
        }
        for (int cIdx=0; cIdx < c.length(); cIdx++) {
          positionIndex.put(seqIndex,i);
          sequence.append(c.charAt(cIdx));
          seqIndex++;
        }
      }
 else {
        logger.debug("String_Node_Str",g.toString());
        continue;
      }
    }
  }
  return sequence.toString();
}

Fixed version (ground truth):
/** 
 * Returns the full sequence of the Atom records of a parent with X instead of HETATMSs. The advantage of this is that it allows us to also align HETATM groups back to the SEQRES.
 * @param groups the list of groups in a parent
 * @param positionIndex a Map to keep track of which group is at which sequence position
 * @param isNucleotideChain whether the atom groups are predominantly nucleotides (the groups represent a nucleotide chain), if truenon-standard nucleotides will be represented with ambiguous letter 'N' instead of 'X', if false all non-standard residues will be 'X'
 * @return string representations
 */
public static String getFullAtomSequence(List<Group> groups,Map<Integer,Integer> positionIndex,boolean isNucleotideChain){
  StringBuffer sequence=new StringBuffer();
  int seqIndex=0;
  for (int i=0; i < groups.size(); i++) {
    Group g=groups.get(i);
    if (g instanceof AminoAcid) {
      AminoAcid a=(AminoAcid)g;
      char oneLetter=a.getAminoType();
      if (oneLetter == '?')       oneLetter='X';
      positionIndex.put(seqIndex,i);
      sequence.append(oneLetter);
      seqIndex++;
    }
 else {
      if (g.isWater())       continue;
      if (g.size() == 1) {
        Atom a=g.getAtom(0);
        if (a == null)         continue;
        if (a.getElement().isMetal())         continue;
      }
      ChemComp cc=g.getChemComp();
      if (cc == null) {
        logger.debug("String_Node_Str",g.toString());
        continue;
      }
      if (ResidueType.lPeptideLinking.equals(cc.getResidueType()) || PolymerType.PROTEIN_ONLY.contains(cc.getPolymerType()) || PolymerType.POLYNUCLEOTIDE_ONLY.contains(cc.getPolymerType())) {
        String c=cc.getOne_letter_code();
        if (c.equals("String_Node_Str")) {
          if (isNucleotideChain && PolymerType.POLYNUCLEOTIDE_ONLY.contains(cc.getPolymerType())) {
            c="String_Node_Str";
          }
 else {
            c="String_Node_Str";
          }
        }
        if (c.length() > 1) {
          logger.info("String_Node_Str",g.toString(),c);
        }
        for (int cIdx=0; cIdx < c.length(); cIdx++) {
          positionIndex.put(seqIndex,i);
          sequence.append(c.charAt(cIdx));
          seqIndex++;
        }
      }
 else {
        logger.debug("String_Node_Str",g.toString());
        continue;
      }
    }
  }
  return sequence.toString();
}