/// <summary> Constructor creates a new instance of the Aggregation_HtmlSubwriter class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object to display </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
        /// <param name="Paged_Results"> Paged results to display within a browse or search result </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="All_Items_Lookup"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the home page are organized </param>
        /// <param name="Current_User"> Currently logged on user (or object representing the unlogged on user's preferences) </param>
        /// <param name="Static_Web_Content"> HTML content-based browse, info, or imple CMS-style web content objects.  These are objects which are read from a static HTML file and much of the head information must be maintained </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public Aggregation_HtmlSubwriter(Item_Aggregation Current_Aggregation, 
            SobekCM_Navigation_Object Current_Mode, SobekCM_Skin_Object HTML_Skin, 
            Language_Support_Info Translator, 
            Item_Aggregation_Child_Page Browse_Object,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Aggregation_Code_Manager Code_Manager, Item_Lookup_Object All_Items_Lookup,
            List<Thematic_Heading> Thematic_Headings, User_Object Current_User,
            HTML_Based_Content Static_Web_Content,
            Custom_Tracer Tracer )
        {
            currentUser = Current_User;
            base.Current_Aggregation = Current_Aggregation;
            currentMode = Current_Mode;
            Skin = HTML_Skin;
            translator = Translator;
            thisBrowseObject = Browse_Object;
            thisStaticBrowseObject = Static_Web_Content;
            codeManager = Code_Manager;
            itemList = All_Items_Lookup;
            thematicHeadings = Thematic_Headings;
            resultsStatistics = Results_Statistics;
            pagedResults = Paged_Results;
            leftButtons = String.Empty;
            rightButtons = String.Empty;

            // Check to see if the user should be able to edit the home page
            if ((currentMode.Mode == Display_Mode_Enum.Aggregation) && (currentMode.Aggregation_Type == Aggregation_Type_Enum.Home_Edit))
            {
                if ( currentUser == null )
                    currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                else
                {
                    if ((!currentUser.Is_System_Admin) && (!currentUser.Is_Portal_Admin) && (!currentUser.Is_Aggregation_Admin(Current_Aggregation.Code)))
                    {
                        currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                    }
                }
            }
            else if ( currentMode.Aggregation_Type == Aggregation_Type_Enum.Home_Edit )
                currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;

            NameValueCollection form = HttpContext.Current.Request.Form;
            if ( form["item_action"] != null)
            {
                string action = form["item_action"].ToLower().Trim();

                if ((action == "add_aggregation") && ( currentUser != null ))
                {
                    SobekCM_Database.User_Set_Aggregation_Home_Page_Flag(currentUser.UserID, base.Current_Aggregation.Aggregation_ID, true, Tracer);
                    currentUser.Set_Aggregation_Home_Page_Flag(base.Current_Aggregation.Code, base.Current_Aggregation.Name, true);
                    HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "Added aggregation to your home page");
                }

                if (( action == "remove_aggregation") && ( currentUser != null ))
                {
                    int removeAggregationID = base.Current_Aggregation.Aggregation_ID;
                    string remove_code = base.Current_Aggregation.Code;
                    string remove_name = base.Current_Aggregation.Name;

                    if ((form["aggregation"] != null) && (form["aggregation"].Length > 0))
                    {
                        Item_Aggregation_Related_Aggregations aggrInfo = codeManager[form["aggregation"]];
                        if (aggrInfo != null)
                        {
                            remove_code = aggrInfo.Code;
                            removeAggregationID = aggrInfo.ID;
                        }
                    }

                    SobekCM_Database.User_Set_Aggregation_Home_Page_Flag(currentUser.UserID, removeAggregationID, false, Tracer);
                    currentUser.Set_Aggregation_Home_Page_Flag(remove_code, remove_name, false);

                    if (currentMode.Home_Type != Home_Type_Enum.Personalized)
                    {
                        HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", "Removed aggregation from your home page");
                    }
                }

                if ((action == "private_folder") && ( currentUser != null ))
                {
                    User_Folder thisFolder = currentUser.Get_Folder(form["aggregation"]);
                    if (SobekCM_Database.Edit_User_Folder(thisFolder.Folder_ID, currentUser.UserID, -1, thisFolder.Folder_Name, false, String.Empty, Tracer) >= 0)
                        thisFolder.isPublic = false;
                }

                if ((action == "email") && ( currentUser != null ))
                {
                    string address = form["email_address"].Replace(";", ",").Trim();
                    string comments = form["email_comments"].Trim();
                    string format = form["email_format"].Trim().ToUpper();

                    if (address.Length > 0)
                    {
                        // Determine the email format
                        bool is_html_format = format != "TEXT";

                        // CC: the user, unless they are already on the list
                        string cc_list = currentUser.Email;
                        if (address.ToUpper().IndexOf(currentUser.Email.ToUpper()) >= 0)
                            cc_list = String.Empty;

                        // Send the email
                        string any_error = URL_Email_Helper.Send_Email(address, cc_list, comments, currentUser.Full_Name, currentMode.SobekCM_Instance_Abbreviation, is_html_format, HttpContext.Current.Items["Original_URL"].ToString(), base.Current_Aggregation.Name, "Collection", currentUser.UserID);
                        HttpContext.Current.Session.Add("ON_LOAD_MESSAGE", any_error.Length > 0 ? any_error : "Your email has been sent");

                        currentMode.isPostBack = true;

                        // Do this to force a return trip (cirumnavigate cacheing)
                        string original_url = HttpContext.Current.Items["Original_URL"].ToString();
                        if (original_url.IndexOf("?") < 0)
                            HttpContext.Current.Response.Redirect(original_url + "?p=" + DateTime.Now.Millisecond, false);
                        else
                            HttpContext.Current.Response.Redirect(original_url + "&p=" + DateTime.Now.Millisecond, false);

                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        Current_Mode.Request_Completed = true;
                        return;
                    }
                }
            }

            if (( currentMode.Aggregation_Type == Aggregation_Type_Enum.Home_Edit ) && ( form["sbkAghsw_HomeTextEdit"] != null))
            {
                string aggregation_folder = SobekCM_Library_Settings.Base_Design_Location + "aggregations\\" + Current_Aggregation.Code + "\\";
                string file = aggregation_folder + Current_Aggregation.Home_Page_File(currentMode.Language);

                // Make a backup from today, if none made yet
                if (File.Exists(file))
                {
                    DateTime lastWrite = (new FileInfo(file)).LastWriteTime;
                    string new_file = file.ToLower().Replace(".txt", "").Replace(".html", "").Replace(".htm", "") + lastWrite.Year + lastWrite.Month.ToString().PadLeft(2, '0') + lastWrite.Day.ToString() .PadLeft(2, '0')+ ".bak";
                    if (File.Exists(new_file))
                        File.Delete(new_file);
                    File.Move(file, new_file);
                }

                // Write to the file now
                StreamWriter homeWriter = new StreamWriter(file, false);
                homeWriter.WriteLine(form["sbkAghsw_HomeTextEdit"]);
                homeWriter.Flush();
                homeWriter.Close();

                // Also save this change
                SobekCM_Database.Save_Item_Aggregation_Milestone(Current_Aggregation.Code, "Home page edited (" + Web_Language_Enum_Converter.Enum_To_Name(currentMode.Language) + ")", currentUser.Full_Name);

                // Clear this aggreation from the cache
                Cached_Data_Manager.Remove_Item_Aggregation(Current_Aggregation.Code, Tracer);

                // If this is all, save the new text as well.
                if (String.Compare("all", Current_Aggregation.Code, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    HttpContext.Current.Application["SobekCM_Home"] = form["sbkAghsw_HomeTextEdit"];
                }

                // Forward along
                currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                string redirect_url = currentMode.Redirect_URL();
                if (redirect_url.IndexOf("?") > 0)
                    redirect_url = redirect_url + "&refresh=always";
                else
                    redirect_url = redirect_url + "?refresh=always";
                currentMode.Request_Completed = true;
                HttpContext.Current.Response.Redirect(redirect_url, false);
                HttpContext.Current.ApplicationInstance.CompleteRequest();

                return;
            }

            // If this is a search, verify it is a valid search type
            if (currentMode.Mode == Display_Mode_Enum.Search)
            {
                // Not every collection has every search type...
                ReadOnlyCollection<Search_Type_Enum> possibleSearches = base.Current_Aggregation.Search_Types;
                if (!possibleSearches.Contains(currentMode.Search_Type))
                {
                    bool found_valid = false;

                    if ((currentMode.Search_Type == Search_Type_Enum.Full_Text) && (possibleSearches.Contains(Search_Type_Enum.dLOC_Full_Text)))
                    {
                        found_valid = true;
                        currentMode.Search_Type = Search_Type_Enum.dLOC_Full_Text;
                    }

                    if ((!found_valid) && (currentMode.Search_Type == Search_Type_Enum.Basic) && (possibleSearches.Contains(Search_Type_Enum.Newspaper)))
                    {
                        found_valid = true;
                        currentMode.Search_Type = Search_Type_Enum.Newspaper;
                    }

                    if (( !found_valid ) && ( possibleSearches.Count > 0 ))
                    {
                        found_valid = true;
                        currentMode.Search_Type = possibleSearches[0];
                    }

                    if ( !found_valid )
                    {
                        currentMode.Mode = Display_Mode_Enum.Aggregation;
                        currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                    }
                }
            }

            if (currentMode.Mode == Display_Mode_Enum.Search)
            {
                collectionViewer = AggregationViewer_Factory.Get_Viewer(currentMode.Search_Type, base.Current_Aggregation, currentMode, currentUser);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation)
            {
                switch (currentMode.Aggregation_Type)
                {
                    case Aggregation_Type_Enum.Home:
                    case Aggregation_Type_Enum.Home_Edit:
                        collectionViewer = AggregationViewer_Factory.Get_Viewer(base.Current_Aggregation.Views_And_Searches[0], base.Current_Aggregation, currentMode);
                        break;

                    case Aggregation_Type_Enum.Browse_Info:
                        if (resultsStatistics == null)
                        {
                            collectionViewer = new Static_Browse_Info_AggregationViewer(thisBrowseObject, thisStaticBrowseObject, Current_Aggregation, currentMode, Current_User);
                        }
                        else
                        {
                            collectionViewer = new DataSet_Browse_Info_AggregationViewer(thisBrowseObject, resultsStatistics, pagedResults, codeManager, itemList, currentUser);
                        }
                        break;

                    case Aggregation_Type_Enum.Child_Page_Edit:
                        collectionViewer = new Static_Browse_Info_AggregationViewer(thisBrowseObject, thisStaticBrowseObject, Current_Aggregation, currentMode, Current_User);
                        break;

                    case Aggregation_Type_Enum.Browse_By:
                        collectionViewer = new Metadata_Browse_AggregationViewer(Current_Mode, Current_Aggregation, Tracer);
                        break;

                    case Aggregation_Type_Enum.Browse_Map:
                        collectionViewer = new Map_Browse_AggregationViewer(Current_Mode, Current_Aggregation, Tracer);
                        break;

                    case Aggregation_Type_Enum.Browse_Map_Beta:
                        collectionViewer = new Map_Browse_AggregationViewer_Beta(Current_Mode, Current_Aggregation, Tracer);
                        break;

                    case Aggregation_Type_Enum.Item_Count:
                        collectionViewer = new Item_Count_AggregationViewer(Current_Mode, Current_Aggregation);
                        break;

                    case Aggregation_Type_Enum.Usage_Statistics:
                        collectionViewer = new Usage_Statistics_AggregationViewer(Current_Mode, Current_Aggregation);
                        break;

                    case Aggregation_Type_Enum.Private_Items:
                        collectionViewer = new Private_Items_AggregationViewer(Current_Mode, Current_Aggregation, Tracer);
                        break;
                }
            }

            // If execution should end, do it now
            if (currentMode.Request_Completed)
                return;

            if (collectionViewer != null)
            {
                collectionViewer.Translator = translator;
                collectionViewer.HTML_Skin = HTML_Skin;
                collectionViewer.CurrentMode = Current_Mode;
                collectionViewer.CurrentObject = Current_Aggregation;
                collectionViewer.Current_User = Current_User;

                // Pull the standard values
                switch (collectionViewer.Selection_Panel_Display)
                {
                    case Selection_Panel_Display_Enum.Selectable:
                        if (form["show_subaggrs"] != null)
                        {
                            string show_subaggrs = form["show_subaggrs"].ToUpper();
                            if (show_subaggrs == "TRUE")
                                currentMode.Show_Selection_Panel = true;
                        }
                        break;

                    case Selection_Panel_Display_Enum.Always:
                        currentMode.Show_Selection_Panel = true;
                        break;
                }
            }
        }
        /// <summary> Constructor for a new instance of the Static_Browse_Info_AggregationViewer class </summary>
        /// <param name="Browse_Object"> Browse or information object to be displayed </param>
        /// <param name="Static_Web_Content"> HTML content-based browse, info, or imple CMS-style web content objects.  These are objects which are read from a static HTML file and much of the head information must be maintained </param>
        /// <param name="Current_Collection"> Current collection being displayed</param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_User"> Current user/session information </param>
        public Static_Browse_Info_AggregationViewer(Item_Aggregation_Child_Page Browse_Object, HTML_Based_Content Static_Web_Content, Item_Aggregation Current_Collection, SobekCM_Navigation_Object Current_Mode, User_Object Current_User )
            : base(Current_Collection, Current_Mode)
        {
            browseObject = Browse_Object;
            staticWebContent = Static_Web_Content;
            currentUser = Current_User;

            bool isAdmin = (currentUser != null) && (currentUser.Is_Aggregation_Admin(currentCollection.Code));
            if (( currentMode.Aggregation_Type == Aggregation_Type_Enum.Child_Page_Edit) && ( !isAdmin))
                currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;

            NameValueCollection form = HttpContext.Current.Request.Form;
            if ((currentMode.Aggregation_Type == Aggregation_Type_Enum.Child_Page_Edit) && (form["sbkSbia_ChildTextEdit"] != null) && ( currentUser != null ))
            {
                string aggregation_folder = SobekCM_Library_Settings.Base_Design_Location + "aggregations\\" + currentCollection.Code + "\\";
                string file = aggregation_folder + browseObject.Get_Static_HTML_Source(currentMode.Language);

                // Get the header information as well
                if ( !String.IsNullOrEmpty(form["admin_childpage_title"]))
                {
                    staticWebContent.Title = form["admin_childpage_title"];
                }
                if (form["admin_childpage_author"] != null)
                    staticWebContent.Author = form["admin_childpage_author"];
                if (form["admin_childpage_date"] != null)
                    staticWebContent.Date = form["admin_childpage_date"];
                if (form["admin_childpage_description"] != null)
                    staticWebContent.Description = form["admin_childpage_description"];
                if (form["admin_childpage_keywords"] != null)
                    staticWebContent.Keywords = form["admin_childpage_keywords"];
                if (form["admin_childpage_extrahead"] != null)
                    staticWebContent.Extra_Head_Info = form["admin_childpage_extrahead"];

                // Make a backup from today, if none made yet
                if (File.Exists(file))
                {
                    DateTime lastWrite = (new FileInfo(file)).LastWriteTime;
                    string new_file = file.ToLower().Replace(".txt", "").Replace(".html", "").Replace(".htm", "") + lastWrite.Year + lastWrite.Month.ToString().PadLeft(2, '0') + lastWrite.Day.ToString() .PadLeft(2, '0')+ ".bak";
                    if (File.Exists(new_file))
                        File.Delete(new_file);
                    File.Move(file, new_file);
                }

                // Assign the new text
                Static_Web_Content.Static_Text = form["sbkSbia_ChildTextEdit"];
                Static_Web_Content.Date = DateTime.Now.ToLongDateString();
                Static_Web_Content.Save_To_File(file);

                // Also save this change
                SobekCM_Database.Save_Item_Aggregation_Milestone(currentCollection.Code, "Child page '" + browseObject.Code + "' edited (" + Web_Language_Enum_Converter.Enum_To_Name(currentMode.Language) + ")", currentUser.Full_Name);

                // Forward along
                currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;
                if ( Browse_Object.Browse_Type == Item_Aggregation_Child_Page.Visibility_Type.METADATA_BROWSE_BY )
                    currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_By;

                string redirect_url = currentMode.Redirect_URL();
                if (redirect_url.IndexOf("?") > 0)
                    redirect_url = redirect_url + "&refresh=always";
                else
                    redirect_url = redirect_url + "?refresh=always";
                currentMode.Request_Completed = true;
                HttpContext.Current.Response.Redirect(redirect_url, false);
                HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
        }
        /// <summary> Add the aggregation-level main menu </summary>
        /// <param name="Output"> Stream to which to write the HTML for this menu </param>
        /// <param name="Mode"> Mode / navigation information for the current request</param>
        /// <param name="User"> Currently logged on user (or object representing the unlogged on user's preferences) </param>
        /// <param name="Current_Aggregation"> Aggregation object which may have additional aggregation-level child pages to display in the main menu  </param>
        /// <param name="Translations"> Language support object for writing the name of the view in the appropriate interface language </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        public static void Add_Aggregation_Main_Menu(TextWriter Output, SobekCM_Navigation_Object Mode, User_Object User, Item_Aggregation Current_Aggregation, Language_Support_Info Translations, Aggregation_Code_Manager Code_Manager )
        {
            Output.WriteLine("<!-- Add the main aggregation menu -->");
            Output.WriteLine("<nav id=\"sbkAgm_MenuBar\" class=\"sbkMenu_Bar\">");
            Output.WriteLine("  <ul class=\"sf-menu\" id=\"sbkAgm_Menu\">");

            // Get ready to draw the tabs
            string home = "Home";
            string collection_home = Translations.Get_Translation(Current_Aggregation.ShortName, Mode.Language ) + " Home";
            string sobek_home_text = Mode.SobekCM_Instance_Abbreviation + " Home";
            string viewItems = "View Items";
            string allItems = "View All Items";
            string newItems = "View Recently Added Items";
            string myCollections = "MY COLLECTIONS";
            string partners = "BROWSE PARTNERS";
            string browseBy = "BROWSE BY";
            const string BROWSE_MAP = "MAP BROWSE";
            const string list_view_text = "List View";
            const string brief_view_text = "Brief View";
            const string tree_view_text = "Tree View";
            const string partners_text = "Browse Partners";

            if (Mode.Language == Web_Language_Enum.Spanish)
            {
                home = "INICIO";
                collection_home = "INICIO " + Translations.Get_Translation(Current_Aggregation.ShortName, Mode.Language);
                sobek_home_text = "INICIO " + Mode.SobekCM_Instance_Abbreviation.ToUpper();
                allItems = "TODOS LOS ARTÍCULOS";
                newItems = "NUEVOS ARTÍCULOS";
                browseBy = "BÚSQUEDA POR";
                partners = "AFILIADOS";
                myCollections = "MIS COLECCIONES";
                viewItems = "VER ARTÍCULOS";
            }

            if (Mode.Language == Web_Language_Enum.French)
            {
                home = "PAGE D'ACCUEIL";
                sobek_home_text = "PAGE D'ACCUEIL";
                allItems = "TOUS LES ARTICLES";
                newItems = "NOUVEAUX ARTICLES";
                browseBy = "PARCOURIR PAR";
                viewItems = "VOIR ARTICLES";
            }

            // Save the current mode and browse
            Display_Mode_Enum thisMode = Mode.Mode;
            Aggregation_Type_Enum thisAggrType = Mode.Aggregation_Type;
            Search_Type_Enum thisSearch = Mode.Search_Type;
            Home_Type_Enum thisHomeType = Mode.Home_Type;
            Result_Display_Type_Enum resultsType = Mode.Result_Display_Type;
            ushort page = Mode.Page;
            string browse_code = Mode.Info_Browse_Mode;
            string aggregation = Mode.Aggregation;
            if ((thisMode == Display_Mode_Enum.Aggregation) && ((thisAggrType == Aggregation_Type_Enum.Browse_Info) || (thisAggrType == Aggregation_Type_Enum.Child_Page_Edit)))
            {
                browse_code = Mode.Info_Browse_Mode;
            }

            // Get the home search type (just to do a matching in case it was explicitly requested)
            Item_Aggregation.CollectionViewsAndSearchesEnum homeView = Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search;
            if (Current_Aggregation.Views_And_Searches.Count > 0)
            {
                homeView = Current_Aggregation.Views_And_Searches[0];
            }

            // Remove any search string
            string current_search = Mode.Search_String;
            Mode.Search_String = String.Empty;

            // Add any PRE-MENU instance options
            bool pre_menu_options_exist = false;
            string first_pre_menu_option = String.Empty;
            string second_pre_menu_option = String.Empty;
            if (SobekCM_Library_Settings.Additional_Settings.ContainsKey("Aggregation Viewer.Static First Menu Item"))
                first_pre_menu_option = SobekCM_Library_Settings.Additional_Settings["Aggregation Viewer.Static First Menu Item"];
            if (SobekCM_Library_Settings.Additional_Settings.ContainsKey("Aggregation Viewer.Static Second Menu Item"))
                second_pre_menu_option = SobekCM_Library_Settings.Additional_Settings["Aggregation Viewer.Static Second Menu Item"];
            if ((first_pre_menu_option.Length > 0) || (second_pre_menu_option.Length > 0))
            {
                pre_menu_options_exist = true;
                if (first_pre_menu_option.Length > 0)
                {
                    string[] first_splitter = first_pre_menu_option.Replace("[", "").Replace("]", "").Split(";".ToCharArray());
                    if (first_splitter.Length > 0)
                    {
                        Output.WriteLine("    <li><a href=\"" + first_splitter[1] + "\" title=\"" + System.Web.HttpUtility.HtmlEncode(first_splitter[0]) + "\">" + System.Web.HttpUtility.HtmlEncode(first_splitter[0]) + "</a></li>");
                    }
                }
                if (second_pre_menu_option.Length > 0)
                {
                    string[] second_splitter = second_pre_menu_option.Replace("[", "").Replace("]", "").Split(";".ToCharArray());
                    if (second_splitter.Length > 0)
                    {
                        Output.WriteLine("    <li><a href=\"" + second_splitter[1] + "\" title=\"" + System.Web.HttpUtility.HtmlEncode(second_splitter[0]) + "\">" + System.Web.HttpUtility.HtmlEncode(second_splitter[0]) + "</a></li>");
                    }
                }
            }

            bool isOnHome = (((Mode.Mode == Display_Mode_Enum.Aggregation) && (Mode.Aggregation_Type == Aggregation_Type_Enum.Home)) ||
                 ((Mode.Mode == Display_Mode_Enum.Search) &&
                  (Aggregation_Nav_Bar_HTML_Factory.Do_Search_Types_Match(homeView, Mode.Search_Type))));

            // Add the HOME tab
            if ((Current_Aggregation.Code == "all") || ( Current_Aggregation.Code == Mode.Default_Aggregation))
            {
                // Add the 'SOBEK HOME' first menu option and suboptions
                Mode.Mode = Display_Mode_Enum.Aggregation;
                Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                Mode.Home_Type = Home_Type_Enum.List;

                if (Current_Aggregation.Code == "all")
                {
                    // What is considered HOME changes here at the top level
                    if ((thisHomeType == Home_Type_Enum.Partners_List) || (thisHomeType == Home_Type_Enum.Partners_Thumbnails) || (thisHomeType == Home_Type_Enum.Personalized))
                        isOnHome = false;

                    // If some instance-wide pre-menu items existed, don't use the home image
                    if (pre_menu_options_exist)
                    {
                        if (isOnHome)
                            Output.WriteLine("    <li class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + sobek_home_text + "</a><ul id=\"sbkAgm_HomeSubMenu\">");
                        else
                            Output.WriteLine("    <li><a href=\"" + Mode.Redirect_URL() + "\">" + sobek_home_text + "</a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }
                    else
                    {
                        if ( isOnHome )
                            Output.WriteLine("    <li id=\"sbkAgm_Home\" class=\"sbkMenu_Home selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\" class=\"sbkMenu_NoPadding\"><img src=\"" + Mode.Default_Images_URL + "home.png\" /> <div class=\"sbkMenu_HomeText\">" + sobek_home_text + "</div></a><ul id=\"sbkAgm_HomeSubMenu\">");
                        else
                            Output.WriteLine("    <li id=\"sbkAgm_Home\" class=\"sbkMenu_Home\"><a href=\"" + Mode.Redirect_URL() + "\" class=\"sbkMenu_NoPadding\"><img src=\"" + Mode.Default_Images_URL + "home.png\" /> <div class=\"sbkMenu_HomeText\">" + sobek_home_text + "</div></a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }

                    Output.WriteLine("      <li id=\"sbkAgm_HomeListView\"><a href=\"" + Mode.Redirect_URL() + "\">" + list_view_text + "</a></li>");
                    Mode.Home_Type = Home_Type_Enum.Descriptions;
                    Output.WriteLine("      <li id=\"sbkAgm_HomeBriefView\"><a href=\"" + Mode.Redirect_URL() + "\">" + brief_view_text + "</a></li>");
                    if (SobekCM_Library_Settings.Include_TreeView_On_System_Home)
                    {
                        Mode.Home_Type = Home_Type_Enum.Tree_Collapsed;
                        Output.WriteLine("      <li id=\"sbkAgm_HomeTreeView\"><a href=\"" + Mode.Redirect_URL() + "\">" + tree_view_text + "</a></li>");
                    }
                    Output.WriteLine("    </ul></li>");
                }
                else
                {
                    Output.WriteLine("    <li id=\"sbkAgm_Home\"><a href=\"" + Mode.Redirect_URL() + "\" class=\"sbkAgm_NoPadding\"><img src=\"" + Mode.Default_Images_URL + "home.png\" /> <div class=\"sbkAgm_HomeText\">" + sobek_home_text + "</div></a></li>");
                }
            }
            else
            {

                // Add the 'SOBEK HOME' first menu option and suboptions
                Mode.Mode = Display_Mode_Enum.Aggregation;
                Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                Mode.Home_Type = Home_Type_Enum.List;

                // If some instance-wide pre-menu items existed, don't use the home image
                if (pre_menu_options_exist)
                {
                    if (isOnHome)
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Home\" class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + home + "</a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Home\"><a href=\"" + Mode.Redirect_URL() + "\">" + home + "</a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }
                }
                else
                {
                    if (isOnHome)
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Home\" class=\"selected-sf-menu-item-link sbkMenu_Home\"><a href=\"" + Mode.Redirect_URL() + "\" class=\"sbkMenu_NoPadding\"><img src=\"" + Mode.Default_Images_URL + "home.png\" /> <div class=\"sbkMenu_HomeText\">" + home + "</div></a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Home\" class=\"sbkMenu_Home\"><a href=\"" + Mode.Redirect_URL() + "\" class=\"sbkMenu_NoPadding\"><img src=\"" + Mode.Default_Images_URL + "home.png\" /> <div class=\"sbkMenu_HomeText\">" + home + "</div></a><ul id=\"sbkAgm_HomeSubMenu\">");
                    }
                }

                Output.WriteLine("      <li id=\"sbkAgm_AggrHome\"><a href=\"" + Mode.Redirect_URL() + "\">" + collection_home + "</a></li>");

                Mode.Aggregation = String.Empty;
                if (Mode.Default_Aggregation != "all")
                {
                    Output.WriteLine("      <li id=\"sbkAgm_InstanceHome\"><a href=\"" + Mode.Redirect_URL() + "\">" + sobek_home_text + "</a></li>");
                }
                else
                {
                    Output.WriteLine("      <li id=\"sbkAgm_InstanceHome\"><a href=\"" + Mode.Redirect_URL() + "\">" + sobek_home_text + "</a><ul id=\"sbkAgm_InstanceHomeSubMenu\">");
                    Output.WriteLine("        <li id=\"sbkAgm_HomeListView\"><a href=\"" + Mode.Redirect_URL() + "\">" + list_view_text + "</a></li>");
                    Mode.Home_Type = Home_Type_Enum.Descriptions;
                    Output.WriteLine("        <li id=\"sbkAgm_HomeBriefView\"><a href=\"" + Mode.Redirect_URL() + "\">" + brief_view_text + "</a></li>");
                    if (SobekCM_Library_Settings.Include_TreeView_On_System_Home)
                    {
                        Mode.Home_Type = Home_Type_Enum.Tree_Collapsed;
                        Output.WriteLine("        <li id=\"sbkAgm_HomeTreeView\"><a href=\"" + Mode.Redirect_URL() + "\">" + tree_view_text + "</a></li>");
                    }
                    if ((User != null) && (User.LoggedOn))
                    {
                        Mode.Home_Type = Home_Type_Enum.Personalized;
                        Output.WriteLine("        <li id=\"sbkAgm_HomePersonalized\"><a href=\"" + Mode.Redirect_URL() + "\">" + myCollections + "</a></li>");
                    }
                    if (SobekCM_Library_Settings.Include_Partners_On_System_Home)
                    {
                        Mode.Home_Type = Home_Type_Enum.Partners_List;
                        Output.WriteLine("        <li id=\"sbkAgm_HomePartners\"><a href=\"" + Mode.Redirect_URL() + "\">" + partners_text + "</a></li>");
                    }
                    Output.WriteLine("      </ul></li>");
                }

                Output.WriteLine("    </ul></li>");

                Mode.Aggregation = Current_Aggregation.Code;
            }

            // Add any additional search types
            Mode.Mode = thisMode;
            for (int i = 1; i < Current_Aggregation.Views_And_Searches.Count; i++)
            {
                Output.Write("    " + Aggregation_Nav_Bar_HTML_Factory.Menu_Get_Nav_Bar_HTML(Current_Aggregation.Views_And_Searches[i], Mode, Translations));
            }

            // Replace any search string
            Mode.Search_String = current_search;

            // Check for the existence of any BROWSE BY pages
            if (Current_Aggregation.Has_Browse_By_Pages)
            {
                Mode.Mode = Display_Mode_Enum.Aggregation;
                Mode.Aggregation_Type = Aggregation_Type_Enum.Browse_By;
                Mode.Info_Browse_Mode = String.Empty;

                // Get sorted collection of (public) browse bys linked to this aggregation
                ReadOnlyCollection<Item_Aggregation_Child_Page> public_browses = Current_Aggregation.Browse_By_Pages(Mode.Language);
                if (public_browses.Count > 0)
                {
                    if (((thisMode == Display_Mode_Enum.Aggregation) && (thisAggrType == Aggregation_Type_Enum.Browse_By)) || (Mode.Is_Robot))
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_BrowseBy\" class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + browseBy + "</a><ul id=\"sbkAgm_BrowseBySubMenu\">");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_BrowseBy\"><a href=\"" + Mode.Redirect_URL() + "\">" + browseBy + "</a><ul id=\"sbkAgm_BrowseBySubMenu\">");
                    }

                    foreach (Item_Aggregation_Child_Page thisBrowse in public_browses)
                    {
                        // Static HTML or metadata browse by?
                        if (thisBrowse.Source == Item_Aggregation_Child_Page.Source_Type.Static_HTML)
                        {
                            Mode.Info_Browse_Mode = thisBrowse.Code;
                            Output.WriteLine("      <li><a href=\"" + Mode.Redirect_URL().Replace("&", "&amp") + "\">" + thisBrowse.Get_Label(Mode.Language) + "</a></li>");
                        }
                        else
                        {
                            Metadata_Search_Field facetField = SobekCM_Library_Settings.Metadata_Search_Field_By_Display_Name(thisBrowse.Code);
                            if (facetField != null)
                            {
                                Mode.Info_Browse_Mode = thisBrowse.Code.ToLower().Replace(" ", "_");
                                Output.WriteLine("      <li><a href=\"" + Mode.Redirect_URL().Replace("&", "&amp") + "\">" + facetField.Display_Term + "</a></li>");
                            }
                        }
                    }

                    Output.WriteLine("    </ul></li>");
                }
            }

            // Check for the existence of any MAP BROWSE pages
            if (Current_Aggregation.Views_And_Searches.Contains(Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Browse))
            {
                Mode.Mode = Display_Mode_Enum.Aggregation;
                Mode.Aggregation_Type = Aggregation_Type_Enum.Browse_Map;
                Mode.Info_Browse_Mode = String.Empty;

                if ((thisMode == Display_Mode_Enum.Aggregation) && (thisAggrType == Aggregation_Type_Enum.Browse_Map))
                {
                    Output.WriteLine("    <li id=\"sbkAgm_MapBrowse\" class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + BROWSE_MAP + "</a></li>");
                }
                else
                {
                    Output.WriteLine("    <li id=\"sbkAgm_MapBrowse\"><a href=\"" + Mode.Redirect_URL() + "\">" + BROWSE_MAP + "</a></li>");
                }
            }

            // Add all the browses and child pages
            Mode.Mode = Display_Mode_Enum.Aggregation;
            Mode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;

            // Find the URL for all these browses
            Mode.Info_Browse_Mode = "XYXYXYXYXY";
            string redirect_url = Mode.Redirect_URL();
            Mode.Page = 1;

            // Only show ALL and NEW if they are in the collection list of searches and views
            int included_browses = 0;
            if (Current_Aggregation.Views_And_Searches.Contains(Item_Aggregation.CollectionViewsAndSearchesEnum.All_New_Items))
            {
                // First, look for 'ALL'
                if (Current_Aggregation.Contains_Browse_Info("all"))
                {
                    bool includeNew = ((Current_Aggregation.Contains_Browse_Info("new")) && (!Mode.Is_Robot));
                    if (includeNew)
                    {
                        if ((browse_code == "all") || (browse_code == "new" ))
                        {
                            Output.WriteLine("    <li id=\"sbkAgm_ViewItems\" class=\"selected-sf-menu-item-link\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "all").Replace("/info/", "/") + "\">" + viewItems + "</a><ul id=\"sbkAgm_ViewItemsSubMenu\">");
                        }
                        else
                        {
                            Output.WriteLine("    <li id=\"sbkAgm_ViewItems\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "all").Replace("/info/", "/") + "\">" + viewItems + "</a><ul id=\"sbkAgm_ViewItemsSubMenu\">");
                        }

                        Output.WriteLine("    <li id=\"sbkAgm_AllBrowse\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "all").Replace("/info/", "/") + "\">" + allItems + "</a></li>");
                        Output.WriteLine("    <li id=\"sbkAgm_NewBrowse\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "new").Replace("/info/", "/") + "\">" + newItems + "</a></li>");

                        Output.WriteLine("    </ul></li>");
                    }
                    else
                    {
                        if (browse_code == "all")
                        {
                            Output.WriteLine("    <li id=\"sbkAgm_ViewItems\" class=\"selected-sf-menu-item-link\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "all").Replace("/info/", "/") + "\">" + viewItems + "</a></li>");
                        }
                        else
                        {
                            Output.WriteLine("    <li id=\"sbkAgm_ViewItems\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", "all").Replace("/info/", "/") + "\">" + viewItems + "</a></li>");
                        }
                    }

                    included_browses++;
                }
            }

            Mode.Result_Display_Type = Result_Display_Type_Enum.NONE;
            redirect_url = Mode.Redirect_URL();

            // Are there any additional browses to include?
            ReadOnlyCollection<Item_Aggregation_Child_Page> otherBrowses = Current_Aggregation.Browse_Home_Pages(Mode.Language);
            if (otherBrowses.Count > included_browses)
            {
                // Now, step through the sorted list
                foreach (Item_Aggregation_Child_Page thisBrowseObj in otherBrowses.Where(thisBrowseObj => (thisBrowseObj.Code != "all") && (thisBrowseObj.Code != "new")))
                {
                    Mode.Info_Browse_Mode = thisBrowseObj.Code;
                    if (browse_code == thisBrowseObj.Code)
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_NewBrowse\" class=\"selected-sf-menu-item-link\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", thisBrowseObj.Code) + "\">" + thisBrowseObj.Get_Label(Mode.Language) + "</a></li>");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_NewBrowse\"><a href=\"" + redirect_url.Replace("XYXYXYXYXY", thisBrowseObj.Code) + "\">" + thisBrowseObj.Get_Label(Mode.Language) + "</a></li>");
                    }
                }
            }

            // If this is NOT the all collection, then show subcollections
            if ((Current_Aggregation.Code != "all") && (Current_Aggregation.Children_Count > 0))
            {
                // Verify some of the children are active and not hidden
                // Keep the last aggregation alias
                string lastAlias = Mode.Aggregation_Alias;
                Mode.Aggregation_Alias = String.Empty;
                Mode.Info_Browse_Mode = String.Empty;

                // Collect the html to write (this alphabetizes the children)
                List<string> html_list = new List<string>();
                foreach (Item_Aggregation_Related_Aggregations childAggr in Current_Aggregation.Children)
                {
                    Item_Aggregation_Related_Aggregations latest = Code_Manager[childAggr.Code];
                    if ((latest != null) && (!latest.Hidden) && (latest.Active))
                    {
                        string name = childAggr.ShortName;
                        if (name.ToUpper() == "ADDED AUTOMATICALLY")
                            name = childAggr.Code + " ( Added Automatically )";

                        Mode.Aggregation = childAggr.Code.ToLower();
                        html_list.Add("      <li><a href=\"" + Mode.Redirect_URL() + "\">" + Translations.Get_Translation(name, Mode.Language) + "</a></li>");
                    }
                }

                if (html_list.Count > 0)
                {
                    string childTypes = Current_Aggregation.Child_Types.Trim();
                    Output.WriteLine("    <li id=\"sbkAgm_SubCollections\"><a href=\"#subcolls\">" + Translations.Get_Translation(childTypes, Mode.Language) + "</a><ul id=\"sbkAgm_SubCollectionsMenu\">");
                    foreach (string thisHtml in html_list)
                    {
                        Output.WriteLine(thisHtml);
                    }
                    Output.WriteLine("    </ul></li>");

                    // Restore the old alias
                    Mode.Aggregation_Alias = lastAlias;
                }
            }

            // If there is a user and this is the main home page, show MY COLLECTIONS
            if ((User != null) && ( User.LoggedOn ))
            {
                if (Current_Aggregation.Code == "all")
                {
                    Mode.Mode = Display_Mode_Enum.Aggregation;
                    Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                    Mode.Home_Type = Home_Type_Enum.Personalized;

                    // Show personalized
                    if (thisHomeType == Home_Type_Enum.Personalized)
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_MyCollections\" class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + myCollections + "</a></li>");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_MyCollections\"><a href=\"" + Mode.Redirect_URL() + "\">" + myCollections + "</a></li>");
                    }
                }
                else
                {
                    if (User.Is_Aggregation_Admin(Current_Aggregation.Code))
                    {
                        // Return the code and mode back
                        Mode.Info_Browse_Mode = String.Empty;
                        Mode.Search_Type = thisSearch;
                        Mode.Mode = thisMode;
                        Mode.Home_Type = thisHomeType;

                        Output.Write(Aggregation_Nav_Bar_HTML_Factory.Menu_Get_Nav_Bar_HTML(Item_Aggregation.CollectionViewsAndSearchesEnum.Admin_View, Mode, Translations));
                    }
                }
            }

            // Show institutional lists?
            if (Current_Aggregation.Code == "all")
            {
                // Is this library set to show the partners tab?
                if (SobekCM_Library_Settings.Include_Partners_On_System_Home)
                {
                    Mode.Mode = Display_Mode_Enum.Aggregation;
                    Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                    Mode.Home_Type = Home_Type_Enum.Partners_List;

                    if (((thisHomeType == Home_Type_Enum.Partners_List) || (thisHomeType == Home_Type_Enum.Partners_Thumbnails)))
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Partners\" class=\"selected-sf-menu-item-link\"><a href=\"" + Mode.Redirect_URL() + "\">" + partners + "</a></li>");
                    }
                    else
                    {
                        Output.WriteLine("    <li id=\"sbkAgm_Partners\"><a href=\"" + Mode.Redirect_URL() + "\">" + partners + "</a></li>");
                    }
                }
            }

            // Return the code and mode back
            Mode.Info_Browse_Mode = browse_code;
            Mode.Aggregation_Type = thisAggrType;
            Mode.Search_Type = thisSearch;
            Mode.Mode = thisMode;
            Mode.Home_Type = thisHomeType;
            Mode.Result_Display_Type = resultsType;
            Mode.Aggregation = aggregation;
            Mode.Page = page;

            Output.WriteLine("  </ul>");
            Output.WriteLine("</nav>");
            Output.WriteLine();

            Output.WriteLine("<!-- Initialize the main user menu -->");
            Output.WriteLine("<script>");
            Output.WriteLine("  jQuery(document).ready(function () {");
            Output.WriteLine("     jQuery('ul.sf-menu').superfish({");

            Output.WriteLine("          onBeforeShow: function() { ");
            Output.WriteLine("               if ( $(this).attr('id') == 'sbkAgm_SubCollectionsMenu')");
            Output.WriteLine("               {");
            Output.WriteLine("                 var thisWidth = $(this).width();");
            Output.WriteLine("                 var parent = $('#sbkAgm_SubCollections');");
            Output.WriteLine("                 var offset = $('#sbkAgm_SubCollections').offset();");
            Output.WriteLine("                 if ( $(window).width() < offset.left + thisWidth )");
            Output.WriteLine("                 {");
            Output.WriteLine("                   var newleft = thisWidth - parent.width();");
            Output.WriteLine("                   $(this).css('left', '-' + newleft + 'px');");
            Output.WriteLine("                 }");
            Output.WriteLine("               }");
            Output.WriteLine("          }");

            Output.WriteLine("    });");
            Output.WriteLine("  });");
            Output.WriteLine("</script>");
            Output.WriteLine();
        }