private void PopulateBlock(TreeNode Node, Block Block)
        {
            if (Block.Elements.Count == 0)
            {
                Node.Text += "<Empty block>";
            }
            else
            {
                TreeNodeCollection nds = Node.Nodes;

                foreach (Element el in Block.Elements)
                {
                    PopulateElement(el, nds);
                }

                Node.Expand();
            }
        }
        private void PopulateElement(Element Item, TreeNodeCollection Nodes)
        {
            TreeNode nd;

            if (Item == null)
            {
                nd = Nodes.Add("<Nothing>");
            }
            else if (Item is Block)
            {
                Block bl = (Block)Item;

                nd = Nodes.Add((bl.Name != "") ? "#" + bl.Name + "#" : "");
                switch (bl.Type)
                {
                case Block.eType.Multi:
                    nd.Text += "[Multi Block]";
                    break;

                default:
                    nd.Text += "[Block]";
                    break;
                }
                PopulateBlock(nd, bl);
            }
            else if (Item is FunctionCall)
            {
                var fc = Item as FunctionCall;
                nd = Nodes.Add("Call " + fc.Name + "(" + ((fc.Arguments.Count > 0) ? fc.Arguments.Aggregate("", (current, e) => current + ("," + e)).Substring(1) : "") + ")");
                foreach (var el in fc.Arguments)
                {
                    PopulateElement(el, nd.Nodes);
                }
            }
            else if (Item is TextSearch)
            {
                nd = Nodes.Add("Match '" + ((TextSearch)Item).Pattern + "'");
                TextSearch ts = (TextSearch)Item;
                switch (ts.Type)
                {
                case TextSearch.eType.Find:
                    nd.Text += " (Find)";
                    break;

                case TextSearch.eType.FindReverse:
                    nd.Text += " (Find reverse)";
                    break;

                case TextSearch.eType.RegularExpression:
                    nd.Text += " (Regular expression)" + ts.Tree.Aggregate("", (current, v) => current + ("." + v));
                    break;
                }
            }
            else if (Item is Literal)
            {
                Literal lt = (Literal)Item;

                switch (lt.Type)
                {
                case Literal.eType.Text:
                    nd = Nodes.Add("Text literal '" + lt.AssemblyDisplayText + "'");
                    break;

                case Literal.eType.Number:
                    nd = Nodes.Add("Number literal '" + lt.Number.ToString() + "'");
                    break;

                default:
                    nd = Nodes.Add("Unknown literal '" + lt + "'");
                    break;
                }
            }
            else if (Item is Variable)
            {
                var    vr = (Variable)Item;
                string s;

                switch (vr.Type)
                {
                case Variable.eType.Variable:
                    s = "%" + vr.Name + "%" + vr.Nodes.Aggregate("", (current, v) => current + ("." + v));
                    break;

                case Variable.eType.Tree:
                    if (vr.Nodes.Count == 0)
                    {
                        s = "Tree";
                    }
                    else
                    {
                        s = vr.Nodes.Aggregate("", (current, v) => current + ("." + v)).Substring(1);
                    }
                    break;

                case Variable.eType.RetVal:
                    s = "RetVal" + vr.Nodes.Aggregate("", (current, v) => current + ("." + v));
                    break;

                case Variable.eType.Setting:
                    s = "@" + vr.Name + "@" + vr.Nodes.Aggregate("", (current, v) => current + ("." + v));
                    break;

                case Variable.eType.Skipped:
                    s = "Skipped";
                    break;

                case Variable.eType.Source:
                    s = "Source";
                    break;

                case Variable.eType.New:
                    s = "New";
                    break;

                default:
                    s = "???" + vr.Nodes.Aggregate("", (current, v) => current + ("." + v));
                    break;
                }

                nd = Nodes.Add(s);
                vr.Nodes.ForEach(v => PopulateElement(v.Key, nd.Nodes));
            }
            else if (Item is BinaryOperator)
            {
                var cmp = (BinaryOperator)Item;
                switch (cmp.Type)
                {
                case BinaryOperator.eType.Equal:
                    nd = Nodes.Add("Equal");
                    break;

                case BinaryOperator.eType.NotEqual:
                    nd = Nodes.Add("Not Equal");
                    break;

                case BinaryOperator.eType.ReferenceCopy:
                    nd = Nodes.Add("Reference Copy");
                    break;

                case BinaryOperator.eType.ReferenceEqual:
                    nd = Nodes.Add("Reference Equal");
                    break;

                case BinaryOperator.eType.ReferenceNotEqual:
                    nd = Nodes.Add("Reference Not Equal");
                    break;

                case BinaryOperator.eType.TildeAppend:
                    nd = Nodes.Add("Tilde Append");
                    break;

                case BinaryOperator.eType.Tilde:
                    nd = Nodes.Add("Tilde");
                    break;

                case BinaryOperator.eType.Pipe:
                    nd = Nodes.Add("Pipe");
                    break;

                case BinaryOperator.eType.TextAppend:
                    nd = Nodes.Add("Text append");
                    break;

                case BinaryOperator.eType.TreeAppend:
                    nd = Nodes.Add("Tree append");
                    break;

                default:
                    nd = Nodes.Add("Unknown Binary Operator");
                    break;
                }
                PopulateElement(cmp.lhs, nd.Nodes);
                PopulateElement(cmp.rhs, nd.Nodes);
                nd.Expand();
            }
            else if (Item is ControlFlow)
            {
                ControlFlow ret = (ControlFlow)Item;
                nd = Nodes.Add(ret.Type.ToString());
                if (ret.Name != null)
                {
                    nd.Text += ":" + ret.Name;
                }
            }
            else
            {
                nd = Nodes.Add("<Undefined>");
            }

            if (Item != null)
            {
                string q = Item.Quantifier.ToString();
                if (q != "")
                {
                    nd.Text += q;
                }

                nd.Text += ":" + Item.ReturnType.ToString();

                Item.Annotation.TreeViewNode = nd;
                nd.Tag = Item.Annotation;
            }
        }
        private void PopulateBlock(TreeNode Node, Block Block)
        {
            if (Block.Elements.Count == 0)
                Node.Text += "<Empty block>";
            else
            {
                TreeNodeCollection nds = Node.Nodes;

                foreach (Element el in Block.Elements)
                    PopulateElement(el, nds);

                Node.Expand();
            }
        }