/// <summary>
        /// Expands the nodeInfo.
        /// </summary>
        /// <param name="nodeInfo">The nodeInfo.</param>
        /// <returns>false to cancel</returns>
        public bool ExpandNode(TreeNode node)
        {
            // get rid of the dummy
            TreeNode[] removeNodes = node.Nodes.Cast<TreeNode>().ToArray();
            NodeInfo nodeInfo = node.GetInfo();

            return this.AddSubNodes(nodeInfo, () =>
            {
                // remove the original nodeInfo when finished
                foreach (TreeNode n in removeNodes)
                {
                    this.Nodes.Remove(n);
                }
            });
        }
        /// <summary>
        /// Returns all the exceptions that a tree nodeInfo and it's child nodeInfo point to.
        /// </summary>
        /// <param name="nodeInfo">The nodeInfo.</param>
        /// <returns>
        /// The exceptions that a nodeInfo and it's child nodeInfo point to.
        /// </returns>
        private IEnumerable<ThrownException> AddList(TreeNode node)
        {
            Class cls = node.GetInfo().GetAnalysisObject<Class>();

            IEnumerable<ThrownException> l = null;

            if (cls != null)
            {
                Type type = cls.ClassType;
                l = this.ExceptionTree.ExceptionDictionary.GetList(type);
            }
            else
            {
                l = new ThrownException[] { };
            }

            foreach (TreeNode child in node.Nodes)
            {
                l = l.Concat(this.AddList(child));
            }

            node.GetInfo().ExtraData = l;
            return l;
        }
            public static ReloadNode Create(TreeNode node)
            {
                AssemblyItem asm = node.GetInfo().GetAnalysisObject<AssemblyItem>();

                if (asm == null)
                {
                    return null;
                }

                return new ReloadNode()
                {
                    Filename = asm.Assembly.Location,
                    Expanded = node.IsExpanded
                };
            }
        private void UpdateNode(TreeNode node)
        {
            NodeInfo info = node.GetInfo();
            if (info != null)
            {
                node.GetInfo().UpdateNode();
            }

            foreach (TreeNode child in node.Nodes)
            {
                this.UpdateNode(child);
            }
        }
        public void ShowCallStack(CallStack callStack, TreeNode startAt, CancellationToken cancelToken)
        {
            if (callStack.Count == 0)
            {
                return;
            }

            // start from the bottom of the stack
            CallStack stack = new CallStack(callStack.Reverse());

            TreeNode lastExistingNode = null;
            TreeNode newNodesRoot = null;
            NodeInfo nodeInfo = startAt.GetInfo();
            TreeNode node = nodeInfo.Node;
            TreeNode lastNode = node;

            bool first = nodeInfo.GetAnalysisObject<Method>() == stack.Peek();

            while (stack.Count >= 0)
            {
                if ((node.Nodes.Count == 0) || (node.Nodes[0].Tag == null))
                {
                    // hasn't got the child nodeInfo yet.

                    nodeInfo = node.GetInfo();

                    if (newNodesRoot == null)
                    {
                        lastExistingNode = node;
                        node = newNodesRoot = new TreeNode();
                    }
                    else
                    {
                        node.Nodes.Clear();
                    }

                    TreeNode[] childNodes = this.CreateSubNodes(nodeInfo, cancelToken);
                    node.Nodes.AddRange(childNodes);
                }

                lastNode = node;

                if (stack.Count == 0)
                {
                    break;
                }

                Method method = stack.Pop();
                if (!first)
                {
                    node = this.FindNode(ni => ni.GetAnalysisObject<Method>() == method, node, 1);
                }
                first = false;
            }

            this.InvokeIfRequired(() =>
            {
                if ((lastExistingNode.Nodes.Count == 0) || (lastExistingNode.Nodes[0].Tag == null))
                {
                    lastExistingNode.Nodes.Clear();
                }

                lastExistingNode.Nodes.AddRange(newNodesRoot.Nodes.Cast<TreeNode>().ToArray());
                lastNode.EnsureVisible();
                this.SelectedNode = lastNode;
            });
        }
        public void ReloadClassNodes(TreeNode node)
        {
            NodeInfo info = node.GetInfo();

            if ((info != null) && info.Type.HasFlag(NodeType.Class))
            {
                node.Collapse(true);
                node.Nodes.Clear();
                node.Nodes.Add(this.CreateLazyDummyNode());
                return;
            }

            foreach (TreeNode n in node.Nodes)
            {
                this.ReloadClassNodes(n);
            }
        }