Program: 173345
Project: 173345
Buggy source:
/** 
 * Get a list of buyable trains for the currently operating company. Omit trains that the company has no money for. If there is no cash to buy any train from the Bank, prepare for emergency train buying.
 */
public void setBuyableTrains(){
  if (operatingCompany.value() == null)   return;
  int cash=operatingCompany.value().getCash();
  int cost=0;
  Set<Train> trains;
  boolean hasTrains=operatingCompany.value().getPortfolioModel().getNumberOfTrains() > 0;
  if (cash == 0 && hasTrains)   return;
  boolean canBuyTrainNow=canBuyTrainNow();
  boolean mustBuyTrain=!hasTrains && operatingCompany.value().mustOwnATrain();
  boolean emergency=false;
  SortedMap<Integer,Train> newEmergencyTrains=new TreeMap<Integer,Train>();
  SortedMap<Integer,Train> usedEmergencyTrains=new TreeMap<Integer,Train>();
  if (getCurrentPhase().canBuyMoreTrainsPerTurn() || trainsBoughtThisTurn.isEmpty()) {
    boolean mayBuyMoreOfEachType=getCurrentPhase().canBuyMoreTrainsPerTypePerTurn();
    trains=trainManager.getAvailableNewTrains();
    for (    Train train : trains) {
      if (!operatingCompany.value().mayBuyTrainType(train))       continue;
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getCertType())) {
        continue;
      }
      List<TrainType> types=train.getCertType().getPotentialTrainTypes();
      for (      TrainType type : types) {
        cost=type.getCost();
        if (cost <= cash) {
          if (canBuyTrainNow) {
            BuyTrain action=new BuyTrain(train,type,ipo.getParent(),cost);
            action.setForcedBuyIfNoRoute(mustBuyTrain);
            possibleActions.add(action);
          }
        }
 else         if (mustBuyTrain) {
          newEmergencyTrains.put(cost,train);
        }
      }
      if (train.canBeExchanged() && hasTrains) {
        cost=train.getCertType().getExchangeCost();
        if (cost <= cash) {
          Set<Train> exchangeableTrains=operatingCompany.value().getPortfolioModel().getUniqueTrains();
          BuyTrain action=new BuyTrain(train,ipo.getParent(),cost);
          action.setTrainsForExchange(exchangeableTrains);
          possibleActions.add(action);
          canBuyTrainNow=true;
        }
      }
      if (!canBuyTrainNow)       continue;
      for (      SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) {
        int reducedPrice=stb.getPrice(cost);
        if (reducedPrice > cash)         continue;
        BuyTrain bt=new BuyTrain(train,ipo.getParent(),reducedPrice);
        bt.setSpecialProperty(stb);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
    }
    if (!canBuyTrainNow)     return;
    trains=pool.getUniqueTrains();
    for (    Train train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getCertType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        BuyTrain bt=new BuyTrain(train,pool.getParent(),cost);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
 else       if (mustBuyTrain) {
        usedEmergencyTrains.put(cost,train);
      }
    }
    emergency=mustBuyTrain && possibleActions.getType(BuyTrain.class).isEmpty();
    if (emergency || getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MAY_ALWAYS_BUY_NEW_TRAIN) && !newEmergencyTrains.isEmpty()) {
      if (getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MUST_BUY_CHEAPEST_TRAIN)) {
        int cheapestTrainCost=newEmergencyTrains.firstKey();
        Train cheapestTrain=newEmergencyTrains.get(cheapestTrainCost);
        if (!usedEmergencyTrains.isEmpty() && usedEmergencyTrains.firstKey() < cheapestTrainCost) {
          cheapestTrainCost=usedEmergencyTrains.firstKey();
          cheapestTrain=usedEmergencyTrains.get(cheapestTrainCost);
        }
        BuyTrain bt=new BuyTrain(cheapestTrain,cheapestTrain.getOwner(),cheapestTrainCost);
        bt.setPresidentMustAddCash(cheapestTrainCost - cash);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
 else {
        for (        Train train : newEmergencyTrains.values()) {
          BuyTrain bt=new BuyTrain(train,ipo.getParent(),train.getCost());
          bt.setPresidentMustAddCash(train.getCost() - cash);
          bt.setForcedBuyIfNoRoute(mustBuyTrain);
          possibleActions.add(bt);
        }
        for (        Train train : usedEmergencyTrains.values()) {
          BuyTrain bt=new BuyTrain(train,pool.getParent(),train.getCost());
          bt.setPresidentMustAddCash(train.getCost() - cash);
          bt.setForcedBuyIfNoRoute(mustBuyTrain);
          possibleActions.add(bt);
        }
      }
    }
  }
  if (!canBuyTrainNow)   return;
  if (getCurrentPhase().isTrainTradingAllowed()) {
    BuyTrain bt;
    Player p;
    int index;
    int numberOfPlayers=playerManager.getNumberOfPlayers();
    int presidentCash=operatingCompany.value().getPresident().getCashValue();
    List<List<PublicCompany>> companiesPerPlayer=new ArrayList<List<PublicCompany>>(numberOfPlayers);
    for (int i=0; i < numberOfPlayers; i++)     companiesPerPlayer.add(new ArrayList<PublicCompany>(4));
    List<PublicCompany> companies;
    for (    PublicCompany c : getOperatingCompanies()) {
      if (c.isClosed() || c == operatingCompany.value())       continue;
      p=c.getPresident();
      index=p.getIndex();
      companiesPerPlayer.get(index).add(c);
    }
    int currentPlayerIndex=playerManager.getCurrentPlayer().getIndex();
    for (int i=currentPlayerIndex; i < currentPlayerIndex + numberOfPlayers; i++) {
      companies=companiesPerPlayer.get(i % numberOfPlayers);
      for (      PublicCompany company : companies) {
        trains=company.getPortfolioModel().getUniqueTrains();
        for (        Train train : trains) {
          if (train.isObsolete() || !train.isTradeable())           continue;
          bt=null;
          if (i != currentPlayerIndex && getGameParameterAsBoolean(GameDef.Parm.FIXED_PRICE_TRAINS_BETWEEN_PRESIDENTS) || operatingCompany.value().mustTradeTrainsAtFixedPrice() || company.mustTradeTrainsAtFixedPrice()) {
            if ((cash >= train.getCost()) && (operatingCompany.value().mayBuyTrainType(train))) {
              bt=new BuyTrain(train,company,train.getCost());
            }
 else {
              continue;
            }
          }
 else           if (cash > 0 || emergency && getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MAY_BUY_FROM_COMPANY)) {
            bt=new BuyTrain(train,company,0);
            if (emergency && cash < train.getCost()) {
              bt.setPresidentMayAddCash(Math.min(train.getCost() - cash,presidentCash));
            }
          }
          if (bt != null)           possibleActions.add(bt);
        }
      }
    }
  }
  if (!operatingCompany.value().mustOwnATrain() || operatingCompany.value().getPortfolioModel().getNumberOfTrains() > 0) {
    doneAllowed=true;
  }
}

