public boolean updateHilight(TopoTreeNode node) {

    //		System.out.println("Begin update hilight");
    if (node != null) {

      if (node.hilighted) {
        // return false; 		// commented so as not to suppress highlight of same node; so user can
        // click node, click tag, then click same node
      }

      if (hilightedNode != null) {

        hilightedNode.hilighted = false;
      }
      hilightedNode = node;
      hilightedNode.hilighted = true;

      // add the new node to the selection

      m_ttable.promoteTagSilent(m_ttable.getListedTag());

      while (m_ttable.topTag().full_components.size() > 0) {

        TopoTreeNode n = null;
        for (TopoTreeNode k : m_ttable.topTag().full_components) {
          if (n == null) {
            n = k;
          } else if (n.num_points < k.num_points) {
            n = k;
          }
        }

        m_ttable.topTag().removeComponent(n);
      }
      m_ttable.topTag().addComponent(node);
      for (TagChangeListener tagChangeListener : tagChangeListeners) {

        tagChangeListener.tagsChanged();
      }
      redraw();
    } else {

      if (hilightedNode == null) {

        return false;
      }
      hilightedNode.hilighted = false;
      hilightedNode = null;

      //
      m_ttable.promoteTagSilent(m_ttable.getListedTag());
      while (m_ttable.topTag().full_components.size() > 0) {

        TopoTreeNode n = null;
        for (TopoTreeNode k : m_ttable.topTag().full_components) {
          if (n == null) {
            n = k;
          } else if (n.num_points < k.num_points) {
            n = k;
          }
        }

        m_ttable.topTag().removeComponent(n);
      }
      for (TagChangeListener tagChangeListener : tagChangeListeners) {

        tagChangeListener.tagsChanged();
      }
      redraw();
    }
    //		System.out.println("End update hilight");

    return true;
  }
  // recursive draw routine
  public void drawNode(
      TopoTreeNode node, int left, int right, int level, int px, int py, boolean drawNode, Tag t) {

    boolean draw_full = false;
    boolean self_in_tag =
        t == null ? true : (t.part_components.contains(node) || t.full_components.contains(node));
    if (!self_in_tag) {

      return;
    }

    // draw the edge to its parent
    if (px != -1) {

      if (t != null && t.part_components.contains(node)) {

        stroke(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue());
        if (t == m_ttable.topTag()) {
          strokeWeight(3.f);
        } else {
          strokeWeight(2.f);
        }
      } else {

        if (t != null && t.full_components.contains(node)) {

          draw_full = true;

          stroke(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue());
          if (t == m_ttable.topTag() || t == m_ttable.topNonListedTag()) {
            strokeWeight(3.f);
          } else {
            strokeWeight(2.f);
          }
        } else {

          stroke(128);
          strokeWeight(1.f);
        }
      }

      //			line((left + right) / 2, level_size * (level + 1), px, py);
    }

    // break out if there's no room to recurse

    if (left != right) {

      // slice up the remaining space

      int topsize = 0;
      for (TopoTreeNode ttn : node.children) {

        if (ttn.num_points >= ignore_component_size) topsize += ttn.num_points;
      }
      int newleft = left;
      int newright = left;
      for (TopoTreeNode ttn : node.children) {

        boolean child_in_tag =
            t == null ? true : (t.part_components.contains(ttn) || t.full_components.contains(ttn));

        if (ttn.num_points >= ignore_component_size) {

          newright +=
              (int) Math.round((right - left) * ((float) ttn.num_points) / ((float) topsize));

          drawNode(
              ttn,
              newleft,
              newright,
              level + 1,
              (left + right) / 2,
              level_size * (level + 1),
              true,
              t);

          newleft = newright;
        } else {

          if (child_in_tag && t != null) {

            draw_full = true;
          }
        }
      }
    }

    node.x = (left + right) / 2;
    node.y = level_size * (level + 1);

    // draw the node
    if ((drawNode || node.hilighted) && !node.isSameAsChild) {

      // chose color based on tags
      if (draw_full && t != null) {

        fill(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue());
      } else {
        fill(PrettyColors.Grey.getRed(), PrettyColors.Grey.getGreen(), PrettyColors.Grey.getBlue());
      }
      stroke(0);

      if (!node.hilighted) noStroke();

      int node_size = DEF_NODE_SIZE;
      if (node.hilighted || (draw_full && t == m_ttable.topTag())) {
        node_size = 3 * DEF_NODE_SIZE;
      }
      if (t != null && !draw_full) return;
      rect(
          (left + right) / 2 - node_size / 2,
          level_size * (level + 1) - node_size / 2,
          node_size,
          node_size);

      if (node.hilighted) {

        if (draw_full) {

          stroke(
              2 * t.tag_color.getRed() / 3,
              2 * t.tag_color.getGreen() / 3,
              2 * t.tag_color.getBlue() / 3);
        }
        strokeWeight(2.f);
        rect(
            (left + right) / 2 - 3 * node_size / 4,
            level_size * (level + 1) - 3 * node_size / 4,
            3 * node_size / 2,
            3 * node_size / 2);
      }

      stroke(0);
      strokeWeight(1.f);
    }
  }