Program: 16379
Project: 16379
Buggy source:
/** 
 * Builds a Structure object containing the quaternary structure built from given asymUnit and transformations, by adding symmetry partners as new models. The output Structure will be different depending on the multiModel parameter: <li> the symmetry-expanded chains are added as new models, one per transformId. All original models but  the first one are discarded. </li> <li> as original with symmetry-expanded chains added with renamed chain ids and names (in the form  originalAsymId_transformId and originalAuthId_transformId) </li>
 * @param asymUnit
 * @param transformations
 * @param useAsymIds if true use {@link Chain#getId()} to match the ids in the BiologicalAssemblyTransformation (needed if data read from mmCIF), if false use  {@link Chain#getName()} for the chain matching (needed if data read from PDB).
 * @param multiModel if true the output Structure will be a multi-model one with one transformId per model, if false the outputStructure will be as the original with added chains with renamed asymIds (in the form originalAsymId_transformId and originalAuthId_transformId). 
 * @return
 */
public Structure rebuildQuaternaryStructure(Structure asymUnit,List<BiologicalAssemblyTransformation> transformations,boolean useAsymIds,boolean multiModel){
  orderTransformationsByChainId(asymUnit,transformations);
  Structure s=asymUnit.clone();
  s.resetModels();
  for (  BiologicalAssemblyTransformation transformation : transformations) {
    List<Chain> chainsToTransform=new ArrayList<>();
    if (useAsymIds) {
      Chain c=asymUnit.getChain(transformation.getChainId());
      chainsToTransform.add(c);
    }
 else {
      Chain polyC=asymUnit.getPolyChainByPDB(transformation.getChainId());
      List<Chain> nonPolyCs=asymUnit.getNonPolyChainsByPDB(transformation.getChainId());
      Chain waterC=asymUnit.getWaterChainByPDB(transformation.getChainId());
      if (polyC != null)       chainsToTransform.add(polyC);
      if (!nonPolyCs.isEmpty())       chainsToTransform.addAll(nonPolyCs);
      if (waterC != null)       chainsToTransform.add(waterC);
    }
    for (    Chain c : chainsToTransform) {
      Chain chain=(Chain)c.clone();
      for (      Group g : chain.getAtomGroups()) {
        for (        Atom a : g.getAtoms()) {
          transformation.transformPoint(a.getCoords());
        }
      }
      String transformId=transformation.getId();
      if (multiModel)       addChainMultiModel(s,chain,transformId);
 else       addChainFlattened(s,chain,transformId);
    }
  }
  s.setBiologicalAssembly(true);
  return s;
}

Fixed version (ground truth):
/** 
 * Builds a Structure object containing the quaternary structure built from given asymUnit and transformations, by adding symmetry partners as new models. The output Structure will be different depending on the multiModel parameter: <li> the symmetry-expanded chains are added as new models, one per transformId. All original models but  the first one are discarded. </li> <li> as original with symmetry-expanded chains added with renamed chain ids and names (in the form  originalAsymId_transformId and originalAuthId_transformId) </li>
 * @param asymUnit
 * @param transformations
 * @param useAsymIds if true use {@link Chain#getId()} to match the ids in the BiologicalAssemblyTransformation (needed if data read from mmCIF), if false use  {@link Chain#getName()} for the chain matching (needed if data read from PDB).
 * @param multiModel if true the output Structure will be a multi-model one with one transformId per model, if false the outputStructure will be as the original with added chains with renamed asymIds (in the form originalAsymId_transformId and originalAuthId_transformId). 
 * @return
 */
public Structure rebuildQuaternaryStructure(Structure asymUnit,List<BiologicalAssemblyTransformation> transformations,boolean useAsymIds,boolean multiModel){
  orderTransformationsByChainId(asymUnit,transformations);
  Structure s=asymUnit.clone();
  s.resetModels();
  for (  BiologicalAssemblyTransformation transformation : transformations) {
    List<Chain> chainsToTransform=new ArrayList<>();
    if (useAsymIds) {
      Chain c=asymUnit.getChain(transformation.getChainId());
      chainsToTransform.add(c);
    }
 else {
      Chain polyC=asymUnit.getPolyChainByPDB(transformation.getChainId());
      List<Chain> nonPolyCs=asymUnit.getNonPolyChainsByPDB(transformation.getChainId());
      Chain waterC=asymUnit.getWaterChainByPDB(transformation.getChainId());
      if (polyC != null)       chainsToTransform.add(polyC);
      if (!nonPolyCs.isEmpty())       chainsToTransform.addAll(nonPolyCs);
      if (waterC != null)       chainsToTransform.add(waterC);
    }
    for (    Chain c : chainsToTransform) {
      Chain chain=(Chain)c.clone();
      Calc.transform(chain,transformation.getTransformationMatrix());
      String transformId=transformation.getId();
      if (multiModel)       addChainMultiModel(s,chain,transformId);
 else       addChainFlattened(s,chain,transformId);
    }
  }
  s.setBiologicalAssembly(true);
  return s;
}