Fixed version (ground truth):
/** 
 * Get a list of buyable trains for the currently operating company. Omit trains that the company has no money for. If there is no cash to buy any train from the Bank, prepare for emergency train buying.
 */
public void setBuyableTrains(){
  if (operatingCompany.value() == null)   return;
  int cash=operatingCompany.value().getCash();
  int cost=0;
  Set<Train> trains;
  boolean hasTrains=operatingCompany.value().getPortfolioModel().getNumberOfTrains() > 0;
  if (cash == 0 && hasTrains)   return;
  boolean canBuyTrainNow=canBuyTrainNow();
  boolean mustBuyTrain=!hasTrains && operatingCompany.value().mustOwnATrain();
  boolean emergency=false;
  SortedMap<Integer,Train> newEmergencyTrains=new TreeMap<Integer,Train>();
  SortedMap<Integer,Train> usedEmergencyTrains=new TreeMap<Integer,Train>();
  if (getCurrentPhase().canBuyMoreTrainsPerTurn() || trainsBoughtThisTurn.isEmpty()) {
    boolean mayBuyMoreOfEachType=getCurrentPhase().canBuyMoreTrainsPerTypePerTurn();
    trains=trainManager.getAvailableNewTrains();
    for (    Train train : trains) {
      if (!operatingCompany.value().mayBuyTrainType(train))       continue;
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getCertType())) {
        continue;
      }
      List<TrainType> types=train.getCertType().getPotentialTrainTypes();
      for (      TrainType type : types) {
        cost=type.getCost();
        if (cost <= cash) {
          if (canBuyTrainNow) {
            BuyTrain action=new BuyTrain(train,type,ipo.getParent(),cost);
            action.setForcedBuyIfNoRoute(mustBuyTrain);
            possibleActions.add(action);
          }
        }
 else         if (mustBuyTrain) {
          newEmergencyTrains.put(cost,train);
        }
      }
      if (train.canBeExchanged() && hasTrains) {
        cost=train.getCertType().getExchangeCost();
        if (cost <= cash) {
          Set<Train> exchangeableTrains=operatingCompany.value().getPortfolioModel().getUniqueTrains();
          BuyTrain action=new BuyTrain(train,ipo.getParent(),cost);
          action.setTrainsForExchange(exchangeableTrains);
          possibleActions.add(action);
          canBuyTrainNow=true;
        }
      }
      if (!canBuyTrainNow)       continue;
      for (      SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) {
        int reducedPrice=stb.getPrice(cost);
        if (reducedPrice > cash)         continue;
        BuyTrain bt=new BuyTrain(train,ipo.getParent(),reducedPrice);
        bt.setSpecialProperty(stb);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
    }
    if (!canBuyTrainNow)     return;
    trains=pool.getUniqueTrains();
    for (    Train train : trains) {
      if (!mayBuyMoreOfEachType && trainsBoughtThisTurn.contains(train.getCertType())) {
        continue;
      }
      cost=train.getCost();
      if (cost <= cash) {
        BuyTrain bt=new BuyTrain(train,pool.getParent(),cost);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
 else       if (mustBuyTrain) {
        usedEmergencyTrains.put(cost,train);
      }
    }
    emergency=mustBuyTrain && possibleActions.getType(BuyTrain.class).isEmpty();
    if (emergency || getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MAY_ALWAYS_BUY_NEW_TRAIN) && !newEmergencyTrains.isEmpty()) {
      if (getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MUST_BUY_CHEAPEST_TRAIN)) {
        int cheapestTrainCost=newEmergencyTrains.firstKey();
        Train cheapestTrain=newEmergencyTrains.get(cheapestTrainCost);
        if (!usedEmergencyTrains.isEmpty() && usedEmergencyTrains.firstKey() < cheapestTrainCost) {
          cheapestTrainCost=usedEmergencyTrains.firstKey();
          cheapestTrain=usedEmergencyTrains.get(cheapestTrainCost);
        }
        BuyTrain bt=new BuyTrain(cheapestTrain,cheapestTrain.getOwner(),cheapestTrainCost);
        bt.setPresidentMustAddCash(cheapestTrainCost - cash);
        bt.setForcedBuyIfNoRoute(mustBuyTrain);
        possibleActions.add(bt);
      }
 else {
        for (        Train train : newEmergencyTrains.values()) {
          BuyTrain bt=new BuyTrain(train,ipo.getParent(),train.getCost());
          bt.setPresidentMustAddCash(train.getCost() - cash);
          bt.setForcedBuyIfNoRoute(mustBuyTrain);
          possibleActions.add(bt);
        }
        for (        Train train : usedEmergencyTrains.values()) {
          BuyTrain bt=new BuyTrain(train,pool.getParent(),train.getCost());
          bt.setPresidentMustAddCash(train.getCost() - cash);
          bt.setForcedBuyIfNoRoute(mustBuyTrain);
          possibleActions.add(bt);
        }
      }
    }
  }
  if (!canBuyTrainNow)   return;
  if (getCurrentPhase().isTrainTradingAllowed()) {
    BuyTrain bt;
    Player p;
    int index;
    int numberOfPlayers=playerManager.getNumberOfPlayers();
    int presidentCash=operatingCompany.value().getPresident().getCashValue();
    List<List<PublicCompany>> companiesPerPlayer=new ArrayList<List<PublicCompany>>(numberOfPlayers);
    for (int i=0; i < numberOfPlayers; i++)     companiesPerPlayer.add(new ArrayList<PublicCompany>(4));
    List<PublicCompany> companies;
    for (    PublicCompany c : companyManager.getAllPublicCompanies()) {
      if (!c.hasFloated())       continue;
      if (c.isClosed() || c == operatingCompany.value())       continue;
      p=c.getPresident();
      index=p.getIndex();
      companiesPerPlayer.get(index).add(c);
    }
    int currentPlayerIndex=playerManager.getCurrentPlayer().getIndex();
    for (int i=currentPlayerIndex; i < currentPlayerIndex + numberOfPlayers; i++) {
      companies=companiesPerPlayer.get(i % numberOfPlayers);
      for (      PublicCompany company : companies) {
        trains=company.getPortfolioModel().getUniqueTrains();
        for (        Train train : trains) {
          if (train.isObsolete() || !train.isTradeable())           continue;
          bt=null;
          if (i != currentPlayerIndex && getGameParameterAsBoolean(GameDef.Parm.FIXED_PRICE_TRAINS_BETWEEN_PRESIDENTS) || operatingCompany.value().mustTradeTrainsAtFixedPrice() || company.mustTradeTrainsAtFixedPrice()) {
            if ((cash >= train.getCost()) && (operatingCompany.value().mayBuyTrainType(train))) {
              bt=new BuyTrain(train,company,train.getCost());
            }
 else {
              continue;
            }
          }
 else           if (cash > 0 || emergency && getGameParameterAsBoolean(GameDef.Parm.EMERGENCY_MAY_BUY_FROM_COMPANY)) {
            bt=new BuyTrain(train,company,0);
            if (emergency && cash < train.getCost()) {
              bt.setPresidentMayAddCash(Math.min(train.getCost() - cash,presidentCash));
            }
          }
          if (bt != null)           possibleActions.add(bt);
        }
      }
    }
  }
  if (!operatingCompany.value().mustOwnATrain() || operatingCompany.value().getPortfolioModel().getNumberOfTrains() > 0) {
    doneAllowed=true;
  }
}