/// <summary>
        /// Computes the next visible TreeViewItem in order from top to bottom.
        /// Wraps around when it gets to the bottom-most item.
        /// </summary>
        /// <param name="treeViewItem">The starting item.</param>
        /// <returns>The next item in the traversal.</returns>
        private static TreeViewItem NextVisibleTreeViewItem(TreeViewItem treeViewItem)
        {
            // First child
            if (treeViewItem.IsExpanded && treeViewItem.HasItems && treeViewItem.Items.Count > 0)
            {
                return(treeViewItem.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem);
            }

            while (true)
            {
                var parent = treeViewItem.FindVisualAncestor <TreeViewItem>();
                ItemContainerGenerator itemContainerGenerator;
                if (parent == null)
                {
                    var treeView = treeViewItem.FindVisualAncestor <TreeView>();
                    itemContainerGenerator = treeView.ItemContainerGenerator;
                }
                else
                {
                    itemContainerGenerator = parent.ItemContainerGenerator;
                }

                var childIndex = itemContainerGenerator.IndexFromContainer(treeViewItem);
                if (childIndex >= 0 && (childIndex + 1) < itemContainerGenerator.Items.Count)
                {
                    // Next sibling
                    return(itemContainerGenerator.ContainerFromIndex(childIndex + 1) as TreeViewItem);
                }

                // No more siblings
                if (parent == null)
                {
                    // Reached the end. Start at the top again.
                    return(itemContainerGenerator.ContainerFromIndex(0) as TreeViewItem);
                }

                // Go to the parent and find its next sibling.
                treeViewItem = parent;
            }
        }