/**
   * Update the dialog contents.
   *
   * @param jheader The job portion of the dialog header.
   * @param job The queue job.
   * @param info The current job status information.
   */
  public void updateContents(
      String jheader, QueueJob job, QueueJobInfo info, SubProcessExecDetails details) {
    ActionAgenda agenda = job.getActionAgenda();
    QueueJobResults results = info.getResults();

    String dir = "-";
    if ((agenda != null) && (info.getOsType() != null))
      dir = agenda.getTargetPath(info.getOsType()).toString();

    String hostname = "";
    if (info.getHostname() != null) hostname = (" [" + info.getHostname() + "]");

    String command = "-";
    if (details != null) command = details.getCommand();

    TreeMap<String, String> env = new TreeMap<String, String>();
    if (details != null) env = details.getEnvironment();

    setHeader("Execution Details -" + jheader + hostname);

    pWorkingDirField.setText(dir);

    BaseAction action = job.getAction();
    pCommandLineLabel.setText(
        "Action Command:  " + action.getName() + " (v" + action.getVersionID() + ")");
    pCommandLineArea.setText(command);

    {
      Component comps[] = UIFactory.createTitledPanels();
      {
        JPanel tpanel = (JPanel) comps[0];
        JPanel vpanel = (JPanel) comps[1];

        if (!env.isEmpty()) {
          String last = env.lastKey();
          for (String key : env.keySet()) {
            String value = env.get(key);

            JTextField field =
                UIFactory.createTitledTextField(tpanel, key + ":", sTSize, vpanel, value, sVSize);
            field.setHorizontalAlignment(JLabel.LEFT);

            if (!key.equals(last)) UIFactory.addVerticalSpacer(tpanel, vpanel, 3);
          }
        } else {
          tpanel.add(Box.createRigidArea(new Dimension(sTSize, 0)));
          vpanel.add(Box.createHorizontalGlue());
        }
      }

      pEnvLabel.setText("Toolset Environment:  " + agenda.getToolset());
      pEnvScroll.setViewportView(comps[2]);
    }
  }
    public synchronized void update(JobState prevState, QueueJobInfo info) {
      if (LogMgr.getInstance().isLoggable(LogMgr.Kind.Ops, LogMgr.Level.Finest)) {
        LogMgr.getInstance()
            .log(
                LogMgr.Kind.Ops,
                LogMgr.Level.Finest,
                "Job Count Update ["
                    + info.getJobID()
                    + "]: "
                    + prevState
                    + " -> "
                    + info.getState());
      }

      //      if(LogMgr.getInstance().isLoggable(LogMgr.Kind.Ops, LogMgr.Level.Finest)) {
      //         StringBuilder buf = new StringBuilder();
      //         buf.append("Job Pre-Counts [" + info.getJobID() + "]: " +
      //                    prevState + " -> " + info.getState() + "\n  ");
      //         for(JobState js : JobState.all())
      //           buf.append(js + "[" + pCounts[js.ordinal()] + "] ");
      //         LogMgr.getInstance().log(LogMgr.Kind.Ops, LogMgr.Level.Finest, buf.toString());
      //       }

      if (prevState != null) {
        if (pCounts[prevState.ordinal()] > 0) {
          pCounts[prevState.ordinal()]--;
        } else {
          LogMgr.getInstance()
              .logAndFlush(
                  LogMgr.Kind.Ops,
                  LogMgr.Level.Warning,
                  "Somehow the count of jobs with a "
                      + prevState
                      + " state was already "
                      + "when attempting to decrement the count after a change to a "
                      + info.getState()
                      + " state for the job ("
                      + info.getJobID()
                      + ")!");
        }
      }

      pCounts[info.getState().ordinal()]++;

      //     if(LogMgr.getInstance().isLoggable(LogMgr.Kind.Ops, LogMgr.Level.Finest)) {
      //         StringBuilder buf = new StringBuilder();
      //         buf.append("Job Post-Counts [" + info.getJobID() + "]: " +
      //                    prevState + " -> " + info.getState() + "\n  ");
      //         for(JobState js : JobState.all())
      //           buf.append(js + "[" + pCounts[js.ordinal()] + "] ");
      //         LogMgr.getInstance().log(LogMgr.Kind.Ops, LogMgr.Level.Finest, buf.toString());
      //       }
    }
  /**
   * Update the job state counts after a change to the job state information.
   *
   * @param timer The operation timer.
   * @param prevState The previous job state before the change or <CODE>null</CODE> if the previous
   *     state is unknown.
   * @para info The current job info which includes the updated job state.
   */
  public void update(TaskTimer timer, JobState prevState, QueueJobInfo info) {
    Counters counters = null;
    timer.acquire();
    synchronized (pCountersByJob) {
      timer.resume();
      counters = pCountersByJob.get(info.getJobID());
    }

    if (counters != null) counters.update(prevState, info);
    else
      LogMgr.getInstance()
          .logAndFlush(
              LogMgr.Kind.Ops,
              LogMgr.Level.Warning,
              "Somehow the job (" + info.getJobID() + ") was not in the state counts table!");
  }