Program: 173569
Project: 173569
Buggy source:
public boolean buyTrain(BuyTrain action){
  Train train=action.getTrain();
  PublicCompany company=action.getCompany();
  String companyName=company.getId();
  Train exchangedTrain=action.getExchangedTrain();
  SpecialTrainBuy stb=null;
  String errMsg=null;
  int presidentCash=action.getPresidentCashToAdd();
  boolean presidentMustSellShares=false;
  int price=action.getPricePaid();
  int actualPresidentCash=0;
  int cashToBeRaisedByPresident=0;
  Player currentPlayer=operatingCompany.value().getPresident();
  while (true) {
    if (getStep() != GameDef.OrStep.BUY_TRAIN) {
      errMsg=LocalText.getText("String_Node_Str");
      break;
    }
    if (train == null) {
      errMsg=LocalText.getText("String_Node_Str");
      break;
    }
    if (price < 0) {
      errMsg=LocalText.getText("String_Node_Str",Currency.format(this,price));
      break;
    }
    int fixedPrice=action.getFixedCost();
    if (fixedPrice != 0 && fixedPrice != price) {
      errMsg=LocalText.getText("String_Node_Str",Currency.format(this,price),Currency.format(this,fixedPrice));
    }
    int trainLimit=operatingCompany.value().getCurrentTrainLimit();
    if (!canBuyTrainNow() && !action.isForExchange()) {
      errMsg=LocalText.getText("String_Node_Str",String.valueOf(trainLimit));
      break;
    }
    if (action.mustPresidentAddCash()) {
      presidentCash=action.getPresidentCashToAdd();
      if (currentPlayer.getCashValue() >= presidentCash) {
        actualPresidentCash=presidentCash;
      }
 else {
        presidentMustSellShares=true;
        cashToBeRaisedByPresident=presidentCash - currentPlayer.getCashValue();
      }
    }
 else     if (action.mayPresidentAddCash()) {
      presidentCash=price - operatingCompany.value().getCash();
      if (presidentCash > action.getPresidentCashToAdd()) {
        errMsg=LocalText.getText("String_Node_Str",Currency.format(this,action.getPresidentCashToAdd()));
        break;
      }
 else       if (currentPlayer.getCashValue() >= presidentCash) {
        actualPresidentCash=presidentCash;
      }
 else {
        presidentMustSellShares=true;
        cashToBeRaisedByPresident=presidentCash - currentPlayer.getCashValue();
      }
    }
 else {
      if (price > operatingCompany.value().getCash()) {
        errMsg=LocalText.getText("String_Node_Str",companyName,Currency.format(this,operatingCompany.value().getCash()),Currency.format(this,price));
        break;
      }
    }
    if (action.isForExchange()) {
      if (exchangedTrain == null) {
        errMsg=LocalText.getText("String_Node_Str");
        break;
      }
 else       if (operatingCompany.value().getPortfolioModel().getTrainOfType(exchangedTrain.getCertType()) == null) {
        errMsg=LocalText.getText("String_Node_Str",operatingCompany.value().getId(),exchangedTrain.getId());
        break;
      }
    }
    stb=action.getSpecialProperty();
    break;
  }
  if (errMsg != null) {
    DisplayBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),Currency.format(this,price),errMsg));
    return false;
  }
  ChangeStack.start(this,action);
  Phase previousPhase=getCurrentPhase();
  if (presidentMustSellShares) {
    savedAction=action;
    gameManager.startShareSellingRound(operatingCompany.value().getPresident(),cashToBeRaisedByPresident,operatingCompany.value(),true);
    return true;
  }
  if (actualPresidentCash > 0) {
    String cashText=Currency.wire(currentPlayer,actualPresidentCash,operatingCompany.value());
    ReportBuffer.add(LocalText.getText("String_Node_Str",operatingCompany.value().getId(),currentPlayer.getId(),cashText));
  }
  Owner oldOwner=train.getOwner();
  if (exchangedTrain != null) {
    Train oldTrain=operatingCompany.value().getPortfolioModel().getTrainOfType(exchangedTrain.getCertType());
    (train.isObsolete() ? scrapHeap : pool).addTrain(oldTrain);
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,exchangedTrain.getId(),train.getId(),oldOwner.getId(),Currency.format(this,price)));
  }
 else   if (stb == null) {
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),oldOwner.getId(),Currency.format(this,price)));
  }
 else {
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),oldOwner.getId(),Currency.format(this,price),stb.getOriginalCompany().getId()));
  }
  train.setType(action.getType());
  operatingCompany.value().buyTrain(train,price);
  if (oldOwner == ipo.getTrainsModel()) {
    train.getCertType().addToBoughtFromIPO();
    trainManager.setAnyTrainBought(true);
    if (train.getCertType().hasInfiniteQuantity()) {
      ipo.addTrain(trainManager.cloneTrain(train.getCertType()));
    }
  }
  if (oldOwner instanceof Bank) {
    trainsBoughtThisTurn.add(train.getCertType());
  }
  if (stb != null) {
    stb.setExercised();
    log.debug("String_Node_Str");
  }
  trainManager.checkTrainAvailability(train,oldOwner);
  if (getCurrentPhase() != previousPhase && checkForExcessTrains()) {
    stepObject.set(GameDef.OrStep.DISCARD_TRAINS);
  }
  if (trainManager.hasPhaseChanged())   newPhaseChecks();
  return true;
}

