/// <summary>
        /// Render the treeview with the first two levels of albums that are viewable to the logged on user.
        /// </summary>
        private TreeView Generate()
        {
            _tv = new TreeView
            {
                EnableCheckBoxPlugin = _tvOptions.EnableCheckboxPlugin
            };

            foreach (IAlbum rootAlbum in GetRootAlbums())
            {
                // Add root node.
                TreeNode rootNode = new TreeNode();

                string albumTitle = GetRootAlbumTitle(rootAlbum);
                rootNode.Text     = albumTitle;
                rootNode.ToolTip  = albumTitle;
                rootNode.Id       = String.Concat("tv_", rootAlbum.Id.ToString(CultureInfo.InvariantCulture));
                rootNode.DataId   = rootAlbum.Id.ToString(CultureInfo.InvariantCulture);
                rootNode.Expanded = true;
                rootNode.AddCssClass("jstree-root-node");

                if (!String.IsNullOrEmpty(_tvOptions.NavigateUrl))
                {
                    var url = rootAlbum.IsVirtualAlbum ? _tvOptions.NavigateUrl : Utils.AddQueryStringParameter(_tvOptions.NavigateUrl, String.Concat("aid=", rootAlbum.Id.ToString(CultureInfo.InvariantCulture)));
                    rootNode.NavigateUrl = url;
                }

                if (_tvOptions.EnableCheckboxPlugin)
                {
                    rootNode.ShowCheckBox = !rootAlbum.IsVirtualAlbum && Utils.IsUserAuthorized(_tvOptions.RequiredSecurityPermissions, RoleController.GetGalleryServerRolesForUser(), rootAlbum.Id, rootAlbum.GalleryId, rootAlbum.IsPrivate, SecurityActionsOption.RequireOne, rootAlbum.IsVirtualAlbum);
                    rootNode.Selectable   = rootNode.ShowCheckBox;
                }
                else
                {
                    rootNode.Selectable = true;
                }
                //if (!rootNode.Selectable) rootNode.HoverCssClass = String.Empty;

                // Select and check this node if needed.
                if (_tvOptions.SelectedAlbumIds.Contains(rootAlbum.Id))
                {
                    rootNode.Selected = true;
                }

                _tv.Nodes.Add(rootNode);

                // Add the first level of albums below the root album.
                BindAlbumToTreeview(rootAlbum.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).ToSortedList(), rootNode, false);

                // Only display the root node if it is selectable or we added any children to it; otherwise, remove it.
                if (!rootNode.Selectable && rootNode.Nodes.Count == 0)
                {
                    _tv.Nodes.Remove(rootNode);
                }
            }

            // Make sure all specified albums are visible and checked.
            foreach (int albumId in _tvOptions.SelectedAlbumIds)
            {
                IAlbum album = AlbumController.LoadAlbumInstance(albumId, false);
                if (Utils.IsUserAuthorized(_tvOptions.RequiredSecurityPermissions, RoleController.GetGalleryServerRolesForUser(), album.Id, album.GalleryId, album.IsPrivate, SecurityActionsOption.RequireOne, album.IsVirtualAlbum))
                {
                    BindSpecificAlbumToTreeview(album);
                }
            }

            return(_tv);
        }
        /// <summary>
        /// Add the collection of albums to the specified treeview node.
        /// </summary>
        /// <param name="albums">The collection of albums to add the the treeview node.</param>
        /// <param name="parentNode">The treeview node that will receive child nodes representing the specified albums.</param>
        /// <param name="expandNode">Specifies whether the nodes should be expanded.</param>
        private void BindAlbumToTreeview(IEnumerable <IGalleryObject> albums, TreeNode parentNode, bool expandNode)
        {
            foreach (IAlbum album in albums)
            {
                TreeNode node       = new TreeNode();
                string   albumTitle = Utils.RemoveHtmlTags(album.Title);
                node.Text     = albumTitle;
                node.ToolTip  = albumTitle;
                node.Id       = String.Concat("tv_", album.Id.ToString(CultureInfo.InvariantCulture));
                node.DataId   = album.Id.ToString(CultureInfo.InvariantCulture);
                node.Expanded = expandNode;

                if (!String.IsNullOrEmpty(_tvOptions.NavigateUrl))
                {
                    node.NavigateUrl = Utils.AddQueryStringParameter(_tvOptions.NavigateUrl, String.Concat("aid=", album.Id.ToString(CultureInfo.InvariantCulture)));
                }

                if (_tvOptions.EnableCheckboxPlugin && !parentNode.ShowCheckBox)
                {
                    node.ShowCheckBox = !album.IsVirtualAlbum && Utils.IsUserAuthorized(_tvOptions.RequiredSecurityPermissions, RoleController.GetGalleryServerRolesForUser(), album.Id, album.GalleryId, album.IsPrivate, SecurityActionsOption.RequireOne, album.IsVirtualAlbum);
                    node.Selectable   = node.ShowCheckBox;
                }
                else
                {
                    node.Selectable = true;
                }

                if (album.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).Any())
                {
                    node.HasChildren = true;
                }

                // Select and check this node if needed.
                if (_tvOptions.SelectedAlbumIds.Contains(album.Id))
                {
                    node.Expanded = true;
                    node.Selected = true;
                    // Expand the child of the selected album.
                    BindAlbumToTreeview(album.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).ToSortedList(), node, false);
                }

                parentNode.Nodes.Add(node);
            }
        }