/*
   * @see org.argouml.ui.explorer.TreeModelUMLEventListener#modelElementRemoved(java.lang.Object)
   */
  public void modelElementRemoved(Object node) {
    for (ExplorerTreeNode changeNode : new ArrayList<ExplorerTreeNode>(findNodes(node))) {
      if (changeNode.getParent() != null) {
        removeNodeFromParent(changeNode);
      }
    }

    traverseModified((TreeNode) getRoot(), node);
  }
  /**
   * Merges the current children with the new children removing children no longer present and
   * adding new children in the right place.
   *
   * @param node the TreeNode were merging lists for.
   * @param children the current child UserObjects, in order.
   * @param newChildren the expected child UserObjects, in order.
   * @throws UnsupportedOperationException if the Iterator returned by newChildren doesn't support
   *     the remove operation, or if newChildren itself doesn't support remove or removeAll.
   * @throws NullPointerException if node, children or newChildren are null.
   */
  private void mergeChildren(ExplorerTreeNode node, List children, List newChildren) {
    Set removeObjects = prepareAddRemoveSets(children, newChildren);
    // Remember that children are not TreeNodes but UserObjects
    List<ExplorerTreeNode> actualNodes = new ArrayList<ExplorerTreeNode>();
    Enumeration childrenEnum = node.children();
    while (childrenEnum.hasMoreElements()) {
      actualNodes.add((ExplorerTreeNode) childrenEnum.nextElement());
    }

    int position = 0;
    Iterator childNodes = actualNodes.iterator();
    Iterator newNodes = newChildren.iterator();
    Object firstNew = newNodes.hasNext() ? newNodes.next() : null;
    while (childNodes.hasNext()) {
      Object childObj = childNodes.next();
      if (!(childObj instanceof ExplorerTreeNode)) {
        continue;
      }

      ExplorerTreeNode child = (ExplorerTreeNode) childObj;
      Object userObject = child.getUserObject();

      if (removeObjects.contains(userObject)) {
        removeNodeFromParent(child);
      } else {
        while (firstNew != null && order.compare(firstNew, userObject) < 0) {
          insertNodeInto(new ExplorerTreeNode(firstNew, this), node, position);
          position++;
          firstNew = newNodes.hasNext() ? newNodes.next() : null;
        }
        position++;
      }
    }

    // Add any remaining nodes
    while (firstNew != null) {
      insertNodeInto(new ExplorerTreeNode(firstNew, this), node, position);
      position++;
      firstNew = newNodes.hasNext() ? newNodes.next() : null;
    }
  }