/**
   * If only one toolhead is used, a cool command for the unused head is added to this gcode source
   * object. Created to avoid smell/problems for single prints on a dual machine when prior build
   * was cancelled, or a toolhead is left hot from pre-heating.
   */
  public void coolUnusedToolhead() {
    GCodeCommand gcode;
    String line;

    double tval;
    int additionPoint = 0;
    boolean addPointFound = false;

    boolean seenT0 = false;
    boolean seenT1 = false;

    for (Iterator<String> it = source.iterator(); it.hasNext(); ) {
      line = it.next();
      gcode = new GCodeCommand(line);

      tval = gcode.getCodeValue('T');

      if (tval == 0) seenT0 = true;
      if (tval == 1) seenT1 = true;

      if (!addPointFound) additionPoint++;

      if (gcode.getCodeValue('M') == 104) addPointFound = true;

      if (seenT0 && seenT1) return;
    }

    if (seenT0 && !seenT1) add(additionPoint, "M104 T1 S0");
    if (seenT1 && !seenT0) add(additionPoint, "M104 T0 S0");
  }
  /**
   * This method handles shuffling together two gcodes, it first executes preprocessing and then
   * hands the gcodes off to Layer_Helper
   */
  public void combine() {
    MutableGCodeSource left, right;

    // load our layers into something we can use
    left = new MutableGCodeSource(leftFile);
    right = new MutableGCodeSource(rightFile);

    // remove  some tags we don't want/get
    SkeinforgePostProcessor.stripNonLayerTagComments(left);
    SkeinforgePostProcessor.stripNonLayerTagComments(right);

    // load our layers into something we can *really* use
    LinkedList<Layer> leftLayers = parseLayers(left);
    LinkedList<Layer> rightLayers = parseLayers(right);

    // merge our layers into one list
    final LinkedList<Layer> layers = doMerge(leftLayers, rightLayers);

    // refresh and repopulate our result
    result = new MutableGCodeSource();
    for (Layer l : layers) {
      result.add(l.getCommands());
    }

    // add start gcode, updated based on settings
    SkeinforgePostProcessor.prependAndModifyStartCode(result, startGCode);
    // add end code
    Layer endLayer = new Layer(Double.MAX_VALUE, endGCode.asList());
    result.add(endLayer.toString());
    // interlace progress updates
    result.addProgressUpdates();
  }
  /**
   * does the post-processing, called by Slic3r Generator
   *
   * @return
   */
  protected BuildCode runPostProcessing() {
    // Load our code to a source iterator
    source = new MutableGCodeSource(generator.output.file);

    if (!dualstruding) {
      if (prependStart) runPrepend(startCode);
      if (appendEnd) runAppend(endCode);

      if (!multiHead) toolheadTarget = ToolheadAlias.SINGLE;

      if (toolheadTarget != null) runToolheadSwap(toolheadTarget);
    }

    // these display the build % on The Replicator
    if (addProgressUpdates) {
      source.addSlic3rProgressUpdates();
    }

    if (prependMetaInfo) {
      MutableGCodeSource metaInfo = new MutableGCodeSource();
      String curDate = getPrettyPrintDate();
      String machineName = (machineType != null ? machineType.getName() : "CNC Machine");
      // metaInfo.add("(** UUID: " + UUID.randomUUID().toString() + " **)");
      metaInfo.add("(** This GCode was generated by ReplicatorG " + Base.VERSION_NAME + " **)");
      // TRICKY: calling a static method on an instance of a class is considered bad practice,
      //				but I'm not sure how to access displayName without it
      metaInfo.add("(*  using " + generator.displayName + "  *)");
      metaInfo.add(
          "(*  for a " + (multiHead ? "Dual headed " : "Single headed ") + machineName + "  *)");
      metaInfo.add("(*  on " + curDate + " *)");

      runPrepend(metaInfo);
    }

    // scans to cool unused head if required
    //		if( multiHead )
    //			source.coolUnusedToolhead();

    // Write the modified source back to our file
    source.writeToFile(generator.output.file);

    return generator.output;
  }
 /**
  * appends code to the file
  *
  * @param newCode
  */
 private void runAppend(GCodeSource newCode) {
   if (newCode != null) source.add(newCode);
 }
 /**
  * prepends code to the file
  *
  * @param newCode
  */
 private void runPrepend(GCodeSource newCode) {
   if (newCode != null) source.add(0, newCode);
 }
 /// inserts the passed gcode at specified location, 0 indexed.
 public void add(int location, GCodeSource toAdd) {
   add(location, toAdd.asList());
 }
 /// appends an entire GCode source file.
 public void add(GCodeSource toAdd) {
   add(toAdd.asList());
 }
 /// Make a deep copy of this MutableGCodeSource and returns it to the caller.
 public MutableGCodeSource copy() {
   MutableGCodeSource newSource = new MutableGCodeSource();
   for (String line : source) newSource.add(new String(line));
   return newSource;
 }