protected void deleteCurrent() {
      int num_logs_deleted = 0;
      Set<Group> groups_changed = new HashSet<>();

      for (TreePath tp : display.logTree.getSelectionPaths()) {
        if (tp.getPathCount() == 3) {
          Group group = (Group) tp.getPath()[1];
          LogReference reference = (LogReference) tp.getLastPathComponent();

          Debug.warn("deleting {%s} from {%s}", reference, group);
          group.remove(reference);

          ++num_logs_deleted;
          groups_changed.add(group);
        } else {
          Debug.warn("cannot delete {%s}", tp.getLastPathComponent());
        }
      }

      for (Group group : groups_changed) {
        TreeModelEvent removeEvent = new TreeModelEvent(this, new Object[] {this, group});

        for (TreeModelListener listener : listeners) listener.treeStructureChanged(removeEvent);
      }

      ToolMessage.displayAndPrint("deleted %d logs", num_logs_deleted);
    }
    @Override
    protected void run() {
      Debug.warn("trying to connect to %s", robotAddress);
      robot = RobotConnection.connectToRobot(robotAddress, outerThis);

      if (robot == null) {
        ToolMessage.displayError("connection failed to: %s", robotAddress);

        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                display.connectButton.setEnabled(true);
              }
            });

        return;
      } else {
        ToolMessage.displayWarn("SUCCESS: connected to %s (%s)", robotAddress, robot);

        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                display.connectButton.setEnabled(true);

                display.connectButton.setText("disconnect");
                display.loadButton.setEnabled(false);
                updateComboBoxAndSettings(
                    display.robotAddressBox, UserSettings.addresses, robotAddress);

                controlRequestFlags();

                lastGroup = Group.groupForStream(robotAddress);
                Events.GGroupAdded.generate(this, lastGroup);
              }
            });
      }
    }
  private void setupFooter() {
    try {
      usedFileStore = Files.getFileStore(ToolSettings.NBITES_DIR_PATH);
    } catch (Exception e) {
      e.printStackTrace();
      ;
      throw new Error(e);
    }

    Debug.warn("Tool footer using fileStore: %s", usedFileStore.name());

    display.diskAvailLabel.setText(Utility.progressString(progressSize, 0.5));
    display.jvmAvailLabel.setText(Utility.progressString(progressSize, 0.5));

    footerJvmTimer =
        new Timer(
            1000, // ms
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                footerJvmAction();
              }
            });

    footerJvmTimer.start();

    footerDiskTimer =
        new Timer(
            1000,
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                footerDiskAction();
              }
            });
    footerDiskTimer.start();
  }