public StronglyConnectedComponentsBV(BitVector typeVariableList, TypeResolverBV resolver)
      throws TypeException {
    this.resolver = resolver;
    variables = typeVariableList;

    black = new TreeSet();
    finished = new LinkedList();

    for (BitSetIterator i = variables.iterator(); i.hasNext(); ) {
      TypeVariableBV var = resolver.typeVariableForId(i.next());

      if (!black.contains(var)) {
        black.add(var);
        dfsg_visit(var);
      }
    }

    black = new TreeSet();

    for (Iterator i = finished.iterator(); i.hasNext(); ) {
      TypeVariableBV var = (TypeVariableBV) i.next();

      if (!black.contains(var)) {
        current_tree = new LinkedList();
        forest.add(current_tree);
        black.add(var);
        dfsgt_visit(var);
      }
    }

    for (Iterator i = forest.iterator(); i.hasNext(); ) {
      LinkedList list = (LinkedList) i.next();
      TypeVariableBV previous = null;
      StringBuffer s = null;
      if (DEBUG) {
        s = new StringBuffer("scc:\n");
      }

      for (Iterator j = list.iterator(); j.hasNext(); ) {
        TypeVariableBV current = (TypeVariableBV) j.next();

        if (DEBUG) {
          s.append(" " + current + "\n");
        }

        if (previous == null) {
          previous = current;
        } else {
          try {
            previous = previous.union(current);
          } catch (TypeException e) {
            if (DEBUG) {
              G.v().out.println(s);
            }
            throw e;
          }
        }
      }
    }
  }
  private void dfsgt_visit(TypeVariableBV var) {
    current_tree.add(var);

    BitVector children = var.children();

    for (BitSetIterator i = children.iterator(); i.hasNext(); ) {
      TypeVariableBV child = resolver.typeVariableForId(i.next());

      if (!black.contains(child)) {
        black.add(child);
        dfsgt_visit(child);
      }
    }
  }
  private void dfsg_visit(TypeVariableBV var) {
    BitVector parents = var.parents();

    for (BitSetIterator i = parents.iterator(); i.hasNext(); ) {
      TypeVariableBV parent = resolver.typeVariableForId(i.next());

      if (!black.contains(parent)) {
        black.add(parent);
        dfsg_visit(parent);
      }
    }

    finished.add(0, var);
  }