/**
   * A tool group has been added. Batched adds will come through the toolsAdded method.
   *
   * @param evt The event that caused this method to be called
   */
  public void toolGroupAdded(ToolGroupEvent evt) {
    ToolGroup group = (ToolGroup) evt.getSource();
    ToolGroup tool = (ToolGroup) evt.getChild();

    TreePath path = buildTreePath(group);

    // System.out.println("group added " + group.getName() + " kid " + tool.getName());

    Object[] children = new Object[1];
    int[] indicies = new int[1];
    int index;

    ToolGroupTreeNode parent = (ToolGroupTreeNode) path.getLastPathComponent();
    ToolGroupTreeNode child = new ToolGroupTreeNode(tool, parent);
    parent.insert(child, parent.getChildCount());

    index = getIndexOfChild(parent, child);
    indicies[0] = index;
    children[0] = child;

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesInserted(treeEvent);

    tool.addToolGroupListener(this);
  }
  /**
   * A group of tool groups have been added.
   *
   * @param name The catalog name
   * @param groups The list of tool groups added
   */
  public void toolGroupsAdded(String name, List<ToolGroup> groups) {
    if (!name.equals(catalog.getName())) return;

    TreePath path = new TreePath(catalogRoot);
    Object[] children = new Object[groups.size()];
    int[] indicies = new int[groups.size()];

    for (int i = 0; i < groups.size(); i++) {
      ToolGroup group = groups.get(i);
      ToolGroupTreeNode child = new ToolGroupTreeNode(group, catalogRoot);
      catalogRoot.insert(child, catalogRoot.getChildCount());

      int index = catalogRoot.getIndex(child);
      indicies[i] = index;
      children[i] = child;
      // System.out.println("Catalog bulk root adding group " + group.getName());
    }

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesInserted(treeEvent);

    // Add listeners later to make sure we don't end up with any weird
    // side effects of a fast building tree.
    for (int i = 0; i < groups.size(); i++) {
      ToolGroup group = groups.get(i);
      group.addToolGroupListener(this);
    }
  }
  /**
   * Build children objects for the requested node type. If the node is an attribute then do
   * nothing. Listeners will be added to the root item but not the children. This is to prevent odd
   * mixups if the children have listeners but have not yet had their children built. The viewable
   * tree would get very mixed up then
   *
   * @param root The root object to add children for
   */
  private void buildChildren(ToolGroupTreeNode root) {
    ToolGroupChild toolItem = root.getToolObject();

    if (toolItem instanceof ToolGroup) {
      ToolGroup tg = (ToolGroup) toolItem;
      List<ToolGroupChild> kids = tg.getChildren();

      for (int i = 0; i < kids.size(); i++) {
        ToolGroupChild child = kids.get(i);
        ToolGroupTreeNode kid = new ToolGroupTreeNode(child, root);

        root.insert(kid, i);
      }
    }
  }
  /**
   * A tool has been removed. Batched removes will come through the toolsRemoved method.
   *
   * @param evt The event that caused this method to be called
   */
  public void toolGroupRemoved(ToolGroupEvent evt) {

    ToolGroup group = (ToolGroup) evt.getSource();
    ToolGroup tool = (ToolGroup) evt.getChild();

    tool.removeToolGroupListener(this);

    TreePath path = buildTreePath(group);

    Object[] children = new Object[1];
    int[] indicies = new int[1];
    int index;

    ToolGroupTreeNode parent = (ToolGroupTreeNode) path.getLastPathComponent();
    ToolGroupTreeNode child = parent.getTreeNodeChild(tool);
    index = getIndexOfChild(parent, child);
    indicies[0] = index;
    children[0] = child;

    parent.remove(child);

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesRemoved(treeEvent);
  }
  /**
   * A group of tool groups have been removed.
   *
   * @param name The catalog name
   * @param groups The list of tool groups that have been removed
   */
  public void toolGroupsRemoved(String name, List<ToolGroup> groups) {
    if (!name.equals(catalog.getName())) return;

    TreePath path = new TreePath(catalogRoot);
    Object[] children = new Object[groups.size()];
    int[] indicies = new int[groups.size()];

    for (int i = 0; i < groups.size(); i++) {
      ToolGroup group = groups.get(i);

      group.removeToolGroupListener(this);

      ToolGroupTreeNode child = catalogRoot.getTreeNodeChild(group);

      int index = catalogRoot.getIndex(child);
      indicies[i] = index;
      children[i] = child;

      catalogRoot.remove(child);
    }

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesRemoved(treeEvent);
  }
  /**
   * A tool has been removed. Batched removes will come through the toolsRemoved method.
   *
   * @param name The catalog name
   * @param group The toolGroup removed from
   */
  public void toolGroupRemoved(String name, ToolGroup group) {
    if (!name.equals(catalog.getName())) return;

    group.removeToolGroupListener(this);

    TreePath path = new TreePath(catalogRoot);
    Object[] children = new Object[1];
    int[] indicies = new int[1];

    ToolGroupTreeNode child = catalogRoot.getTreeNodeChild(group);
    int index = catalogRoot.getIndex(child);
    indicies[0] = index;
    children[0] = child;

    catalogRoot.remove(child);

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesRemoved(treeEvent);
  }
  /**
   * A tool group has been added. Batched adds will come through the toolsAdded method.
   *
   * @param name The catalog name
   * @param group The toolGroup added to
   */
  public void toolGroupAdded(String name, ToolGroup group) {
    if (!name.equals(catalog.getName())) return;

    TreePath path = new TreePath(catalogRoot);
    Object[] children = new Object[1];
    int[] indicies = new int[1];

    ToolGroupTreeNode child = new ToolGroupTreeNode(group, catalogRoot);
    catalogRoot.insert(child, catalogRoot.getChildCount());

    int index = catalogRoot.getIndex(child);
    indicies[0] = index;
    children[0] = child;

    // System.out.println("Catalog root adding group " + group.getName());

    TreeModelEvent treeEvent = new TreeModelEvent(this, path, indicies, children);
    fireTreeNodesInserted(treeEvent);

    group.addToolGroupListener(this);
  }