@Override
  public void setStopButtonVisibility(String nodeId, boolean visible) {
    ProcessTreeNode processTreeNode = processTreeNodes.get(nodeId);
    if (processTreeNode == null) {
      return;
    }

    if (visible) {
      processTreeNode
          .getTreeNodeElement()
          .getClassList()
          .remove(machineResources.getCss().hideStopButton());
    } else {
      processTreeNode
          .getTreeNodeElement()
          .getClassList()
          .add(machineResources.getCss().hideStopButton());
    }
  }
  @Override
  public void markProcessHasOutput(String processId) {
    if (processId.equals(activeProcessId)) {
      return;
    }

    ProcessTreeNode treeNode = processTreeNodes.get(processId);
    if (treeNode != null) {
      treeNode.setHasUnreadContent(true);
      treeNode.getTreeNodeElement().getClassList().add(machineResources.getCss().badgeVisible());
    }
  }
  @Override
  public void setProcessesData(@NotNull ProcessTreeNode root) {
    processTree.asWidget().setVisible(true);
    processTree.getModel().setRoot(root);
    processTree.renderTree(-1);

    for (ProcessTreeNode processTreeNode : processTreeNodes.values()) {
      if (!processTreeNode.getId().equals(activeProcessId) && processTreeNode.hasUnreadContent()) {
        processTreeNode
            .getTreeNodeElement()
            .getClassList()
            .add(machineResources.getCss().badgeVisible());
      }
    }
  }
  @Override
  public void setProcessRunning(String nodeId, boolean running) {
    ProcessTreeNode processTreeNode = processTreeNodes.get(nodeId);
    if (processTreeNode == null) {
      return;
    }

    processTreeNode.setRunning(running);

    JsElement spanElement =
        (JsElement) processTreeNode.getTreeNodeElement().getFirstChild().getChildNodes().item(1);
    if (running) {
      spanElement.setAttribute("running", "true");
    } else {
      spanElement.setAttribute("running", "false");
    }
  }
  @Override
  public void showProcessOutput(String processId) {
    if (processWidgets.containsKey(processId)) {
      onResize();
      outputPanel.showWidget(processWidgets.get(processId).asWidget());

      activeProcessId = processId;

      ProcessTreeNode treeNode = processTreeNodes.get(processId);
      if (treeNode != null) {
        treeNode.setHasUnreadContent(false);
        treeNode
            .getTreeNodeElement()
            .getClassList()
            .remove(machineResources.getCss().badgeVisible());
      }
    }
  }
  @Override
  public void selectNode(final ProcessTreeNode node) {
    SelectionModel<ProcessTreeNode> selectionModel = processTree.getSelectionModel();

    if (node == null) {
      selectionModel.clearSelections();
      return;
    } else {
      selectionModel.setTreeActive(true);
      selectionModel.clearSelections();
      selectionModel.selectSingleNode(node);

      node.getTreeNodeElement().scrollIntoView();
    }

    Scheduler.get()
        .scheduleDeferred(
            new Scheduler.ScheduledCommand() {
              @Override
              public void execute() {
                delegate.onTreeNodeSelected(node);
              }
            });
  }