Fixed version (ground truth):
public boolean buyTrain(BuyTrain action){
  Train train=action.getTrain();
  PublicCompany company=action.getCompany();
  String companyName=company.getId();
  Train exchangedTrain=action.getExchangedTrain();
  SpecialTrainBuy stb=null;
  String errMsg=null;
  int presidentCash=action.getPresidentCashToAdd();
  boolean presidentMustSellShares=false;
  int price=action.getPricePaid();
  int actualPresidentCash=0;
  int cashToBeRaisedByPresident=0;
  Player currentPlayer=operatingCompany.value().getPresident();
  while (true) {
    if (getStep() != GameDef.OrStep.BUY_TRAIN) {
      errMsg=LocalText.getText("String_Node_Str");
      break;
    }
    if (train == null) {
      errMsg=LocalText.getText("String_Node_Str");
      break;
    }
    if (price < 0) {
      errMsg=LocalText.getText("String_Node_Str",Currency.format(this,price));
      break;
    }
    int fixedPrice=action.getFixedCost();
    if (fixedPrice != 0 && fixedPrice != price) {
      errMsg=LocalText.getText("String_Node_Str",Currency.format(this,price),Currency.format(this,fixedPrice));
    }
    int trainLimit=operatingCompany.value().getCurrentTrainLimit();
    if (!canBuyTrainNow() && !action.isForExchange()) {
      errMsg=LocalText.getText("String_Node_Str",String.valueOf(trainLimit));
      break;
    }
    if (action.mustPresidentAddCash()) {
      presidentCash=action.getPresidentCashToAdd();
      if (currentPlayer.getCashValue() >= presidentCash) {
        actualPresidentCash=presidentCash;
      }
 else {
        presidentMustSellShares=true;
        cashToBeRaisedByPresident=presidentCash - currentPlayer.getCashValue();
      }
    }
 else     if (action.mayPresidentAddCash()) {
      presidentCash=price - operatingCompany.value().getCash();
      if (presidentCash > action.getPresidentCashToAdd()) {
        errMsg=LocalText.getText("String_Node_Str",Currency.format(this,action.getPresidentCashToAdd()));
        break;
      }
 else       if (currentPlayer.getCashValue() >= presidentCash) {
        actualPresidentCash=presidentCash;
      }
 else {
        presidentMustSellShares=true;
        cashToBeRaisedByPresident=presidentCash - currentPlayer.getCashValue();
      }
    }
 else {
      if (price > operatingCompany.value().getCash()) {
        errMsg=LocalText.getText("String_Node_Str",companyName,Currency.format(this,operatingCompany.value().getCash()),Currency.format(this,price));
        break;
      }
    }
    if (action.isForExchange()) {
      if (exchangedTrain == null) {
        errMsg=LocalText.getText("String_Node_Str");
        break;
      }
 else       if (operatingCompany.value().getPortfolioModel().getTrainOfType(exchangedTrain.getCertType()) == null) {
        errMsg=LocalText.getText("String_Node_Str",operatingCompany.value().getId(),exchangedTrain.getId());
        break;
      }
    }
    stb=action.getSpecialProperty();
    break;
  }
  if (errMsg != null) {
    DisplayBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),Currency.format(this,price),errMsg));
    return false;
  }
  ChangeStack.start(this,action);
  Phase previousPhase=getCurrentPhase();
  if (presidentMustSellShares) {
    savedAction=action;
    gameManager.startShareSellingRound(operatingCompany.value().getPresident(),cashToBeRaisedByPresident,operatingCompany.value(),true);
    return true;
  }
  if (actualPresidentCash > 0) {
    String cashText=Currency.wire(currentPlayer,actualPresidentCash,operatingCompany.value());
    ReportBuffer.add(LocalText.getText("String_Node_Str",operatingCompany.value().getId(),currentPlayer.getId(),cashText));
  }
  Owner oldOwner=train.getOwner();
  if (exchangedTrain != null) {
    Train oldTrain=operatingCompany.value().getPortfolioModel().getTrainOfType(exchangedTrain.getCertType());
    (train.isObsolete() ? scrapHeap : pool).addTrain(oldTrain);
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,exchangedTrain.getId(),train.getId(),oldOwner.getId(),Currency.format(this,price)));
  }
 else   if (stb == null) {
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),oldOwner.getId(),Currency.format(this,price)));
  }
 else {
    ReportBuffer.add(LocalText.getText("String_Node_Str",companyName,train.getId(),oldOwner.getId(),Currency.format(this,price),stb.getOriginalCompany().getId()));
  }
  train.setType(action.getType());
  operatingCompany.value().buyTrain(train,price);
  if (oldOwner == ipo.getParent()) {
    train.getCertType().addToBoughtFromIPO();
    trainManager.setAnyTrainBought(true);
    if (train.getCertType().hasInfiniteQuantity()) {
      ipo.addTrain(trainManager.cloneTrain(train.getCertType()));
    }
  }
  if (oldOwner instanceof BankPortfolio) {
    trainsBoughtThisTurn.add(train.getCertType());
  }
  if (stb != null) {
    stb.setExercised();
    log.debug("String_Node_Str");
  }
  trainManager.checkTrainAvailability(train,oldOwner);
  if (getCurrentPhase() != previousPhase && checkForExcessTrains()) {
    stepObject.set(GameDef.OrStep.DISCARD_TRAINS);
  }
  if (trainManager.hasPhaseChanged())   newPhaseChecks();
  return true;
}