@Override
    public CFG createCFG() {
        CFG cfg = new CFG(null);
        BasicBlock start = new BasicBlock("PROGRAM-START", BasicBlock.NOT_REDUCIBLE);
        BasicBlock end = new BasicBlock("PROGRAM-END", BasicBlock.REDUCIBLE_SINGLETON);
        cfg.start = start;
        cfg.end = end;
        cfg.addVertex(start);
        cfg.addVertex(end);
        CFG firstCFG = body.get(0).createCFG();
        cfg.addVertex(firstCFG.start);
        cfg.addVertex(firstCFG.end);
        cfg.addEdge(start, firstCFG.start);
        BasicBlock prev = firstCFG.end;
        // If there is only one node, then we would fall through the for loop, so
        // we just copy over all nodes in the CFG here. TODO: Don't Copy Paste
        if (body.size() == 1) {
            firstCFG.vertexSet()
                    .stream()
                        .forEachOrdered(block ->
                            firstCFG
                                    .edgesOf(block)
                                    .stream()
                                    .forEachOrdered(edge -> {
                                        BasicBlock src = firstCFG.getEdgeSource(edge);
                                        BasicBlock tgt = firstCFG.getEdgeTarget(edge);
                                        cfg.addVertex(src);
                                        cfg.addVertex(tgt);
                                        cfg.addEdge(src, tgt);
                                    })
                        );
        }
        for (ASTNode node : body.subList(1, body.size())) {
            if (node instanceof IfConditionalASTNode) {
                Logger.getAnonymousLogger().info(node.getClass().getName());
            }
            CFG stmtCFG = node.createCFG();
            if (stmtCFG == null) { 
                continue;
            }
            cfg.addVertex(stmtCFG.start);
            cfg.addVertex(stmtCFG.end);
            cfg.addEdge(prev, stmtCFG.start);
            Logger.getAnonymousLogger().info(stmtCFG.toString());
            stmtCFG.vertexSet()
                    .stream()
                        .forEachOrdered(block ->
                            stmtCFG
                                    .edgesOf(block)
                                    .stream()
                                    .forEachOrdered(edge -> {
                                        BasicBlock src = stmtCFG.getEdgeSource(edge);
                                        BasicBlock tgt = stmtCFG.getEdgeTarget(edge);
                                        if (node instanceof IfConditionalASTNode) {
                                            Logger.getAnonymousLogger().info("Bridging Gap for: " + src + " and " + tgt);
                                        }
                                        cfg.addVertex(src);
                                        cfg.addVertex(tgt);
                                        cfg.addEdge(src, tgt);
                                    })
                        );
            prev = stmtCFG.end;
        }
        cfg.addEdge(prev, end);
        removeTrivialNodes(cfg);
        Logger.getAnonymousLogger().info("Reducing...");
        Set<BasicBlock> processed = new TreeSet<>();
        reduceCFG(cfg, processed);
//        processed.clear();
//        reduceCFG(cfg, processed);
        return cfg;                
    }
