protected void togglePausedConsumer(IAction pauseConsumer) {

    // The button can get out of sync if two clients are used.
    final boolean currentState = queueConnection.isQueuePaused(getSubmissionQueueName());
    try {
      pauseConsumer.setChecked(!currentState); // We are toggling it.

      IPublisher<PauseBean> pauser = service.createPublisher(getUri(), IEventService.CMD_TOPIC);
      pauser.setStatusSetName(IEventService.CMD_SET); // The set that other clients may check
      pauser.setStatusSetAddRequired(true);

      PauseBean pbean = new PauseBean();
      pbean.setQueueName(getSubmissionQueueName()); // The queue we are pausing
      pbean.setPause(pauseConsumer.isChecked());
      pauser.broadcast(pbean);

    } catch (Exception e) {
      ErrorDialog.openError(
          getViewSite().getShell(),
          "Cannot pause queue " + getSubmissionQueueName(),
          "Cannot pause queue "
              + getSubmissionQueueName()
              + "\n\nPlease contact your support representative.",
          new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
    }
    pauseConsumer.setChecked(queueConnection.isQueuePaused(getSubmissionQueueName()));
  }
  protected void purgeQueues() throws EventException {

    boolean ok =
        MessageDialog.openQuestion(
            getSite().getShell(),
            "Confirm Clear Queues",
            "Are you sure you would like to remove all items from the queue "
                + getQueueName()
                + " and "
                + getSubmissionQueueName()
                + "?\n\nThis could abort or disconnect runs of other users.");
    if (!ok) return;

    queueConnection.clearQueue(getQueueName());
    queueConnection.clearQueue(getSubmissionQueueName());

    reconnect();
  }
  private void executeBean(U bean) throws EventException, InterruptedException {

    // We record the bean in the status queue
    if (overrideMap != null && overrideMap.containsKey(bean.getUniqueId())) {
      U o = overrideMap.remove(bean.getUniqueId());
      bean.setStatus(o.getStatus());
    }
    logger.trace("Moving " + bean + " to " + mover.getSubmitQueueName());
    mover.submit(bean);

    // Run the process
    if (runner == null) {
      bean.setStatus(Status.FAILED);
      bean.setMessage("No runner set for consumer " + getName() + ". Nothing run");
      status.broadcast(bean);
      throw new EventException("You must set the runner before executing beans from the queue!");
    }

    if (processes.containsKey(bean.getUniqueId())) {
      throw new EventException(
          "The bean with unique id '"
              + bean.getUniqueId()
              + "' has already been used. Cannot run the same uuid twice!");
    }

    // We peal off the most recent bean from the submission queue

    if (bean.getStatus() == Status.REQUEST_TERMINATE) {
      bean.setStatus(Status.TERMINATED);
      bean.setMessage("Run aborted before started");
      status.broadcast(bean);
      return;
    }

    if (bean.getStatus().isFinal()) return; // This is not the bean you are looking for.

    IConsumerProcess<U> process = runner.createProcess(bean, status);
    processes.put(bean.getUniqueId(), new WeakReference<IConsumerProcess<U>>(process));

    process.start(); // Depending on the process may run in a separate thread (default is not to)
  }
  @Override
  public void disconnect() throws EventException {

    if (isActive()) stop();

    super.disconnect();
    setActive(false);
    mover.disconnect();
    status.disconnect();
    if (alive != null) alive.disconnect();
    if (command != null) command.disconnect();
    if (overrideMap != null) overrideMap.clear();
    try {
      if (connection != null) connection.close();
    } catch (JMSException e) {
      throw new EventException("Cannot close consumer connection!", e);
    }
  }
  @Override
  public void createPartControl(Composite content) {

    content.setLayout(new GridLayout(1, false));
    Util.removeMargins(content);

    this.viewer =
        new TableViewer(content, SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
    viewer.setUseHashlookup(true);
    viewer.getTable().setHeaderVisible(true);
    viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    createColumns();
    viewer.setContentProvider(createContentProvider());

    try {
      queueConnection = service.createSubmitter(getUri(), getSubmissionQueueName());
      queueConnection.setStatusTopicName(getTopicName());
      updateQueue(getUri());

      String name = getSecondaryIdAttribute("partName");
      if (name != null) setPartName(name);

      createActions();

      // We just use this submitter to read the queue
      createTopicListener(getUri());

    } catch (Exception e) {
      logger.error("Cannot listen to topic of command server!", e);
    }

    selectionProvider = new DelegatingSelectionProvider(viewer);
    getViewSite().setSelectionProvider(selectionProvider);
    viewer.addSelectionChangedListener(
        new ISelectionChangedListener() {
          @Override
          public void selectionChanged(SelectionChangedEvent event) {
            updateSelected();
          }
        });
  }
  private void rerun(StatusBean bean) {

    try {

      final DateFormat format = DateFormat.getDateTimeInstance();
      boolean ok =
          MessageDialog.openQuestion(
              getViewSite().getShell(),
              "Confirm resubmission " + bean.getName(),
              "Are you sure you want to rerun "
                  + bean.getName()
                  + " submitted on "
                  + format.format(new Date(bean.getSubmissionTime()))
                  + "?");

      if (!ok) return;

      final StatusBean copy = bean.getClass().newInstance();
      copy.merge(bean);
      copy.setUniqueId(UUID.randomUUID().toString());
      copy.setMessage("Rerun of " + bean.getName());
      copy.setStatus(org.eclipse.scanning.api.event.status.Status.SUBMITTED);
      copy.setPercentComplete(0.0);
      copy.setSubmissionTime(System.currentTimeMillis());

      queueConnection.submit(copy, true);

      reconnect();

    } catch (Exception e) {
      ErrorDialog.openError(
          getViewSite().getShell(),
          "Cannot rerun " + bean.getName(),
          "Cannot rerun " + bean.getName() + "\n\nPlease contact your support representative.",
          new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
    }
  }
  protected void stopJob() {

    final StatusBean bean = getSelection();
    if (bean == null) return;

    if (!bean.getStatus().isActive()) {

      String queueName = null;

      if (bean.getStatus() != org.eclipse.scanning.api.event.status.Status.SUBMITTED) {
        queueName = getQueueName();
        boolean ok =
            MessageDialog.openQuestion(
                getSite().getShell(),
                "Confirm Remove '" + bean.getName() + "'",
                "Are you sure you would like to remove '" + bean.getName() + "'?");
        if (!ok) return;
      } else {
        // Submitted delete it right away without asking or the consumer will run it!
        queueName = getSubmissionQueueName();
      }

      // It is submitted and not running. We can probably delete it.
      try {
        queueConnection.remove(bean, queueName);
        refresh();
      } catch (EventException e) {
        ErrorDialog.openError(
            getViewSite().getShell(),
            "Cannot delete " + bean.getName(),
            "Cannot delete "
                + bean.getName()
                + "\n\nIt might have changed state at the same time and being remoted.",
            new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
      }
      return;
    }

    try {

      final DateFormat format = DateFormat.getDateTimeInstance();
      boolean ok =
          MessageDialog.openQuestion(
              getViewSite().getShell(),
              "Confirm terminate " + bean.getName(),
              "Are you sure you want to terminate "
                  + bean.getName()
                  + " submitted on "
                  + format.format(new Date(bean.getSubmissionTime()))
                  + "?");

      if (!ok) return;

      bean.setStatus(org.eclipse.scanning.api.event.status.Status.REQUEST_TERMINATE);
      bean.setMessage("Termination of " + bean.getName());

      IPublisher<StatusBean> terminate = service.createPublisher(getUri(), getTopicName());
      terminate.broadcast(bean);

    } catch (Exception e) {
      ErrorDialog.openError(
          getViewSite().getShell(),
          "Cannot terminate " + bean.getName(),
          "Cannot terminate " + bean.getName() + "\n\nPlease contact your support representative.",
          new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
    }
  }
  private void createActions() throws Exception {

    final IContributionManager toolMan = getViewSite().getActionBars().getToolBarManager();
    final IContributionManager dropDown = getViewSite().getActionBars().getMenuManager();
    final MenuManager menuMan = new MenuManager();

    final Action openResults =
        new Action(
            "Open results for selected run", Activator.getImageDescriptor("icons/results.png")) {
          public void run() {
            openResults(getSelection());
          }
        };

    toolMan.add(openResults);
    toolMan.add(new Separator());
    menuMan.add(openResults);
    menuMan.add(new Separator());
    dropDown.add(openResults);
    dropDown.add(new Separator());

    this.up =
        new Action("Less urgent (-1)", Activator.getImageDescriptor("icons/arrow-090.png")) {
          public void run() {
            final StatusBean bean = getSelection();
            try {
              queueConnection.reorder(bean, -1);
            } catch (EventException e) {
              ErrorDialog.openError(
                  getViewSite().getShell(),
                  "Cannot move " + bean.getName(),
                  "'" + bean.getName() + "' cannot be moved in the submission queue.",
                  new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
            }
            refresh();
          }
        };
    up.setEnabled(false);
    toolMan.add(up);
    menuMan.add(up);
    dropDown.add(up);

    this.down =
        new Action("More urgent (+1)", Activator.getImageDescriptor("icons/arrow-270.png")) {
          public void run() {
            final StatusBean bean = getSelection();
            try {
              queueConnection.reorder(getSelection(), +1);
            } catch (EventException e) {
              ErrorDialog.openError(
                  getViewSite().getShell(),
                  "Cannot move " + bean.getName(),
                  e.getMessage(),
                  new Status(IStatus.ERROR, "org.eclipse.scanning.event.ui", e.getMessage()));
            }
            refresh();
          }
        };
    down.setEnabled(false);
    toolMan.add(down);
    menuMan.add(down);
    dropDown.add(down);

    this.pause =
        new Action("Pause job.\nPauses a running job.", IAction.AS_CHECK_BOX) {
          public void run() {
            pauseJob();
          }
        };
    pause.setImageDescriptor(Activator.getImageDescriptor("icons/control-pause.png"));
    pause.setEnabled(false);
    pause.setChecked(false);
    toolMan.add(pause);
    menuMan.add(pause);
    dropDown.add(pause);

    this.pauseConsumer =
        new Action(
            "Pause " + getPartName() + " Queue. Does not pause running job.",
            IAction.AS_CHECK_BOX) {
          public void run() {
            togglePausedConsumer(this);
          }
        };
    pauseConsumer.setImageDescriptor(Activator.getImageDescriptor("icons/control-pause-red.png"));
    pauseConsumer.setChecked(queueConnection.isQueuePaused(getSubmissionQueueName()));
    toolMan.add(pauseConsumer);
    menuMan.add(pauseConsumer);
    dropDown.add(pauseConsumer);

    this.pauseMonitor = service.createSubscriber(getUri(), EventConstants.CMD_TOPIC);
    pauseMonitor.addListener(
        new IBeanListener<PauseBean>() {
          @Override
          public void beanChangePerformed(BeanEvent<PauseBean> evt) {
            pauseConsumer.setChecked(queueConnection.isQueuePaused(getSubmissionQueueName()));
          }
        });

    this.remove =
        new Action(
            "Stop job or remove if finished",
            Activator.getImageDescriptor("icons/control-stop-square.png")) {
          public void run() {
            stopJob();
          }
        };
    remove.setEnabled(false);
    toolMan.add(remove);
    menuMan.add(remove);
    dropDown.add(remove);

    this.rerun =
        new Action("Rerun...", Activator.getImageDescriptor("icons/rerun.png")) {
          public void run() {
            rerunSelection();
          }
        };
    rerun.setEnabled(false);
    toolMan.add(rerun);
    menuMan.add(rerun);
    dropDown.add(rerun);

    IAction open =
        new Action("Open...", Activator.getImageDescriptor("icons/application-dock-090.png")) {
          public void run() {
            openSelection();
          }
        };
    toolMan.add(open);
    menuMan.add(open);
    dropDown.add(open);

    this.edit =
        new Action("Edit...", Activator.getImageDescriptor("icons/modify.png")) {
          public void run() {
            editSelection();
          }
        };
    edit.setEnabled(false);
    toolMan.add(edit);
    menuMan.add(edit);
    dropDown.add(edit);

    toolMan.add(new Separator());
    menuMan.add(new Separator());

    final Action showAll =
        new Action("Show other users results", IAction.AS_CHECK_BOX) {
          public void run() {
            showEntireQueue = isChecked();
            viewer.refresh();
          }
        };
    showAll.setImageDescriptor(Activator.getImageDescriptor("icons/spectacle-lorgnette.png"));

    toolMan.add(showAll);
    menuMan.add(showAll);
    dropDown.add(showAll);

    toolMan.add(new Separator());
    menuMan.add(new Separator());
    dropDown.add(new Separator());

    final Action refresh =
        new Action("Refresh", Activator.getImageDescriptor("icons/arrow-circle-double-135.png")) {
          public void run() {
            reconnect();
          }
        };

    toolMan.add(refresh);
    menuMan.add(refresh);
    dropDown.add(refresh);

    final Action configure =
        new Action("Configure...", Activator.getImageDescriptor("icons/document--pencil.png")) {
          public void run() {
            PropertiesDialog dialog = new PropertiesDialog(getSite().getShell(), idProperties);

            int ok = dialog.open();
            if (ok == PropertiesDialog.OK) {
              idProperties.clear();
              idProperties.putAll(dialog.getProps());
              reconnect();
            }
          }
        };

    toolMan.add(configure);
    menuMan.add(configure);
    dropDown.add(configure);

    final Action clearQueue =
        new Action("Clear Queue") {
          public void run() {
            try {
              purgeQueues();
            } catch (EventException e) {
              e.printStackTrace();
              logger.error("Canot purge queues", e);
            }
          }
        };
    menuMan.add(new Separator());
    dropDown.add(new Separator());
    menuMan.add(clearQueue);
    dropDown.add(clearQueue);

    viewer.getControl().setMenu(menuMan.createContextMenu(viewer.getControl()));
  }