/**
   * Finds the entry node of the main method of the given sdg.
   *
   * @param g sdg to find main entry node of
   * @return entry node of the main method of the given sdg
   */
  private static SDGNode findMainEntry(CFG g) {
    for (SDGNode n : g.vertexSet()) {
      if (g.inDegreeOf(n) == 0) {
        // assert n.getBytecodeMethod().contains("main([Ljava/lang/String;)V");
        return n;
      }
    }

    throw new IllegalStateException();
  }
  private static SDGNode findExitNode(SDGNode node, CFG cfg) {
    SDGNode entry = cfg.getEntry(node);
    LinkedList<SDGNode> wl = new LinkedList<SDGNode>();
    Set<SDGNode> visited = new HashSet<SDGNode>();
    wl.add(entry);
    while (!wl.isEmpty()) {
      SDGNode n = wl.poll();
      visited.add(n);
      if (n.getKind() == SDGNode.Kind.EXIT) {
        return n;
      } else {

        for (SDGEdge e : cfg.outgoingEdgesOf(n)) {
          if (!visited.contains(e.getTarget()) && e.getKind() == SDGEdge.Kind.CONTROL_FLOW) {
            wl.add(e.getTarget());
          }
        }
      }
    }

    throw new IllegalStateException(
        "Visited the following nodes, which not include an exit node: " + visited);
  }