Program: 34558
Project: 34558
Buggy source:
/** 
 * Generates a list of corridor pieces and the next room piece. It only uses connections on the generated pieces, not on the starting piece. The new pieces are not added to the generated piece list, that is up to the calling method after validating the list. If the list has a different size than the selected corridor amount, it returns null instead.
 */
private List<StructureDungeonPieceInst> generateCorridorList(StructureDungeonPieceInst startPiece,Connection startConnection,StructureDungeonPieceArray roomArray,Random rand){
  int corridorAmount=piecesBetweenRooms.random(rand);
  final List<StructureDungeonPieceInst> pieces=new ArrayList<>(corridorAmount);
  final WeightedList<StructureDungeonPieceArray> corridorsAvailable=new WeightedList<>(corridors);
  final TObjectIntHashMap<StructureDungeonPieceArray> corridorCount=new TObjectIntHashMap<>(corridorAmount,Constants.DEFAULT_LOAD_FACTOR,0);
  for (int index=0; index < corridorAmount && corridorsAvailable.getTotalWeight() > 0; index++) {
    final StructureDungeonPieceInst targetPieceInst=index == 0 ? startPiece : pieces.get(index - 1);
    final Connection targetConnection=index == 0 ? startConnection : CollectionUtil.randomOrNull(targetPieceInst.findConnections(),rand);
    if (targetConnection == null)     break;
    for (int attempt=0; attempt < 51; attempt++) {
      if (attempt == 50)       return null;
      StructureDungeonPieceArray nextArray=corridorsAvailable.getRandomItem(rand);
      if (isDoor(nextArray) && !((index == 0 || index == corridorAmount - 1) && ((ISpreadingGeneratorPieceType)targetPieceInst.piece.type).isRoom()))       continue;
      if (corridorCount.get(nextArray) >= nextArray.amount.max)       continue;
      Pair<StructureDungeonPiece,Connection> nextPiece=findSuitablePiece(nextArray,targetConnection.facing,targetPieceInst.piece.type,rand);
      if (nextPiece != null && attempt < 50) {
        final Pos aligned=alignConnections(targetPieceInst,targetConnection,nextPiece.getRight());
        final Size pieceSize=nextPiece.getLeft().size;
        if (canPlaceAreaExtended(aligned,aligned.offset(pieceSize.sizeX - 1,pieceSize.sizeY - 1,pieceSize.sizeZ - 1),pieces)) {
          StructureDungeonPieceInst inst=new StructureDungeonPieceInst(nextPiece.getLeft(),aligned);
          inst.useConnection(nextPiece.getRight());
          if (index > 0)           targetPieceInst.useConnection(targetConnection);
          pieces.add(inst);
          corridorCount.adjustOrPutValue(nextArray,1,1);
          break;
        }
      }
    }
  }
  for (  StructureDungeonPieceArray corridorArray : corridors) {
    if (!corridorArray.amount.in(corridorCount.get(corridorArray)))     return null;
  }
  if (pieces.size() == corridorAmount) {
    final StructureDungeonPieceInst targetPieceInst=pieces.isEmpty() ? startPiece : pieces.get(pieces.size() - 1);
    final Connection targetConnection=pieces.isEmpty() ? startConnection : CollectionUtil.randomOrNull(targetPieceInst.findConnections(),rand);
    final Pair<StructureDungeonPiece,Connection> finalRoom=findSuitablePiece(roomArray,targetConnection.facing,targetPieceInst.piece.type,rand);
    if (finalRoom != null) {
      final Pos aligned=alignConnections(targetPieceInst,targetConnection,finalRoom.getRight());
      final Size pieceSize=finalRoom.getLeft().size;
      if (canPlaceAreaExtended(aligned,aligned.offset(pieceSize.sizeX - 1,pieceSize.sizeY - 1,pieceSize.sizeZ - 1),pieces)) {
        StructureDungeonPieceInst inst=new StructureDungeonPieceInst(finalRoom.getLeft(),aligned);
        inst.useConnection(finalRoom.getRight());
        pieces.get(pieces.size() - 1).useConnection(targetConnection);
        pieces.add(inst);
        return pieces;
      }
    }
  }
  return null;
}

