public void VisualizeAsTreeRecursion(TreeNode node,
                                             IReadOnlyTable <double> variableTable,
                                             IReadOnlyTable <FinishedFunction> functionTable,
                                             bool recursivelyVisualiseFunctions,
                                             string colorStr)
        {
            for (int i = 0; i < colorStr.Length; ++i)
            {
                if (colorStr[i] == '0')
                {
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                if (colorStr[i] == '1')
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                }
                if (colorStr[i] == '2')
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                }
                if (colorStr[i] == '3')
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                }
                Console.Write("|   ");
                Console.ResetColor();
            }

            switch (node)
            {
            case NumberTreeNode lTreeNode:
            {
                Console.WriteLine(lTreeNode.Value.ToString("G7", System.Globalization.CultureInfo.InvariantCulture));
            }
            break;

            case UndefinedVariableTreeNode vTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine(vTreeNode.Name);
                Console.ResetColor();
            }
            break;

            case FunctionParameterTreeNode fpTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine(String.Format("${0}", fpTreeNode.Index));
                Console.ResetColor();
            }
            break;

            case VariableIndexTreeNode iTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(String.Format("V:{0}", iTreeNode.Index));
                Console.ResetColor();
            }
            break;

            case FunctionIndexTreeNode fiTreeNode:
            {
                if (recursivelyVisualiseFunctions)
                {
                    TreeNode      clone  = functionTable[fiTreeNode.Index].TopNode.Clone();
                    DefaultLinker linker = new DefaultLinker();
                    clone = linker.ReplaceParametersWithTreeNodes(clone, fiTreeNode.Parameters);

                    VisualizeAsTreeRecursion(clone, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr);
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine(String.Format("[F:{0}]", fiTreeNode.Index));
                    foreach (TreeNode child in fiTreeNode.Parameters)
                    {
                        VisualizeAsTreeRecursion(child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '3');
                    }
                    Console.ResetColor();
                }
            }
            break;

            case UndefinedFunctionTreeNode fTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.WriteLine(String.Format("{0}()", fTreeNode.Name));
                Console.ResetColor();
                foreach (TreeNode child in fTreeNode.Parameters)
                {
                    VisualizeAsTreeRecursion(child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '0');
                }
                break;
            }

            case UnaryOperationTreeNode uTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(String.Format("[{0}]", uTreeNode.Operation.FunctionName));
                Console.ResetColor();
                VisualizeAsTreeRecursion(uTreeNode.Child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '1');
                break;
            }

            case BinaryOperationTreeNode bTreeNode:
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(String.Format("[{0}]", bTreeNode.Operation.FunctionName));
                Console.ResetColor();
                VisualizeAsTreeRecursion(bTreeNode.LeftChild, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '2');
                VisualizeAsTreeRecursion(bTreeNode.RightChild, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '2');
                break;
            }
            }

            /*
             * for (int i = 0; i < level; ++i)
             * {
             *      Console.Write("|   ");
             * }
             * Console.WriteLine();
             */
        }