Program: 17000
Project: 17000
Buggy source:
/** 
 * @param a
 * @param ca1
 * @param ca2
 * @return
 * @throws StructureException if an error occured during superposition
 */
private static AFPChain splitBlocksByTopology(AFPChain a,Atom[] ca1,Atom[] ca2) throws StructureException {
  int[][][] optAln=a.getOptAln();
  int blockNum=a.getBlockNum();
  int[] optLen=a.getOptLen();
  List<Integer> newBlkLen=new ArrayList<Integer>();
  boolean blockChanged=false;
  for (int blk=0; blk < blockNum; blk++) {
    int currLen=1;
    for (int pos=1; pos < optLen[blk]; pos++) {
      if (optAln[blk][0][pos] <= optAln[blk][0][pos - 1] || optAln[blk][1][pos] <= optAln[blk][1][pos - 1]) {
        newBlkLen.add(currLen);
        currLen=0;
        blockChanged=true;
      }
      currLen++;
    }
    if (optLen[blk] < 2) {
      newBlkLen.add(optLen[blk]);
    }
 else {
      newBlkLen.add(currLen);
    }
  }
  if (!blockChanged) {
    return a;
  }
  List<int[][]> blocks=new ArrayList<int[][]>(newBlkLen.size());
  int oldBlk=0;
  int pos=0;
  for (  int blkLen : newBlkLen) {
    if (blkLen == optLen[oldBlk]) {
      assert(pos == 0);
      blocks.add(optAln[oldBlk]);
    }
 else {
      int[][] newBlock=new int[2][blkLen];
      assert(pos + blkLen <= optLen[oldBlk]);
      for (int i=0; i < blkLen; i++) {
        newBlock[0][i]=optAln[oldBlk][0][pos + i];
        newBlock[1][i]=optAln[oldBlk][1][pos + i];
      }
      pos+=blkLen;
      blocks.add(newBlock);
      if (pos == blkLen) {
        oldBlk++;
        pos=0;
      }
    }
  }
  int[][][] newOptAln=blocks.toArray((int[][][])null);
  int[] newBlockLens=new int[newBlkLen.size()];
  for (int i=0; i < newBlkLen.size(); i++) {
    newBlockLens[i]=newBlkLen.get(i);
  }
  return replaceOptAln(a,ca1,ca2,blocks.size(),newBlockLens,newOptAln);
}

Fixed version (ground truth):
/** 
 * @param a
 * @param ca1
 * @param ca2
 * @return
 * @throws StructureException if an error occured during superposition
 */
private static AFPChain splitBlocksByTopology(AFPChain a,Atom[] ca1,Atom[] ca2) throws StructureException {
  int[][][] optAln=a.getOptAln();
  int blockNum=a.getBlockNum();
  int[] optLen=a.getOptLen();
  List<Integer> newBlkLen=new ArrayList<Integer>();
  boolean blockChanged=false;
  for (int blk=0; blk < blockNum; blk++) {
    int currLen=1;
    for (int pos=1; pos < optLen[blk]; pos++) {
      if (optAln[blk][0][pos] <= optAln[blk][0][pos - 1] || optAln[blk][1][pos] <= optAln[blk][1][pos - 1]) {
        newBlkLen.add(currLen);
        currLen=0;
        blockChanged=true;
      }
      currLen++;
    }
    if (optLen[blk] < 2) {
      newBlkLen.add(optLen[blk]);
    }
 else {
      newBlkLen.add(currLen);
    }
  }
  if (!blockChanged) {
    return a;
  }
  List<int[][]> blocks=new ArrayList<int[][]>(newBlkLen.size());
  int oldBlk=0;
  int pos=0;
  for (  int blkLen : newBlkLen) {
    if (blkLen == optLen[oldBlk]) {
      assert(pos == 0);
      blocks.add(optAln[oldBlk]);
    }
 else {
      int[][] newBlock=new int[2][blkLen];
      assert(pos + blkLen <= optLen[oldBlk]);
      for (int i=0; i < blkLen; i++) {
        newBlock[0][i]=optAln[oldBlk][0][pos + i];
        newBlock[1][i]=optAln[oldBlk][1][pos + i];
      }
      pos+=blkLen;
      blocks.add(newBlock);
      if (pos == optLen[oldBlk]) {
        oldBlk++;
        pos=0;
      }
    }
  }
  int[][][] newOptAln=blocks.toArray(new int[0][][]);
  int[] newBlockLens=new int[newBlkLen.size()];
  for (int i=0; i < newBlkLen.size(); i++) {
    newBlockLens[i]=newBlkLen.get(i);
  }
  return replaceOptAln(a,ca1,ca2,blocks.size(),newBlockLens,newOptAln);
}