private static void printGraphViz(ControlFlowGraph controlFlowGraph, SyntaxNode node, HashSet <SyntaxNode> visitedNodes)
        {
            if (!visitedNodes.Contains(node))
            {
                visitedNodes.Add(node);
                var succs = controlFlowGraph.GetSuccessorsB(node);
                foreach (var succ in succs)
                {
                    int v = succ.Value;
                    var s = succ;

                    /*while (true)
                     * {
                     *  var su = controlFlowGraph.GetSuccessorsB(s.Key);
                     *  if (su.Count != 1)
                     *  {
                     *      break;
                     *  }
                     *  s = su.Single();
                     * }*/
                    if (v == 1)
                    {
                        Console.WriteLine("\"{0}\" -> \"{1}\" [color=\"#00ff00\"];", node.GetLocation().ToString(), s.Key.GetLocation().ToString());
                    }
                    if (v == 0)
                    {
                        Console.WriteLine("\"{0}\" -> \"{1}\" [color=\"#ff0000\"];", node.GetLocation().ToString(), s.Key.GetLocation().ToString());
                    }
                    if (v == -1)
                    {
                        Console.WriteLine("\"{0}\" -> \"{1}\";", node.GetLocation().ToString(), s.Key.GetLocation().ToString());
                    }
                    printGraphViz(controlFlowGraph, s.Key, visitedNodes);
                }
            }
        }
        private static void outputNumericalValueOutput(ControlFlowGraph graph, SyntaxNode node, HashSet <SyntaxNode> history, StringBuilder builder)
        {
            if (!history.Contains(node))
            {
                history.Add(node);
                builder.AppendFormat("  {{ \"key\": \"{0}\",\n    \"value\": ", location(node));
                if (node is LocalDeclarationStatementSyntax || node is VariableDeclarationSyntax)
                {
                    VariableDeclarationSyntax s;
                    if (node is LocalDeclarationStatementSyntax)
                    {
                        s = (node as LocalDeclarationStatementSyntax).Declaration;
                    }
                    else
                    {
                        s = node as VariableDeclarationSyntax;
                    }
                    builder.Append("{ \"type\": \"variable_declaration\", \"declarations\": [");

                    bool firstVar = true;
                    foreach (var v in s.Variables)
                    {
                        if (firstVar)
                        {
                            firstVar = false;
                        }
                        else
                        {
                            builder.Append(",");
                        }
                        builder.AppendFormat(" {{ \"identifier\": \"{0}\", \"initializer\": ", v.Identifier);
                        if (v.Initializer == null)
                        {
                            builder.Append("null");
                        }
                        else
                        {
                            outputNumericalValueOutput(v.Initializer.Value, builder);
                        }
                        builder.Append(" }");
                    }
                    builder.Append(" ] }");
                }
                else if (node is AssignmentExpressionSyntax || (node is ExpressionStatementSyntax && (node as ExpressionStatementSyntax).Expression is AssignmentExpressionSyntax))
                {
                    AssignmentExpressionSyntax s;
                    if (node is AssignmentExpressionSyntax)
                    {
                        s = node as AssignmentExpressionSyntax;
                    }
                    else
                    {
                        s = (node as ExpressionStatementSyntax).Expression as AssignmentExpressionSyntax;
                    }
                    builder.AppendFormat("{{ \"type\": \"variable_assignment\", \"left\": \"{0}\", \"right\": ", s.Left);
                    outputNumericalValueOutput(s.Right, builder);
                    builder.Append(" }");
                }
                else if (node is BinaryExpressionSyntax)
                {
                    builder.Append("{ \"type\": \"comparison\", \"left\": ");
                    var s = node as BinaryExpressionSyntax;
                    outputNumericalValueOutput(s.Left, builder);
                    builder.AppendFormat(", \"op\": \"{0}\", \"right\": ", s.OperatorToken);
                    outputNumericalValueOutput(s.Right, builder);
                    builder.Append(" }");
                }
                else
                {
                    builder.Append("{ \"type\": \"other\" }");
                }
                builder.Append(",\n    \"successors\": [");
                bool firstSucc = true;
                foreach (var succ in graph.GetSuccessorsB(node))
                {
                    if (firstSucc)
                    {
                        firstSucc = false;
                    }
                    else
                    {
                        builder.Append(", ");
                    }
                    builder.AppendFormat("{{ \"key\": \"{0}\", \"value\": {1} }}", location(succ.Key), succ.Value);
                }
                builder.Append("] }");
                foreach (var succ in graph.GetSuccessors(node))
                {
                    if (!history.Contains(succ))
                    {
                        builder.Append(",\n");
                    }
                    outputNumericalValueOutput(graph, succ, history, builder);
                }
            }
        }
        private void analyze(ControlFlowGraph graph, SyntaxNode node, Dictionary <string, NumericalValue <int> > variables, Dictionary <SyntaxNode, Dictionary <string, NumericalValue <int> > > history)
        {
            #region Union usagesAfter with reachingDefinitions
            if (history.ContainsKey(node))
            {
                bool anyChanged = false;
                foreach (var pair in history[node])
                {
                    if (variables.ContainsKey(pair.Key))
                    {
                        var    i   = variables[pair.Key];
                        string old = i.ToString();
                        //Console.WriteLine("{0} vs {1} and {2}", old, i, pair.Value);
                        i.UnionWith(pair.Value);
                        if (!old.Equals(i.ToString()))
                        {
                            anyChanged = true;
                        }
                    }
                    else
                    {
                        variables.Add(pair.Key, pair.Value.Clone());
                        anyChanged = true;
                    }
                }
                if (history[node].Count == 0 && variables.Count != 0)
                {
                    anyChanged = true;
                }
                if (!anyChanged)
                {
                    return;
                }
                else
                {
                    var clone = new Dictionary <string, NumericalValue <int> >();
                    foreach (var v in variables)
                    {
                        clone.Add(v.Key, v.Value.Clone());
                    }
                    history[node] = clone;
                }
            }
            else
            {
                var clone = new Dictionary <string, NumericalValue <int> >();
                foreach (var v in variables)
                {
                    clone.Add(v.Key, v.Value.Clone());
                }
                history.Add(node, clone);
            }
            #endregion

            NumericalValue <int> rangeTrue  = null;
            NumericalValue <int> rangeFalse = null;
            string rangeVar = null;

            #region Process node
            if (node is LocalDeclarationStatementSyntax || node is VariableDeclarationSyntax)
            {
                VariableDeclarationSyntax s;
                if (node is LocalDeclarationStatementSyntax)
                {
                    s = (node as LocalDeclarationStatementSyntax).Declaration;
                }
                else
                {
                    s = node as VariableDeclarationSyntax;
                }

                foreach (var v in s.Variables)
                {
                    if (v.Initializer != null)
                    {
                        if (v.Initializer.Value is LiteralExpressionSyntax)
                        {
                            var valS = (v.Initializer.Value as LiteralExpressionSyntax).Token.ValueText;
                            int valI;
                            if (int.TryParse(valS, out valI))
                            {
                                var valNV = new NumericalValue <int>(valI);
                                if (variables.ContainsKey(v.Identifier.ToString()))
                                {
                                    variables[v.Identifier.ToString()].AssignValue(valNV);
                                }
                                else
                                {
                                    variables.Add(v.Identifier.ToString(), valNV);
                                }
                            }
                        }
                        else if (v.Initializer.Value is IdentifierNameSyntax)
                        {
                            var valNV = variables[v.Initializer.Value.ToString()];
                            if (variables.ContainsKey(v.Identifier.ToString()))
                            {
                                variables[v.Identifier.ToString()].AssignValue(valNV);
                            }
                            else
                            {
                                variables.Add(v.Identifier.ToString(), valNV);
                            }
                        }
                        else
                        {
                            var valNV = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                            if (variables.ContainsKey(v.Identifier.ToString()))
                            {
                                variables[v.Identifier.ToString()].AssignValue(valNV);
                            }
                            else
                            {
                                variables.Add(v.Identifier.ToString(), valNV);
                            }
                        }
                    }
                }
            }
            else if (node is ExpressionStatementSyntax && (node as ExpressionStatementSyntax).Expression is AssignmentExpressionSyntax)
            {
                var s = (node as ExpressionStatementSyntax).Expression as AssignmentExpressionSyntax;
                if (s.Right is LiteralExpressionSyntax)
                {
                    var valS = (s.Right as LiteralExpressionSyntax).Token.ValueText;
                    int valI;
                    if (int.TryParse(valS, out valI))
                    {
                        var valNV = new NumericalValue <int>(valI);
                        if (variables.ContainsKey(s.Left.ToString()))
                        {
                            variables[s.Left.ToString()].AssignValue(valNV);
                        }
                        else
                        {
                            variables.Add(s.Left.ToString(), valNV);
                        }
                    }
                }
                else if (s.Right is IdentifierNameSyntax)
                {
                    var valNV = variables[s.Right.ToString()];
                    if (variables.ContainsKey(s.Left.ToString()))
                    {
                        variables[s.Left.ToString()].AssignValue(valNV);
                    }
                    else
                    {
                        variables.Add(s.Left.ToString(), valNV);
                    }
                }
                else
                {
                    var valNV = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                    if (variables.ContainsKey(s.Left.ToString()))
                    {
                        variables[s.Left.ToString()].AssignValue(valNV);
                    }
                    else
                    {
                        variables.Add(s.Left.ToString(), valNV);
                    }
                }
            }
            else if (node is BinaryExpressionSyntax)
            {
                var n = node as BinaryExpressionSyntax;
                if (n.Right is LiteralExpressionSyntax)
                {
                    int value;
                    if (int.TryParse((n.Right as LiteralExpressionSyntax).Token.ValueText, out value))
                    {
                        if (n.OperatorToken.ToString().Equals("<"))
                        {
                            rangeTrue  = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.EXCLUSIVE);
                            rangeFalse = new NumericalValue <int>(value, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                            rangeVar   = n.Left.ToString();
                        }
                        if (n.OperatorToken.ToString().Equals("<="))
                        {
                            rangeTrue  = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.INCLUSIVE);
                            rangeFalse = new NumericalValue <int>(value, Inclusivity.EXCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                            rangeVar   = n.Left.ToString();
                        }
                        if (n.OperatorToken.ToString().Equals(">"))
                        {
                            rangeTrue  = new NumericalValue <int>(value, Inclusivity.EXCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                            rangeFalse = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.INCLUSIVE);
                            rangeVar   = n.Left.ToString();
                        }
                        if (n.OperatorToken.ToString().Equals(">="))
                        {
                            rangeTrue  = new NumericalValue <int>(value, Inclusivity.INCLUSIVE, int.MaxValue, Inclusivity.INCLUSIVE);
                            rangeFalse = new NumericalValue <int>(int.MinValue, Inclusivity.INCLUSIVE, value, Inclusivity.EXCLUSIVE);
                            rangeVar   = n.Left.ToString();
                        }
                    }
                }
            }

            if (debug)
            {
                Console.WriteLine("({0}): {1} {2}", node.GetLocation().GetLineSpan().StartLinePosition, node, node.GetType());
                foreach (var pair in variables)
                {
                    Console.WriteLine("  {0} -> {1}", pair.Key, pair.Value);
                }
            }
            #endregion

            #region Recurse
            foreach (var succ in graph.GetSuccessorsB(node))
            {
                var variablesPrime = new Dictionary <string, NumericalValue <int> >();
                foreach (var v in variables)
                {
                    variablesPrime.Add(v.Key, v.Value.Clone());
                }
                if (succ.Value == 0)
                {
                    variablesPrime[rangeVar].IntersectWith(rangeFalse);
                }
                else if (succ.Value == 1)
                {
                    variablesPrime[rangeVar].IntersectWith(rangeTrue);
                }
                analyze(graph, succ.Key, variablesPrime, history);
            }
            #endregion
        }