private void printCFG(AST ast) 
    {
        for ( ASTNode node : ast.getChildren() ) 
        {
            if ( node instanceof FunctionDefinitionNode ) 
            {
                final FunctionDefinitionNode function = (FunctionDefinitionNode) node;
                final ControlFlowGraph graph = new ControlFlowAnalyzer().createGraph( function);

                System.out.println("====== "+function.getSignatureAsString()+" ========");

                try ( FileWriter writer = new FileWriter( DOT_OUTPUT ) )
                {
                    writer.write( graph.toDOT() );
                } 
                catch (IOException e) {
                    e.printStackTrace();
                }

                System.out.println( graph.toDOT() );
                
                final DataFlowAnalyzer analyzer = new DataFlowAnalyzer() {

                    @Override
                    protected Node pickNodeToSpill(InterferenceGraph graph)
                    {
                        return graph.getAllNodes().iterator().next();
                    }
                };
                
                analyzer.assignLiveVariables( graph );
                
                final List<BasicBlock> sorted = graph.getAllBlocks();
                Collections.sort(sorted,new Comparator<BasicBlock>() {

                    @Override
                    public int compare(BasicBlock o1, BasicBlock o2)
                    {
                        if ( o1.equals( graph.getFunctionEntry() ) ) {
                            return -1;
                        }
                        if ( o1.equals( graph.getFunctionExit() ) ) {
                            return 1;
                        }    
                        if ( o2.equals( graph.getFunctionEntry() ) ) {
                            return 1;
                        }
                        if ( o2.equals( graph.getFunctionExit() ) ) {
                            return -1;
                        }                         
                        return o1.getIdentifier().compareTo(o2.getIdentifier());
                    }
                } );

                for ( BasicBlock b : sorted ) 
                {
                    System.out.println("============ BLOCK "+b.getIdentifier()+" ===========");
                    System.out.println("ALIVE: "+b.getMetaData().get( DataFlowAnalyzer.ALIVE_VARS_METADATA_KEY ) );
                    System.out.println("====================================================");
                    System.out.println( b );
                    System.out.println("====================================================");
                }
                
                // color graph
                InterferenceGraph interferenceGraph = analyzer.createInterferenceGraph( graph );
                final List<Object> available = Arrays.<Object>asList( Register.A , Register.B , Register.C );
                
                final List<Node> spilled = analyzer.colorGraph( interferenceGraph , available );
                
                System.out.println("============= COLORED ============\n"+interferenceGraph);

                System.out.println("============= SPILLED ============\n");
                for (Node n : spilled ) {
                    System.out.println(n);
                }
                System.out.println("==================================\n");
            }
        }
    }