void addNode(Node node) {
    setNodeReachable(node);
    EdgeList list = node.incoming;
    Edge e;
    for (int i = 0; i < list.size(); i++) {
      e = list.getEdge(i);
      if (!isNodeReachable(e.source)) {
        if (!isCandidate(e)) {
          setCandidate(e);
          candidates.add(e);
        }
      } else candidates.remove(e);
    }

    list = node.outgoing;
    for (int i = 0; i < list.size(); i++) {
      e = list.getEdge(i);
      if (!isNodeReachable(e.target)) {
        if (!isCandidate(e)) {
          setCandidate(e);
          candidates.add(e);
        }
      } else candidates.remove(e);
    }
    members.add(node);
  }
 protected void solve() {
   Node root = graph.nodes.getNode(0);
   setParentEdge(root, null);
   addNode(root);
   while (members.size() < graph.nodes.size()) {
     if (candidates.size() == 0)
       throw new RuntimeException("graph is not fully connected"); // $NON-NLS-1$
     int minSlack = Integer.MAX_VALUE, slack;
     Edge minEdge = null, edge;
     for (int i = 0; i < candidates.size() && minSlack > 0; i++) {
       edge = candidates.getEdge(i);
       slack = edge.getSlack();
       if (slack < minSlack) {
         minSlack = slack;
         minEdge = edge;
       }
     }
     addEdge(minEdge);
   }
   graph.nodes.normalizeRanks();
 }