Fixed version (ground truth):
/** 
 * Generates a list of corridor pieces and the next room piece. It only uses connections on the generated pieces, not on the starting piece. The new pieces are not added to the generated piece list, that is up to the calling method after validating the list. If the list has a different size than the selected corridor amount, it returns null instead.
 */
private List<StructureDungeonPieceInst> generateCorridorList(StructureDungeonPieceInst startPiece,Connection startConnection,StructureDungeonPieceArray roomArray,Random rand){
  int corridorAmount=piecesBetweenRooms.random(rand);
  final List<StructureDungeonPieceInst> pieces=new ArrayList<>(corridorAmount);
  final WeightedList<StructureDungeonPieceArray> corridorsAvailable=new WeightedList<>(corridors);
  final TObjectIntHashMap<StructureDungeonPieceArray> corridorCount=new TObjectIntHashMap<>(corridorAmount,Constants.DEFAULT_LOAD_FACTOR,0);
  for (int index=0; index < corridorAmount && corridorsAvailable.getTotalWeight() > 0; index++) {
    final StructureDungeonPieceInst targetPieceInst=index == 0 ? startPiece : pieces.get(index - 1);
    final Connection targetConnection=index == 0 ? startConnection : CollectionUtil.randomOrNull(targetPieceInst.findConnections(),rand);
    if (targetConnection == null)     break;
    for (int attempt=0; attempt < 51; attempt++) {
      if (attempt == 50)       return null;
      StructureDungeonPieceArray nextArray=corridorsAvailable.getRandomItem(rand);
      if (isDoor(nextArray) && !((index == 0 || index == corridorAmount - 1) && ((ISpreadingGeneratorPieceType)targetPieceInst.piece.type).isRoom()))       continue;
      if (corridorCount.get(nextArray) >= nextArray.amount.max)       continue;
      Pair<StructureDungeonPiece,Connection> nextPiece=findSuitablePiece(nextArray,targetConnection.facing,targetPieceInst.piece.type,rand);
      if (nextPiece != null) {
        final Pos aligned=alignConnections(targetPieceInst,targetConnection,nextPiece.getRight());
        final Size pieceSize=nextPiece.getLeft().size;
        if (canPlaceAreaExtended(aligned,aligned.offset(pieceSize.sizeX - 1,pieceSize.sizeY - 1,pieceSize.sizeZ - 1),pieces)) {
          StructureDungeonPieceInst inst=new StructureDungeonPieceInst(nextPiece.getLeft(),aligned);
          inst.useConnection(nextPiece.getRight());
          if (index > 0)           targetPieceInst.useConnection(targetConnection);
          pieces.add(inst);
          corridorCount.adjustOrPutValue(nextArray,1,1);
          break;
        }
      }
    }
  }
  for (  StructureDungeonPieceArray corridorArray : corridors) {
    if (!corridorArray.amount.in(corridorCount.get(corridorArray)))     return null;
  }
  if (pieces.size() == corridorAmount) {
    final StructureDungeonPieceInst targetPieceInst=pieces.isEmpty() ? startPiece : pieces.get(pieces.size() - 1);
    final Connection targetConnection=pieces.isEmpty() ? startConnection : CollectionUtil.randomOrNull(targetPieceInst.findConnections(),rand);
    final Pair<StructureDungeonPiece,Connection> finalRoom=findSuitablePiece(roomArray,targetConnection.facing,targetPieceInst.piece.type,rand);
    if (finalRoom != null) {
      final Pos aligned=alignConnections(targetPieceInst,targetConnection,finalRoom.getRight());
      final Size pieceSize=finalRoom.getLeft().size;
      if (canPlaceAreaExtended(aligned,aligned.offset(pieceSize.sizeX - 1,pieceSize.sizeY - 1,pieceSize.sizeZ - 1),pieces)) {
        StructureDungeonPieceInst inst=new StructureDungeonPieceInst(finalRoom.getLeft(),aligned);
        inst.useConnection(finalRoom.getRight());
        pieces.get(pieces.size() - 1).useConnection(targetConnection);
        pieces.add(inst);
        return pieces;
      }
    }
  }
  return null;
}