@Override
    public CFG createCFG() {
        CFG cfg = new CFG(null);
        BasicBlock start = new BasicBlock("PROGRAM-START", BasicBlock.NOT_REDUCIBLE);
        BasicBlock end = new BasicBlock("PROGRAM-END", BasicBlock.REDUCIBLE_SINGLETON);
        cfg.start = start;
        cfg.end = end;
        cfg.addVertex(start);
        cfg.addVertex(end);
        CFG firstCFG = body.get(0).createCFG();
        cfg.addVertex(firstCFG.start);
        cfg.addVertex(firstCFG.end);
        cfg.addEdge(start, firstCFG.start);
        BasicBlock prev = firstCFG.end;
       
       
        if (body.size() == 1) {
            firstCFG.vertexSet()
                    .stream()
                        .forEachOrdered(block ->
                            firstCFG
                                    .edgesOf(block)
                                    .stream()
                                    .forEachOrdered(edge -> {
                                        BasicBlock src = firstCFG.getEdgeSource(edge);
                                        BasicBlock tgt = firstCFG.getEdgeTarget(edge);
                                        cfg.addVertex(src);
                                        cfg.addVertex(tgt);
                                        cfg.addEdge(src, tgt);
                                    })
                        );
        }
        for (ASTNode node : body.subList(1, body.size())) {
            if (node instanceof IfConditionalASTNode) {
                Logger.getAnonymousLogger().info(node.getClass().getName());
            }
            CFG stmtCFG = node.createCFG();
            if (stmtCFG == null) { 
                continue;
            }
            cfg.addVertex(stmtCFG.start);
            cfg.addVertex(stmtCFG.end);
            cfg.addEdge(prev, stmtCFG.start);
            Logger.getAnonymousLogger().info(stmtCFG.toString());
            stmtCFG.vertexSet()
                    .stream()
                        .forEachOrdered(block ->
                            stmtCFG
                                    .edgesOf(block)
                                    .stream()
                                    .forEachOrdered(edge -> {
                                        BasicBlock src = stmtCFG.getEdgeSource(edge);
                                        BasicBlock tgt = stmtCFG.getEdgeTarget(edge);
                                        if (node instanceof IfConditionalASTNode) {
                                            Logger.getAnonymousLogger().info("Bridging Gap for: " + src + " and " + tgt);
                                        }
                                        cfg.addVertex(src);
                                        cfg.addVertex(tgt);
                                        cfg.addEdge(src, tgt);
                                    })
                        );
            prev = stmtCFG.end;
        }
        cfg.addEdge(prev, end);
        removeTrivialNodes(cfg);
        Logger.getAnonymousLogger().info("Reducing...");
        Set<BasicBlock> processed = new TreeSet<>();
        reduceCFG(cfg, processed);
        return cfg;                
    }
@override public cfg createcfg() { cfg cfg = new cfg(null); basicblock start = new basicblock("program-start", basicblock.not_reducible); basicblock end = new basicblock("program-end", basicblock.reducible_singleton); cfg.start = start; cfg.end = end; cfg.addvertex(start); cfg.addvertex(end); cfg firstcfg = body.get(0).createcfg(); cfg.addvertex(firstcfg.start); cfg.addvertex(firstcfg.end); cfg.addedge(start, firstcfg.start); basicblock prev = firstcfg.end; if (body.size() == 1) { firstcfg.vertexset() .stream() .foreachordered(block -> firstcfg .edgesof(block) .stream() .foreachordered(edge -> { basicblock src = firstcfg.getedgesource(edge); basicblock tgt = firstcfg.getedgetarget(edge); cfg.addvertex(src); cfg.addvertex(tgt); cfg.addedge(src, tgt); }) ); } for (astnode node : body.sublist(1, body.size())) { if (node instanceof ifconditionalastnode) { logger.getanonymouslogger().info(node.getclass().getname()); } cfg stmtcfg = node.createcfg(); if (stmtcfg == null) { continue; } cfg.addvertex(stmtcfg.start); cfg.addvertex(stmtcfg.end); cfg.addedge(prev, stmtcfg.start); logger.getanonymouslogger().info(stmtcfg.tostring()); stmtcfg.vertexset() .stream() .foreachordered(block -> stmtcfg .edgesof(block) .stream() .foreachordered(edge -> { basicblock src = stmtcfg.getedgesource(edge); basicblock tgt = stmtcfg.getedgetarget(edge); if (node instanceof ifconditionalastnode) { logger.getanonymouslogger().info("bridging gap for: " + src + " and " + tgt); } cfg.addvertex(src); cfg.addvertex(tgt); cfg.addedge(src, tgt); }) ); prev = stmtcfg.end; } cfg.addedge(prev, end); removetrivialnodes(cfg); logger.getanonymouslogger().info("reducing..."); set<basicblock> processed = new treeset<>(); reducecfg(cfg, processed); return cfg; }