@Override
 public void setSpeedAuthority(int blockId, int speed, int authority) {
   if (plcProgramA != null && plcProgramB != null) {
     if (blockId <= endBlock && blockId >= startBlock) {
       if (!(plcProgramA.stop(section.get(blockId - startBlock))
           && plcProgramB.stop(section.get(blockId - startBlock)))) {
         section.get(blockId - startBlock).setSpeedAuthority(speed, authority);
         if (section.get(blockId - startBlock).getMasterSwitch()
             || section.get(blockId - startBlock).hasRRCrossing()) {
           if (!(plcProgramA.slowDown(section.get(blockId - startBlock))
               && plcProgramB.slowDown(section.get(blockId - startBlock)))) {
             section.get(blockId - startBlock).setLight(1);
           } else {
             section.get(blockId - startBlock).setLight(2);
           }
         }
       } else {
         System.out.println("SAFETY CRITICAL: TRAIN MUST STOP");
         if (section.get(blockId - startBlock).getMasterSwitch()
             || section.get(blockId - startBlock).hasRRCrossing()) {
           section.get(blockId - startBlock).setLight(3);
         }
         section.get(blockId - startBlock).setSpeedAuthority(0, 0);
       }
     } else {
       System.err.println("ERROR: BLOCKID NOT CONTAINED WITHIN THIS CONTROLLER");
     }
   } else {
     System.err.println("ERROR: LOAD PLC PROGRAM");
   }
 }
  @Override
  public boolean markBlockForMaintanence(int blockId, boolean needsRepair) {
    if (blockId >= this.startBlock
        && blockId <= this.endBlock
        && this.startBlock != this.overlapBlock
        && plcProgramA != null
        && plcProgramB != null
        && plcProgramA.maintenance(section.get(blockId - this.startBlock))
        && plcProgramB.maintenance(section.get(blockId - this.startBlock))) {

      section.get(blockId - startBlock).setBlockOccupation(needsRepair);
      ;
      if (needsRepair) {
        this.ctc.setBlockOccupied(this.line, blockId);
      } else {
        this.ctc.setBlockUnoccupied(this.line, blockId);
      }
      return true;
    }
    return false;
  }
 @Override
 public boolean engageRRCrossing(int blockId, boolean engagement) {
   if (blockId >= startBlock
       && blockId <= endBlock
       && section.get(blockId - this.startBlock).hasRRCrossing()
       && plcProgramA != null
       && plcProgramB != null
       && plcProgramA.engageRRCrossing(section.get(blockId - startBlock))
       && plcProgramB.engageRRCrossing(section.get(blockId - startBlock))) {
     section.get(blockId - startBlock).setRRCrossingEngagement(engagement);
     return true;
   } else {
     System.err.println(
         "ERROR: "
             + this.line
             + " line TC#"
             + this.controllerId
             + "cannot engage crossing on block #"
             + blockId);
     return false;
   }
 }
 /** checks PLC logic and current switch engagement, switches engagement if different */
 @Override
 public boolean engageSwitch(String switchName, boolean engagement) {
   if (this.switchList.containsKey(switchName)) {
     Iterator<Block> switchBlockIterator = this.switchList.get(switchName).iterator();
     while (switchBlockIterator.hasNext()) {
       Block currBlock = switchBlockIterator.next();
       if (currBlock.getMasterSwitch()) {
         if (currBlock.isSwitchEngaged() != engagement
             && plcProgramA != null
             && plcProgramB != null
             && plcProgramA.engageSwitch(currBlock)
             && plcProgramB.engageSwitch(currBlock)) {
           currBlock.setSwitchEngagement();
           this.ctc.switchChanged(switchName, currBlock.getBlockNumber(), engagement);
           return true;
         }
       }
     }
     return false;
   } else {
     System.err.println("ERROR: THIS TC DOES NOT CONTAIN SWITCH  " + switchName);
     return false;
   }
 }