private void markShared(ControlFlowGraph.Block block) {
    if (ENTRYMAP.get(block) == SHARED) return;
    ENTRYMAP.put(block, SHARED);

    Iterator<ControlFlowGraph.Edge> edges = block.getEdgeIterator();
    while (edges.hasNext()) {
      ControlFlowGraph.Edge edge = edges.next();
      if ("CALL".equals(edge.getType())) continue;
      ControlFlowGraph.Block target = edge.getTarget();
      if (target == null) continue;
      markShared(target);
    }
  }
  private void discoverEntrypoints() {
    ENTRYPOINTS = new HashSet<ControlFlowGraph.Block>();

    // discover edges that have incoming call edges
    Iterator<ControlFlowGraph.Edge> edges = cfg.getEdgeIterator();
    while (edges.hasNext()) {
      ControlFlowGraph.Edge edge = edges.next();
      if ("CALL".equals(edge.getType())) {
        if (edge.getTarget() == null) {
          addIndirectEntrypoints(edge, cfg);
        } else ENTRYPOINTS.add(edge.getTarget());
      }
    }
  }
 private void addIndirectEntrypoints(ControlFlowGraph.Edge edge, ControlFlowGraph cfg) {
   List<Integer> edges = program.getIndirectEdges(edge.getSource().getLastAddress());
   if (edges == null) return;
   for (Integer targetAddr : edges) {
     ControlFlowGraph.Block target = cfg.getBlockStartingAt(targetAddr);
     if (target != null) {
       ENTRYPOINTS.add(target);
     }
   }
 }
  private void propagate(
      ControlFlowGraph.Block entry,
      ControlFlowGraph.Block block,
      HashSet<ControlFlowGraph.Block> seen) {
    if (ENTRYMAP.get(block) == SHARED) return;

    Iterator<ControlFlowGraph.Edge> edges = block.getEdgeIterator();
    while (edges.hasNext()) {
      ControlFlowGraph.Edge edge = edges.next();
      if ("CALL".equals(edge.getType())) continue;
      ControlFlowGraph.Block target = edge.getTarget();
      if (target == null) continue;
      mark(entry, target);

      if (!seen.contains(target)) {
        seen.add(target);
        propagate(entry, target, seen);
      } else {
        seen.add(target);
      }
    }
  }