@Override
    public void initPhase() throws PipelineException {
      /* initialize builder parameters from source images node information */
      setParamValue(new ParamMapping(DeliverNamer.aDeliverable), pSourcePrefix);
      setParamValue(new ParamMapping(aNotes), pSourceVersion.getMessage());
      setParamValue(new ParamMapping(aClientVersion), pSourceVersion.getVersionID().toString());
      setParamValue(new ParamMapping(aClientShotName), pSourcePrefix);

      /* replace placeholder parameters with the names of the available
      slate script, format script and codec settings nodes */
      {
        Path path = pProjectNamer.getSlateNukeScriptsParentPath();
        ArrayList<String> pnames = findChildNodeNames(path);
        if ((pnames == null) || pnames.isEmpty())
          throw new PipelineException(
              "Unable to find any slate creation Nuke script nodes in (" + path + ")!");

        UtilityParam param =
            new EnumUtilityParam(
                aSlateScript,
                "Select the master slate creation Nuke script to use.",
                pnames.get(0),
                pnames);
        replaceParam(param);
      }

      {
        Path path = pProjectNamer.getFormatNukeScriptsParentPath();
        ArrayList<String> pnames = findChildNodeNames(path);
        if ((pnames == null) || pnames.isEmpty())
          throw new PipelineException(
              "Unable to find any image formatting Nuke script nodes in (" + path + ")!");

        UtilityParam param =
            new EnumUtilityParam(
                aFormatScript,
                "Select final image formatting Nuke script to use.",
                pnames.get(0),
                pnames);
        replaceParam(param);
      }

      {
        Path path = pProjectNamer.getQtCodecSettingsParentPath();
        ArrayList<String> pnames = findChildNodeNames(path);
        if ((pnames == null) || pnames.isEmpty())
          throw new PipelineException(
              "Unable to find any QuickTime codec settings nodes in (" + path + ")!");

        UtilityParam param =
            new EnumUtilityParam(
                aCodecSettings,
                "Select the QuickTime codec settings to encode the final movie.",
                pnames.get(0),
                pnames);
        replaceParam(param);
      }
    }
  /**
   * Returns a list of Actions required by this Builder, indexed by the toolset that needs to
   * contain them.
   *
   * <p>Builders should override this method to provide their own requirements. This validation gets
   * performed after all the Setup Passes have been run but before any Construct Passes are run.
   */
  @SuppressWarnings("unchecked")
  @Override
  public MappedArrayList<String, PluginContext> getNeededActions() {
    ArrayList<PluginContext> plugins = new ArrayList<PluginContext>();
    plugins.add(new PluginContext("Touch"));
    plugins.add(new PluginContext("NukeRead"));
    plugins.add(
        new PluginContext(
            "NukeSubstComp", "Temerity", new Range<VersionID>(new VersionID("2.4.3"), null)));
    plugins.add(new PluginContext("DjvUnixQt"));
    plugins.add(
        new PluginContext(
            "SlateSubst", "ICVFX", new Range<VersionID>(new VersionID("1.5.0"), null)));

    MappedArrayList<String, PluginContext> toReturn = new MappedArrayList<String, PluginContext>();
    toReturn.put(getToolset(), plugins);

    return toReturn;
  }
  /**
   * Required constructor for to launch the builder.
   *
   * @param mclient The master manager connection.
   * @param qclient The queue manager connection.
   * @param builderInfo Information that is shared among all builders in a given invocation.
   */
  public QtDeliverBuilder(
      MasterMgrClient mclient, QueueMgrClient qclient, BuilderInformation builderInfo)
      throws PipelineException {
    super(
        "QtDeliver",
        "A builder for constructing the nodes required to prepare an image sequence "
            + "for delivery to the client or for internal review.",
        mclient,
        qclient,
        builderInfo,
        new StudioDefinitions(
            mclient,
            qclient,
            UtilContext.getDefaultUtilContext(mclient),
            builderInfo.getLoggerName()),
        null,
        null,
        null);

    /* setup builder parameters */
    {
      /* hide and set parameters which shouldn't be visible to the user */
      {
        disableParam(new ParamMapping(BaseUtil.aUtilContext, UtilContextUtilityParam.aAuthor));
        disableParam(new ParamMapping(BaseUtil.aUtilContext, UtilContextUtilityParam.aView));

        // disableParam(new ParamMapping(aCheckinWhenDone));
        setParamValue(new ParamMapping(aCheckinWhenDone), true);

        disableParam(new ParamMapping(aReleaseOnError));
        setParamValue(new ParamMapping(aReleaseOnError), true);
      }

      /* the source images being delivered */
      {
        UtilityParam param =
            new NodePathUtilityParam(
                aSourceNode,
                "The fully resolved name of the node containing the images to be delivered.",
                new Path("/"));
        addParam(param);
      }

      {
        UtilityParam param =
            new StringUtilityParam(
                aSourceVersion,
                "The revision number of the source images node being delivered.",
                null);
        addParam(param);
      }

      /* deliverable info */
      {
        ArrayList<String> choices = new ArrayList<String>();
        choices.add("Test");
        choices.add("Temp");
        choices.add("For Approval");
        choices.add("For Preview");
        choices.add("Final");

        UtilityParam param =
            new EnumUtilityParam(
                aDeliveryType, "The reason the deliverable was created.", "For Approval", choices);
        addParam(param);
      }

      {
        UtilityParam param =
            new StringUtilityParam(
                DeliverNamer.aDeliverable,
                "The name for the content of the images being delivered to the client. "
                    + "Typically this will be based on a combination of the shot (or asset) and "
                    + "Pipeline task which generated the images such as: \"ri120-blot\" or "
                    + "\"rorschach-model\".",
                null);
        addParam(param);
      }

      {
        UtilityParam param =
            new StringUtilityParam(
                aClientVersion,
                "The client revision number.  This revision number is unrelated to Pipeline's "
                    + "revision number for the source images and is purely for external client use.",
                null);
        addParam(param);
      }

      {
        UtilityParam param =
            new StringUtilityParam(
                aClientShotName, "The filename of the sequence delivered to the client.", null);
        addParam(param);
      }

      {
        UtilityParam param =
            new StringUtilityParam(
                aNotes,
                "A short description of the Deliverable to be included in the image slates.  "
                    + "If not specified the check-in message associated with the source images node "
                    + "will be used instead.",
                null);
        addParam(param);
      }

      /* Nuke components */
      {
        UtilityParam param =
            new PlaceholderUtilityParam(
                aSlateScript, "Select the master slate creation Nuke script to use.");
        addParam(param);
      }

      {
        UtilityParam param =
            new IntegerUtilityParam(
                aSlateHold,
                "The number of frames to hold the constant slate image before the images being "
                    + "reviewed begin animating.",
                1);
        addParam(param);
      }

      {
        UtilityParam param =
            new PlaceholderUtilityParam(
                aFormatScript, "Select the final image formatting Nuke script to use.");
        addParam(param);
      }

      {
        UtilityParam param =
            new PlaceholderUtilityParam(
                aCodecSettings, "Select the QuickTime codec settings to encode the final movie.");
        addParam(param);
      }
    }

    /* create the setup passes */
    {
      addSetupPass(new QuickTimeEssentials());
      addSetupPass(new SetupDeliveryParams());
      addSetupPass(new GetPrerequisites());
    }

    /* setup the default editors */
    setCommonDefaultEditors();

    /* create the construct passes */
    {
      ConstructPass build = new BuildNodesPass();
      addConstructPass(build);
    }

    /* specify the layout of the parameters for each pass in the UI */
    {
      PassLayoutGroup layout = new PassLayoutGroup("Root", "Root Layout");

      {
        AdvancedLayoutGroup sub = new AdvancedLayoutGroup("QuickTimeEssentials", true);

        sub.addEntry(1, aUtilContext);
        sub.addEntry(1, null);
        sub.addEntry(1, aCheckinWhenDone);
        sub.addEntry(1, aActionOnExistence);
        sub.addEntry(1, aReleaseOnError);
        sub.addEntry(1, null);
        sub.addEntry(1, aSourceNode);
        sub.addEntry(1, aSourceVersion);

        layout.addPass(sub.getName(), sub);
      }

      {
        AdvancedLayoutGroup sub = new AdvancedLayoutGroup("None", true);
        layout.addPass(sub.getName(), sub);
      }

      {
        AdvancedLayoutGroup sub = new AdvancedLayoutGroup("DeliveryDetails", true);
        sub.addEntry(1, aDeliveryType);
        sub.addEntry(1, DeliverNamer.aDeliverable);
        sub.addEntry(1, aClientVersion);
        sub.addEntry(1, aClientShotName);
        sub.addEntry(1, aNotes);
        sub.addEntry(1, null);
        sub.addEntry(1, aSlateScript);
        sub.addEntry(1, aSlateHold);
        sub.addEntry(1, null);
        sub.addEntry(1, aFormatScript);
        sub.addEntry(1, aCodecSettings);

        layout.addPass(sub.getName(), sub);
      }

      setLayout(layout);
    }

    disableParam(new ParamMapping(aActionOnExistence));
    setParamValue(new ParamMapping(aActionOnExistence), ActionOnExistence.Conform.toString());
  }