/**
   * Sets an ordering between two nodes. When an iterator is requested, the first node will appear
   * earlier in the sequence than the second node. If a prior ordering existed between the nodes in
   * the opposite order, it is removed.
   *
   * @return <code>true</code> if no prior ordering existed between the nodes, <code>false</code>
   *     otherwise.
   */
  public boolean setOrdering(Object first, Object second) {
    DigraphNode firstPONode = (DigraphNode) poNodes.get(first);
    DigraphNode secondPONode = (DigraphNode) poNodes.get(second);

    secondPONode.removeEdge(secondPONode);
    return firstPONode.addEdge(secondPONode);
  }
  /** Removes an <code>Object</code> from this <code>PartiallyOrderedSet</code>. */
  public boolean remove(Object o) {
    DigraphNode node = (DigraphNode) poNodes.get(o);
    if (node == null) {
      return false;
    }

    poNodes.remove(o);
    node.dispose();
    return true;
  }
  public PartialOrderIterator(Iterator iter) {
    // Initialize scratch in-degree values, zero list
    while (iter.hasNext()) {
      DigraphNode node = (DigraphNode) iter.next();
      int inDegree = node.getInDegree();
      inDegrees.put(node, new Integer(inDegree));

      // Add nodes with zero in-degree to the zero list
      if (inDegree == 0) {
        zeroList.add(node);
      }
    }
  }
  public Object next() {
    DigraphNode first = (DigraphNode) zeroList.removeFirst();

    // For each out node of the output node, decrement its in-degree
    Iterator outNodes = first.getOutNodes();
    while (outNodes.hasNext()) {
      DigraphNode node = (DigraphNode) outNodes.next();
      int inDegree = ((Integer) inDegrees.get(node)).intValue() - 1;
      inDegrees.put(node, new Integer(inDegree));

      // If the in-degree has fallen to 0, place the node on the list
      if (inDegree == 0) {
        zeroList.add(node);
      }
    }

    return first.getData();
  }
  /** Returns <code>true</code> if an ordering exists between two nodes. */
  public boolean hasOrdering(Object preferred, Object other) {
    DigraphNode preferredPONode = (DigraphNode) poNodes.get(preferred);
    DigraphNode otherPONode = (DigraphNode) poNodes.get(other);

    return preferredPONode.hasEdge(otherPONode);
  }