/**
  * Return a view of an {@link IClassHierarchy} as a {@link Graph}, with edges from classes to
  * immediate subtypes
  */
 public static Graph<IClass> typeHierarchy2Graph(IClassHierarchy cha) throws WalaException {
   Graph<IClass> result = SlowSparseNumberedGraph.make();
   for (IClass c : cha) {
     result.addNode(c);
   }
   for (IClass c : cha) {
     for (IClass x : cha.getImmediateSubclasses(c)) {
       result.addEdge(c, x);
     }
     if (c.isInterface()) {
       for (IClass x : cha.getImplementors(c.getReference())) {
         result.addEdge(c, x);
       }
     }
   }
   return result;
 }
  private static void removeNode(Graph<AbstractPDGNode> cfg, AbstractPDGNode node) {
    Iterator<? extends AbstractPDGNode> itPred = cfg.getPredNodes(node);
    while (itPred.hasNext()) {
      AbstractPDGNode pred = itPred.next();
      Iterator<? extends AbstractPDGNode> itSucc = cfg.getSuccNodes(node);
      while (itSucc.hasNext()) {
        AbstractPDGNode succ = itSucc.next();
        cfg.addEdge(pred, succ);
      }
    }

    cfg.removeNodeAndEdges(node);
  }