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());
      //       }
    }
  /** Get the distribution of job states for the jobs in the given group. */
  public double[] getDistribution(TaskTimer timer, long groupID) {
    Counters counters = null;
    timer.acquire();
    synchronized (pCountersByGroup) {
      timer.resume();
      counters = pCountersByGroup.get(groupID);
    }

    if (counters != null) {
      double dist[] = counters.distribution();

      //       if(LogMgr.getInstance().isLoggable(LogMgr.Kind.Ops, LogMgr.Level.Finest)) {
      //         StringBuilder buf = new StringBuilder();
      //         buf.append("Job Group Distribution [" + groupID + "]:\n  ");
      //         for(JobState js : JobState.all())
      //           buf.append(js + "[" + String.format("%1$.4f", dist[js.ordinal()]) + "] ");
      // 	LogMgr.getInstance().log(LogMgr.Kind.Ops, LogMgr.Level.Finest, buf.toString());
      //       }

      return dist;
    } else {
      LogMgr.getInstance()
          .logAndFlush(
              LogMgr.Kind.Ops,
              LogMgr.Level.Warning,
              "Somehow the job group (" + groupID + ") was not in the state counts table!");

      return new double[JobState.all().size()];
    }
  }
 public Counters(long total) {
   pCounts = new long[JobState.all().size()];
   pTotal = ((double) total);
 }