/// <summary>
        /// Updates the tree if items were removed from an observed
        /// child collection. This might cause rendered tree nodes
        /// to be removed. In case lazy loading is enabled, the update
        /// of the UI may be as subtle as to remove an expander from
        /// a collapsed node if the represented item's childs were
        /// removed.
        /// </summary>
        /// <param name="observed">The observed collection.</param>
        /// <param name="e">The event arguments that provide the
        /// removed items.</param>
        private void HandleRemovedChildItems(ICollection <T> observed, NotifyCollectionChangedEventArgs e)
        {
            IList childs = e.OldItems;

            if (childs.Count == 0)
            {
                return;
            }

            //get the node of the parent item that contains the evented childs
            TreeViewItem parentNode = GetParentNode((T)childs[0], observed);

            if (parentNode == null)
            {
                return;
            }

            foreach (T childItem in childs)
            {
                string itemKey = tree.GetItemKey(childItem);

                //check if we have a corresponding open node
                //-> not necessarily the case if we're doing lazy loading
                TreeViewItem childNode;
                childNode = tree.TryFindItemNode(parentNode.Items, itemKey, false);
                if (childNode != null)
                {
                    //unregister listeners
                    UnregisterListeners(childNode);
                    //remove node from UI
                    parentNode.Items.Remove(childNode);
                }
            }

            //in case of lazy loading, the tree might contain a dummy node
            //(has not been expanded). However, it might be that it's now
            //completely empty...
            if (observed.Count == 0)
            {
                TreeUtil.ClearDummyChildNode(parentNode);
                parentNode.IsExpanded = false;
            }
        }
        /// <summary>
        /// Handles lazy creation of child nodes if a node is being expanded
        /// the first time.
        /// </summary>
        protected virtual void OnNodeExpanded(TreeViewItem treeNode)
        {
            //the node does not represent one of our bound items
            //(custom root or some injected stuff)
            T item = treeNode.Header as T;

            if (item == null)
            {
                return;
            }

            //update the layout
            string itemKey = GetItemKey(item);

            currentLayout.ExpandedNodeIds.Add(itemKey);

            //the tree has already been created - there is nothing more to do here
            if (!IsLazyLoading)
            {
                //the tree has already been created - there is nothing more to do here
                //however, if the node does not contain anything, don't show as expanded
                if (treeNode.Items.Count == 0)
                {
                    treeNode.IsExpanded = false;
                    currentLayout.ExpandedNodeIds.Remove(itemKey);
                }

                return;
            }

            //if we have a dummy node, remove it
            TreeUtil.ClearDummyChildNode(treeNode);

            //get the child items
            ICollection <T> childItems = GetChildItems(item);

            if (treeNode.Items.Count == 0)
            {
                foreach (T childItem in childItems)
                {
                    //create child items with the current layout
                    //-> this also re-expands subitems that were
                    //expanded, but discarded with their ancestor
                    CreateItemNode(childItem, treeNode.Items, currentLayout);
                }

                //refresh to apply sorting
                if (treeNode.Items.NeedsRefresh)
                {
                    treeNode.Items.Refresh();
                }
            }

            if (treeNode.Items.Count == 0)
            {
                //collapse again if there was no data at all
                //unlikely, but the bound item's childs might have changed
                treeNode.IsExpanded = false;
                currentLayout.ExpandedNodeIds.Remove(itemKey);
            }
        }