Abstract class which all collection viewer classes extend
This class implements the iAggregationViewer interface.

Collection viewers are used when displaying collection home pages, searches, browses, and information pages.

During a valid html request, the following steps occur:
  • Application state is built/verified by the Application_State.Application_State_Builder
  • Request is analyzed by the Navigation.SobekCM_QueryString_Analyzer and output as a SobekCM_Navigation_Object
  • Main writer is created for rendering the output, in his case the Html_MainWriter
  • The HTML writer will create the necessary subwriter. For a collection-level request, an instance of the Aggregation_HtmlSubwriter class is created.
  • To display the requested collection view, the collection subwriter will create one or more collection viewers ( implementing this class )
Inheritance: iAggregationViewer
        /// <summary> Constructor creates a new instance of the Aggregation_HtmlSubwriter class </summary>
        /// <param name="Hierarchy_Object"> 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 </param>
        /// <param name="IP_Restrictions"> IP restrictions, used to determine if a user has access to a particular item </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 Hierarchy_Object, 
            SobekCM_Navigation_Object Current_Mode, SobekCM_Skin_Object HTML_Skin, 
            Language_Support_Info Translator, 
            Item_Aggregation_Browse_Info 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,
            IP_Restriction_Ranges IP_Restrictions,
            HTML_Based_Content Static_Web_Content,
            Custom_Tracer Tracer )
        {
            currentUser = Current_User;
            base.Hierarchy_Object = Hierarchy_Object;
            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;
            ipRestrictions = IP_Restrictions;
            resultsStatistics = Results_Statistics;
            pagedResults = Paged_Results;

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

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

                if (action == "remove_aggregation")
                {
                    int removeAggregationID = base.Hierarchy_Object.Aggregation_ID;
                    string remove_code = base.Hierarchy_Object.Code;
                    string remove_name = base.Hierarchy_Object.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")
                {
                    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")
                {
                    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 = true;
                        if (format == "TEXT")
                            is_html_format = false;

                        // 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.Hierarchy_Object.Name, "home");
                        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);
                    }
                }
            }

            // 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.Hierarchy_Object.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_Home;
                    }
                }
            }

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

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Home)
            {
                collectionViewer = AggregationViewer_Factory.Get_Viewer(base.Hierarchy_Object.Views_And_Searches[0], base.Hierarchy_Object, currentMode);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Browse_Info)
            {
                if ( resultsStatistics == null )
                {
                    collectionViewer = new Static_Browse_Info_AggregationViewer(thisBrowseObject, thisStaticBrowseObject);
                }
                else
                {
                    collectionViewer = new DataSet_Browse_Info_AggregationViewer(thisBrowseObject, resultsStatistics, pagedResults, codeManager, itemList, currentUser );
                }
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Browse_By)
            {
                collectionViewer = new Metadata_Browse_AggregationViewer( Current_Mode, Hierarchy_Object, Tracer );
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Browse_Map)
            {
                collectionViewer = new Map_Browse_AggregationViewer(Current_Mode, Hierarchy_Object, Tracer);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Item_Count)
            {
                collectionViewer = new Item_Count_AggregationViewer(Current_Mode, Hierarchy_Object);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Usage_Statistics)
            {
                collectionViewer = new Usage_Statistics_AggregationViewer(Current_Mode, Hierarchy_Object);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Private_Items)
            {
                collectionViewer = new Private_Items_AggregationViewer(Current_Mode, Hierarchy_Object, Tracer);
            }

            if (currentMode.Mode == Display_Mode_Enum.Aggregation_Admin_View)
            {
                collectionViewer = new Admin_AggregationViewer(Hierarchy_Object);
            }

            if (collectionViewer != null)
            {
                collectionViewer.Translator = translator;
                collectionViewer.HTML_Skin = HTML_Skin;
                collectionViewer.CurrentMode = Current_Mode;
                collectionViewer.CurrentObject = Hierarchy_Object;
                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 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 creates a new instance of the Aggregation_HtmlSubwriter class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        public Aggregation_HtmlSubwriter(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            leftButtons = String.Empty;
            rightButtons = String.Empty;
            children_icons_added = false;

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

            #region Handle post backs from the mySobek sharing, emailin, etc.. buttons

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

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

                if (( action == "remove_aggregation") && ( RequestSpecificValues.Current_User != null ))
                {
                    int removeAggregationID = base.RequestSpecificValues.Hierarchy_Object.ID;
                    string remove_code = base.RequestSpecificValues.Hierarchy_Object.Code;
                    string remove_name = base.RequestSpecificValues.Hierarchy_Object.Name;

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

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

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

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

                if ((action == "email") && ( RequestSpecificValues.Current_User != 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 = RequestSpecificValues.Current_User.Email;
                        if (address.ToUpper().IndexOf(RequestSpecificValues.Current_User.Email.ToUpper()) >= 0)
                            cc_list = String.Empty;

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

                        RequestSpecificValues.Current_Mode.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();
                        RequestSpecificValues.Current_Mode.Request_Completed = true;
                        return;
                    }
                }
            }
            #endregion

            #region Handle post backs from editing the home page text

            if (( RequestSpecificValues.Current_Mode.Aggregation_Type == Aggregation_Type_Enum.Home_Edit ) && ( form["sbkAghsw_HomeTextEdit"] != null))
            {
                string aggregation_folder = UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "aggregations\\" + RequestSpecificValues.Hierarchy_Object.Code + "\\";
                if (!Directory.Exists(aggregation_folder))
                    Directory.CreateDirectory(aggregation_folder);

                string file = RequestSpecificValues.Hierarchy_Object.HomePageHtml.Source;

                // 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"].Replace("%]", "%>").Replace("[%", "<%"));
                homeWriter.Flush();
                homeWriter.Close();

                // Also save this change
                SobekCM_Database.Save_Item_Aggregation_Milestone(RequestSpecificValues.Hierarchy_Object.Code, "Home page edited (" + Web_Language_Enum_Converter.Enum_To_Name(RequestSpecificValues.Current_Mode.Language) + ")", RequestSpecificValues.Current_User.Full_Name);

                // Clear this aggreation from the cache
                CachedDataManager.Aggregations.Remove_Item_Aggregation(RequestSpecificValues.Hierarchy_Object.Code, RequestSpecificValues.Tracer);

                // If this is all, save the new text as well
                if (String.Compare("all", RequestSpecificValues.Hierarchy_Object.Code, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    string home_app_key = "SobekCM_Home_" + RequestSpecificValues.Current_Mode.Language_Code;
                    HttpContext.Current.Application[home_app_key] = form["sbkAghsw_HomeTextEdit"].Replace("%]", "%>").Replace("[%", "<%");
                }

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

                return;
            }

            #endregion

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

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

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

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

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

            #region Create the new subviewer to handle this request

            if (RequestSpecificValues.Current_Mode.Mode == Display_Mode_Enum.Search)
            {
                collectionViewer = AggregationViewer_Factory.Get_Viewer(RequestSpecificValues.Current_Mode.Search_Type, RequestSpecificValues);
            }

            if (RequestSpecificValues.Current_Mode.Mode == Display_Mode_Enum.Aggregation)
            {
                switch (RequestSpecificValues.Current_Mode.Aggregation_Type)
                {
                    case Aggregation_Type_Enum.Home:
                    case Aggregation_Type_Enum.Home_Edit:
                        if (!RequestSpecificValues.Hierarchy_Object.Custom_Home_Page)
                        {
                            collectionViewer = AggregationViewer_Factory.Get_Viewer(base.RequestSpecificValues.Hierarchy_Object.Views_And_Searches[0], RequestSpecificValues);
                        }
                        else
                        {
                            collectionViewer = new Custom_Home_Page_AggregationViewer(RequestSpecificValues);
                        }
                        break;

                    case Aggregation_Type_Enum.Browse_Info:
                        if (RequestSpecificValues.Results_Statistics == null)
                        {
                            collectionViewer = new Static_Browse_Info_AggregationViewer(RequestSpecificValues);
                        }
                        else
                        {
                            collectionViewer = new DataSet_Browse_Info_AggregationViewer(RequestSpecificValues);
                        }
                        break;

                    case Aggregation_Type_Enum.Child_Page_Edit:
                        collectionViewer = new Static_Browse_Info_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Browse_By:
                        collectionViewer = new Metadata_Browse_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Browse_Map:
                        collectionViewer = new Map_Browse_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Browse_Map_Beta:
                        collectionViewer = new Map_Browse_AggregationViewer_Beta(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Item_Count:
                        collectionViewer = new Item_Count_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Usage_Statistics:
                        collectionViewer = new Usage_Statistics_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Private_Items:
                        collectionViewer = new Private_Items_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Manage_Menu:
                        collectionViewer = new Manage_Menu_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.User_Permissions:
                        collectionViewer = new User_Permissions_AggregationViewer(RequestSpecificValues);
                        break;

                    case Aggregation_Type_Enum.Work_History:
                        collectionViewer = new Work_History_AggregationViewer(RequestSpecificValues);
                        break;
                }
            }

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

            if (collectionViewer != null)
            {
                // 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")
                                RequestSpecificValues.Current_Mode.Show_Selection_Panel = true;
                        }
                        break;

                    case Selection_Panel_Display_Enum.Always:
                        RequestSpecificValues.Current_Mode.Show_Selection_Panel = true;
                        break;
                }

                behaviors = collectionViewer.AggregationViewer_Behaviors;
            }
            else
            {
                behaviors = emptybehaviors;
            }

            #endregion
        }
        /// <summary> Constructor creates a new instance of the Aggregation_HtmlSubwriter class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        public Aggregation_HtmlSubwriter(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            // Get the item aggregation from the SobekCM engine endpoints
            // If the mode is NULL or the request was already completed, do nothing
            if ((RequestSpecificValues.Current_Mode == null) || (RequestSpecificValues.Current_Mode.Request_Completed))
                return;

            RequestSpecificValues.Tracer.Add_Trace("Aggregation_HtmlSubwriter.Constructor", "Retrieving collection");

            // Check that the current aggregation code is valid
            if (!UI_ApplicationCache_Gateway.Aggregations.isValidCode(RequestSpecificValues.Current_Mode.Aggregation))
            {
                // Is there a "forward value"
                if (UI_ApplicationCache_Gateway.Collection_Aliases.ContainsKey(RequestSpecificValues.Current_Mode.Aggregation))
                {
                    RequestSpecificValues.Current_Mode.Aggregation = UI_ApplicationCache_Gateway.Collection_Aliases[RequestSpecificValues.Current_Mode.Aggregation];
                }
            }

            // Use the method in the base class to actually pull the entire hierarchy
            if (!Get_Collection(RequestSpecificValues.Current_Mode, RequestSpecificValues.Tracer, out hierarchyObject))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Error;
                return;
            }

            //// Check if a differente skin should be used if this is a collection display
            //string current_skin_code = RequestSpecificValues.Current_Mode.Skin.ToUpper();
            //if ((hierarchyObject != null) && (hierarchyObject.Web_Skins != null) && (hierarchyObject.Web_Skins.Count > 0))
            //{
            //    // Do NOT do this replacement if the web skin is in the URL and this is admin mode
            //    if ((!RequestSpecificValues.Current_Mode.Skin_In_URL) || (RequestSpecificValues.Current_Mode.Mode != Display_Mode_Enum.Administrative))
            //    {
            //        if (!hierarchyObject.Web_Skins.Contains(current_skin_code.ToLower()))
            //        {
            //            RequestSpecificValues.Current_Mode.Skin = hierarchyObject.Web_Skins[0];
            //        }
            //    }
            //}

            // Run the browse/info work if it is of those modes
            if (((RequestSpecificValues.Current_Mode.Aggregation_Type == Aggregation_Type_Enum.Browse_Info) || (RequestSpecificValues.Current_Mode.Aggregation_Type == Aggregation_Type_Enum.Child_Page_Edit)))
            {
                RequestSpecificValues.Tracer.Add_Trace("SobekCM_Page_Globals.Browse_Info_Block", "Retrieiving Browse/Info Object");

                // If this is a robot, then get the text from the static page
                if ((RequestSpecificValues.Current_Mode.Is_Robot) && (RequestSpecificValues.Current_Mode.Info_Browse_Mode == "all"))
                {
                    SobekCM_Assistant assistant = new SobekCM_Assistant();
                    browse_info_display_text = assistant.Get_All_Browse_Static_HTML(RequestSpecificValues.Current_Mode, RequestSpecificValues.Tracer);
                    RequestSpecificValues.Current_Mode.Writer_Type = Writer_Type_Enum.HTML_Echo;
                }
                else
                {
                    if (!Get_Browse_Info(RequestSpecificValues.Current_Mode, hierarchyObject, UI_ApplicationCache_Gateway.Settings.Servers.Base_Directory, RequestSpecificValues.Tracer, out thisBrowseObject, out datasetBrowseResultsStats, out pagedResults, out staticBrowse))
                    {
                        RequestSpecificValues.Current_Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                        //RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Error;
                    }
                }
            }

            // Set some basic values
            leftButtons = String.Empty;
            rightButtons = String.Empty;
            children_icons_added = false;

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

            #region Handle post backs from the mySobek sharing, emailin, etc.. buttons

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

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

                if (( action == "remove_aggregation") && ( RequestSpecificValues.Current_User != null ))
                {
                    int removeAggregationID = hierarchyObject.ID;
                    string remove_code = hierarchyObject.Code;
                    string remove_name = hierarchyObject.Name;

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

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

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

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

                if ((action == "email") && ( RequestSpecificValues.Current_User != 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 = RequestSpecificValues.Current_User.Email;
                        if (address.ToUpper().IndexOf(RequestSpecificValues.Current_User.Email.ToUpper()) >= 0)
                            cc_list = String.Empty;

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

                        RequestSpecificValues.Current_Mode.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();
                        RequestSpecificValues.Current_Mode.Request_Completed = true;
                        return;
                    }
                }
            }
            #endregion

            #region Handle post backs from editing the home page text

            if (( RequestSpecificValues.Current_Mode.Aggregation_Type == Aggregation_Type_Enum.Home_Edit ) && ( form["sbkAghsw_HomeTextEdit"] != null))
            {
                string aggregation_folder = UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "aggregations\\" + hierarchyObject.Code + "\\";
                if (!Directory.Exists(aggregation_folder))
                    Directory.CreateDirectory(aggregation_folder);

                string file = hierarchyObject.HomePageHtml.Source;

                // 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);
                }
                else
                {
                    // Ensure the folder exists
                    string directory = Path.GetDirectoryName(file);
                    if (!Directory.Exists(directory))
                        Directory.CreateDirectory(directory);
                }

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

                // Also save this change
                SobekCM_Database.Save_Item_Aggregation_Milestone(hierarchyObject.Code, "Home page edited (" + Web_Language_Enum_Converter.Enum_To_Name(RequestSpecificValues.Current_Mode.Language) + ")", RequestSpecificValues.Current_User.Full_Name);

                // Clear this aggreation from the cache
                CachedDataManager.Aggregations.Remove_Item_Aggregation(hierarchyObject.Code, RequestSpecificValues.Tracer);

                // If this is all, save the new text as well
                if (String.Compare("all", hierarchyObject.Code, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    string home_app_key = "SobekCM_Home_" + RequestSpecificValues.Current_Mode.Language_Code;
                    HttpContext.Current.Application[home_app_key] = form["sbkAghsw_HomeTextEdit"].Replace("%]", "%>").Replace("[%", "<%");
                }

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

                return;
            }

            #endregion

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

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

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

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

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

            #region Create the new subviewer to handle this request

            // First, create the aggregation view bag
            AggregationViewBag viewBag = new AggregationViewBag(hierarchyObject, datasetBrowseResultsStats, pagedResults, thisBrowseObject, staticBrowse);

            if (RequestSpecificValues.Current_Mode.Mode == Display_Mode_Enum.Search)
            {
                collectionViewer = AggregationViewer_Factory.Get_Viewer(RequestSpecificValues.Current_Mode.Search_Type, RequestSpecificValues, viewBag);
            }

            if (RequestSpecificValues.Current_Mode.Mode == Display_Mode_Enum.Aggregation)
            {
                switch (RequestSpecificValues.Current_Mode.Aggregation_Type)
                {
                    case Aggregation_Type_Enum.Home:
                    case Aggregation_Type_Enum.Home_Edit:
                        if (!hierarchyObject.Custom_Home_Page)
                        {
                            // Are there tiles here?
                            string aggregation_tile_directory = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, hierarchyObject.ObjDirectory, "images", "tiles");
                            if (Directory.Exists(aggregation_tile_directory))
                            {
                                string[] jpeg_tiles = Directory.GetFiles(aggregation_tile_directory, "*.jpg");
                                if (jpeg_tiles.Length > 0)
                                    collectionViewer = new Tiles_Home_AggregationViewer(RequestSpecificValues, viewBag);
                            }

                            // If the tiles home page as not built, build the standard viewer
                            if ( collectionViewer == null )
                                collectionViewer = AggregationViewer_Factory.Get_Viewer(hierarchyObject.Views_And_Searches[0], RequestSpecificValues, viewBag);
                        }
                        else
                        {
                            collectionViewer = new Custom_Home_Page_AggregationViewer(RequestSpecificValues, viewBag);
                        }
                        break;

                    case Aggregation_Type_Enum.Browse_Info:
                        if (datasetBrowseResultsStats == null)
                        {
                            collectionViewer = new Static_Browse_Info_AggregationViewer(RequestSpecificValues, viewBag);
                        }
                        else
                        {
                            collectionViewer = new DataSet_Browse_Info_AggregationViewer(RequestSpecificValues, viewBag);
                        }
                        break;

                    case Aggregation_Type_Enum.Child_Page_Edit:
                        collectionViewer = new Static_Browse_Info_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Browse_By:
                        collectionViewer = new Metadata_Browse_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Browse_Map:
                        collectionViewer = new Map_Browse_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Browse_Map_Beta:
                        collectionViewer = new Map_Browse_AggregationViewer_Beta(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Item_Count:
                        collectionViewer = new Item_Count_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Usage_Statistics:
                        collectionViewer = new Usage_Statistics_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Private_Items:
                        collectionViewer = new Private_Items_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Manage_Menu:
                        collectionViewer = new Manage_Menu_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.User_Permissions:
                        collectionViewer = new User_Permissions_AggregationViewer(RequestSpecificValues, viewBag);
                        break;

                    case Aggregation_Type_Enum.Work_History:
                        collectionViewer = new Work_History_AggregationViewer(RequestSpecificValues, viewBag);
                        break;
                }
            }

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

            if (collectionViewer != null)
            {
                // 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")
                                RequestSpecificValues.Current_Mode.Show_Selection_Panel = true;
                        }
                        break;

                    case Selection_Panel_Display_Enum.Always:
                        RequestSpecificValues.Current_Mode.Show_Selection_Panel = true;
                        break;
                }

                behaviors = collectionViewer.AggregationViewer_Behaviors;
            }
            else
            {
                behaviors = emptybehaviors;
            }

            #endregion
        }