/**
   * Return a string representation of this object. It should be nicely formated and include the
   * list of children and ancestor nodes.
   */
  public String toDeepString() {
    StringBuffer buffer = new StringBuffer();

    // write ID
    writeln(buffer, 0, NLS.bind(Messages.stats_pluginid, descriptor.getSymbolicName()));

    // write ancestors
    if (ancestors.size() == 0) {
      writeln(buffer, 1, Messages.depend_noParentPlugins);
    } else {
      writeln(buffer, 1, Messages.depend_requiredBy);
      for (Iterator i = ancestors.iterator(); i.hasNext(); ) {
        PluginDependencyGraphNode ancestor = (PluginDependencyGraphNode) i.next();
        writeln(buffer, 2, ancestor.getId());
      }
    }

    // write children
    if (children.size() == 0) {
      writeln(buffer, 1, Messages.depend_noChildrenPlugins);
    } else {
      writeln(buffer, 1, Messages.depend_requires);
      for (Iterator i = children.iterator(); i.hasNext(); ) {
        PluginDependencyGraphNode child = (PluginDependencyGraphNode) i.next();
        writeln(buffer, 2, child.getId());
      }
    }
    return buffer.toString();
  }
 /** @see java.lang.Object#equals(Object) */
 @Override
 public boolean equals(Object obj) {
   if (obj == null) return false;
   if (!(obj instanceof PluginDependencyGraphNode)) return false;
   PluginDependencyGraphNode other = (PluginDependencyGraphNode) obj;
   return this.getId().equals(other.getId());
 }
 /** @see ISelectionListener#selectionChanged(IWorkbenchPart, ISelection) */
 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
   if (!(selection instanceof IStructuredSelection)) return;
   Object element = ((IStructuredSelection) selection).getFirstElement();
   long id = -1;
   String name = null;
   if (element instanceof BundleDescription) {
     id = ((BundleDescription) element).getBundleId();
     name = ((BundleDescription) element).getSymbolicName();
   }
   if (element instanceof BundleStats) {
     id = ((BundleStats) element).getId();
     name = ((BundleStats) element).getSymbolicName();
   }
   if (id == -1) return;
   PluginDependencyGraphNode node =
       (PluginDependencyGraphNode) getDependencyGraph().get(new Long(id));
   String text =
       node == null ? NLS.bind(Messages.depend_noInformation, name) : node.toDeepString();
   viewer.getDocument().set(text);
   viewer.refresh();
 }
  /**
   * Build the table of plug-in dependencies. Iterate over all the plug-ins in the plug-in registry
   * and the cycle through the list of pre-requisites and create the parent/child relationships in
   * the nodes.
   */
  private Map getDependencyGraph() {
    if (dependencyGraph != null) return dependencyGraph;
    // Build up the dependency graph (see PluginDependencyGraphNode) so
    // we have the information readily available for any plug-in.
    State state = Platform.getPlatformAdmin().getState(false);
    BundleDescription[] plugins = state.getBundles();
    dependencyGraph = new HashMap();
    for (int i = 0; i < plugins.length; i++) {
      BundleDescription descriptor = plugins[i];
      PluginDependencyGraphNode node =
          (PluginDependencyGraphNode) dependencyGraph.get(new Long(descriptor.getBundleId()));
      if (node == null) {
        node = new PluginDependencyGraphNode(descriptor);
        dependencyGraph.put(new Long(descriptor.getBundleId()), node);
      }

      // Cycle through the prerequisites
      BundleSpecification[] requires = descriptor.getRequiredBundles();
      for (int j = 0; j < requires.length; j++) {
        BundleDescription childDesc = (BundleDescription) requires[j].getSupplier();
        // if the child doesn't exist then move to the next child
        if (childDesc == null) continue;

        // if the child entry is not in the table yet then add it
        PluginDependencyGraphNode childNode =
            (PluginDependencyGraphNode) dependencyGraph.get(new Long(childDesc.getBundleId()));
        if (childNode == null) {
          childNode = new PluginDependencyGraphNode(childDesc);
          dependencyGraph.put(new Long(childDesc.getBundleId()), childNode);
        }

        // Add the child to this node's children and set this node as an ancestor
        // of the child node
        node.addChild(childNode);
        childNode.addAncestor(node);
      }
    }
    return dependencyGraph;
  }