@Override
    public void run() {
      UIMaster master = UIMaster.getInstance();
      MasterMgrClient client = master.acquireMasterMgrClient();
      try {
        MappedSet<String, VersionID> versions = pArchives.get(pIndex);
        String archiveName = null;
        String msg = ("Archiving Volume (" + (pIndex + 1) + " of " + pArchives.size() + ")...");
        long opID = master.beginDialogOp(msg);
        master.setDialogOpCancelClient(opID, client);
        long monitorID = client.addMonitor(new DialogOpMonitor(opID));
        try {
          archiveName = client.archive(pPrefix, versions, pArchiver, pToolset);
        } catch (PipelineException ex) {
          showErrorDialog(
              "Error:",
              ex.getMessage()
                  + "\n\n"
                  + "Archive operation aborted early without creating "
                  + "("
                  + (pArchives.size() - pIndex)
                  + " of "
                  + pArchives.size()
                  + ") archive "
                  + "volumes!");
          return;
        } finally {
          master.endDialogOp(opID, "Archived.");
          client.removeMonitor(monitorID);
        }

        SwingUtilities.invokeLater(new RemoveTask(versions));

        ManualArchiveConfirmTask task =
            new ManualArchiveConfirmTask(
                pParent, archiveName, pIndex + 1, pPrefix, pArchives, pToolset, pArchiver);
        SwingUtilities.invokeLater(task);
      } finally {
        master.releaseMasterMgrClient(client);
      }
    }
    @Override
    public void run() {
      UIMaster master = UIMaster.getInstance();
      MasterMgrClient client = master.acquireMasterMgrClient();
      long monitorID = -1L;
      try {
        DoubleMap<String, VersionID, Long> data = null;
        long opID = master.beginDialogOp("Calculating File Sizes...");
        master.setDialogOpCancelClient(opID, client);
        monitorID = client.addMonitor(new DialogOpMonitor(opID));
        try {
          data = client.getArchivedSizes(pVersions);
        } catch (PipelineException ex) {
          showErrorDialog(ex);
        } finally {
          master.endDialogOp(opID, "File Sizes Calculated.");
        }

        /* merge existing and new sizes */
        if (data != null) {
          for (String name : pData.keySet()) {
            TreeMap<VersionID, Long> oversions = pData.get(name);
            TreeMap<VersionID, Long> versions = data.get(name);
            if (versions == null) {
              data.put(name, oversions);
            } else {
              for (VersionID vid : oversions.keySet()) {
                if (versions.get(vid) == null) versions.put(vid, oversions.get(vid));
              }
            }
          }

          UpdateSizesTask task = new UpdateSizesTask(data);
          SwingUtilities.invokeLater(task);
        }
      } finally {
        client.removeMonitor(monitorID);
        master.releaseMasterMgrClient(client);
      }
    }
    @Override
    public void run() {
      UIMaster master = UIMaster.getInstance();
      ArrayList<ArchiveInfo> info = null;

      MasterMgrClient client = master.acquireMasterMgrClient();
      long opID = master.beginDialogOp("Searching for Candidate Versions...");
      master.setDialogOpCancelClient(opID, client);
      long monitorID = client.addMonitor(new DialogOpMonitor(opID));
      try {
        info = client.archiveQuery(pPattern, pMaxArchives);
      } catch (PipelineException ex) {
        showErrorDialog(ex);
      } finally {
        master.endDialogOp(opID, "Archive Search Complete.");
        client.removeMonitor(monitorID);
        master.releaseMasterMgrClient(client);
      }

      UpdateTask task = new UpdateTask(info);
      SwingUtilities.invokeLater(task);
    }
    @Override
    public void run() {
      UIMaster master = UIMaster.getInstance();
      MasterMgrClient client = master.acquireMasterMgrClient();
      try {
        DoubleMap<String, VersionID, Long> versionSizes = null;
        {
          long opID = master.beginDialogOp("Assigning Versions to Archives...");
          long monitorID = client.addMonitor(new DialogOpMonitor(opID));
          try {
            versionSizes = client.getArchivedSizes(pVersions);
          } catch (PipelineException ex) {
            showErrorDialog(ex);
          } finally {
            master.endDialogOp(opID, "Versions Assigned.");
            client.removeMonitor(monitorID);
          }
        }

        /* assign the maximum number of versions to each archive volume without
        exceeding its capacity */
        TreeMap<Integer, MappedSet<String, VersionID>> archives =
            new TreeMap<Integer, MappedSet<String, VersionID>>();
        if (versionSizes != null) {
          long capacity = pArchiver.getCapacity();
          int idx = 0;
          long total = 0L;
          boolean done = false;
          DoubleMap<String, VersionID, Long> skippedVersionSizes =
              new DoubleMap<String, VersionID, Long>();
          while (!done) {
            for (String name : versionSizes.keySet()) {
              for (VersionID vid : versionSizes.keySet(name)) {
                Long size = versionSizes.get(name, vid);
                if ((total + size) >= capacity) {
                  /* the version is too big to fit by itself in a volume */
                  if (total == 0L) {
                    showErrorDialog(
                        "Error:",
                        "The version ("
                            + vid
                            + ") of node ("
                            + name
                            + ") was larger than "
                            + "the capacity of an entire archive volume!  The capacity of the "
                            + "archive volume must be increased to at least "
                            + "("
                            + formatLong(size)
                            + ") in order to archive this version.");
                    return;
                  }

                  skippedVersionSizes.put(name, vid, size);
                }

                /* the version fits, add it to this volume */
                else {
                  MappedSet<String, VersionID> versions = archives.get(idx);
                  if (versions == null) {
                    versions = new MappedSet<String, VersionID>();
                    archives.put(idx, versions);
                  }

                  versions.put(name, vid);
                  total += size;
                }
              }
            }

            /* some versions wouldn't fit in the current volume,
            create a new volume and try again... */
            if (!skippedVersionSizes.isEmpty()) {
              idx++;
              total = 0L;
              versionSizes = skippedVersionSizes;
              skippedVersionSizes = new DoubleMap<String, VersionID, Long>();
            } else {
              if (total < pMinSize) {
                if (idx == 0) {
                  showErrorDialog(
                      "Error:",
                      "The total size ("
                          + formatLong(total)
                          + ") of all versions selected "
                          + "for archiving was less than the minimum archive volume size "
                          + "("
                          + formatLong(pMinSize)
                          + ")!  Either select enough versions to "
                          + "meet this minimum size or specify a smaller minimum size to create "
                          + "an archive volume.");
                  return;
                } else {
                  archives.remove(idx);
                }
              }

              break;
            }
          }
        }

        /* perform the archive operations */
        if (!archives.isEmpty()) {
          if (pArchiver.isManual()) {
            ManualArchiveConfirmTask task =
                new ManualArchiveConfirmTask(
                    pParent, null, 0, pPrefix, archives, pToolset, pArchiver);
            SwingUtilities.invokeLater(task);
          } else {
            long opID = master.beginDialogOp();
            master.setDialogOpCancelClient(opID, client);
            long monitorID = client.addMonitor(new DialogOpMonitor(opID));
            int lastIdx = 0;
            try {
              for (Integer idx : archives.keySet()) {
                master.updateDialogOp(
                    opID, "Archiving Volume (" + (idx + 1) + " of " + archives.size() + ")...");
                lastIdx = idx;
                client.archive(pPrefix, archives.get(idx), pArchiver, pToolset);
              }
            } catch (PipelineException ex) {
              showErrorDialog(
                  "Error:",
                  ex.getMessage()
                      + "\n\n"
                      + "Archive operation aborted early without creating "
                      + "("
                      + (archives.size() - lastIdx)
                      + " of "
                      + archives.size()
                      + ") archive "
                      + "volumes!");
              return;
            } finally {
              master.endDialogOp(opID, "Archived.");
              client.removeMonitor(monitorID);
            }

            RemoveAllTask task = new RemoveAllTask();
            SwingUtilities.invokeLater(task);
          } // else
        } // if(!archives.isEmpty()) {
      } finally {
        master.releaseMasterMgrClient(client);
      }
    }