/// <summary>
        /// Handles changes on the <see cref="ObserveChildItemsProperty"/> dependency property. As
        /// WPF internally uses the dependency property system and bypasses the
        /// <see cref="ObserveChildItems"/> property wrapper, updates should be handled here.
        /// </summary>
        /// <param name="d">The currently processed owner of the property.</param>
        /// <param name="e">Provides information about the updated property.</param>
        private static void ObserveChildItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //don't do anything if the control is being created
            TreeViewBase <T> owner = (TreeViewBase <T>)d;

            if (!owner.IsInitialized)
            {
                return;
            }

            //recreate the three
            owner.Refresh(owner.GetTreeLayout());
        }
        /// <summary>
        /// Handles changes on the <see cref="RootNodeProperty"/> dependency property. As
        /// WPF internally uses the dependency property system and bypasses the
        /// <see cref="RootNode"/> property wrapper, updates should be handled here.
        /// </summary>
        /// <param name="d">The currently processed owner of the property.</param>
        /// <param name="e">Provides information about the updated property.</param>
        private static void RootNodePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //just recreate the tree - this takes care of everything
            TreeViewBase <T> owner    = (TreeViewBase <T>)d;
            TreeViewItem     newValue = (TreeViewItem)e.NewValue;

            //don't do anything if the control is being created
            if (!owner.IsInitialized)
            {
                return;
            }

            owner.Refresh(owner.GetTreeLayout());

            //apply sorting on root or tree (if the new value is null)
            owner.ApplySorting(newValue, null);
        }