/// <summary> Constructor for a new instance of the Web_Content_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="Static_Web_Content"> Object contains all the basic information about this info display </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of page</param>
        public Web_Content_HtmlSubwriter(Item_Aggregation Hierarchy_Object, SobekCM_Navigation_Object Current_Mode, SobekCM_Skin_Object HTML_Skin, HTML_Based_Content Static_Web_Content, SobekCM_SiteMap Site_Map)
        {
            base.Current_Aggregation = Hierarchy_Object;
            currentMode = Current_Mode;
            Skin = HTML_Skin;

            thisStaticBrowseObject = Static_Web_Content;
            siteMap = Site_Map;

            // If there is a sitemap, check if this is a robot request and then if the URL
            // for the sitemap pages is URL restricted
            if ((siteMap != null) && (siteMap.Is_URL_Restricted_For_Robots) && (currentMode.Is_Robot))
            {
                if (currentMode.Base_URL != siteMap.Restricted_Robot_URL)
                {
                    currentMode.Base_URL = siteMap.Restricted_Robot_URL;
                    string redirect_url = currentMode.Redirect_URL();

                    HttpContext.Current.Response.Status = "301 Moved Permanently";
                    HttpContext.Current.Response.AddHeader("Location", redirect_url);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    currentMode.Request_Completed = true;
                    return;
                }
            }
        }
 /// <summary> Constructor for a new instance of the Text_MainWriter class </summary>
 /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
 /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
 /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
 /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
 /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
 /// <param name="Current_Item"> Current item to display </param>
 /// <param name="Current_Page"> Current page within the 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>
 public Text_MainWriter(SobekCM_Navigation_Object Current_Mode,
      Item_Aggregation Hierarchy_Object,
     Search_Results_Statistics Results_Statistics,
     List<iSearch_Title_Result> Paged_Results,
     Item_Aggregation_Child_Page Browse_Object,
     SobekCM_Item Current_Item,
     Page_TreeNode Current_Page,
     HTML_Based_Content Static_Web_Content)
     : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object, Current_Item, Current_Page, Static_Web_Content)
 {
     // All work done in base class
 }
 /// <summary> Constructor for a new instance of the abstractMainWriter abstract class </summary>
 /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
 /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
 /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
 /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
 /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
 /// <param name="Current_Item"> Current item to display </param>
 /// <param name="Current_Page"> Current page within the 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>
 protected abstractMainWriter(SobekCM_Navigation_Object Current_Mode,
     Item_Aggregation Hierarchy_Object,
     Search_Results_Statistics Results_Statistics,
     List<iSearch_Title_Result> Paged_Results,
     Item_Aggregation_Child_Page Browse_Object,
     SobekCM_Item Current_Item,
     Page_TreeNode Current_Page,
     HTML_Based_Content Static_Web_Content )
 {
     currentMode = Current_Mode;
     hierarchyObject = Hierarchy_Object;
     results_statistics = Results_Statistics;
     paged_results = Paged_Results;
     thisBrowseObject = Browse_Object;
     currentItem = Current_Item;
     currentPage = Current_Page;
     htmlBasedContent = Static_Web_Content;
 }
        /// <summary> Constructor for a new instance of the Text_MainWriter class </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
        /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
        /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
        /// <param name="Current_Item"> Current item to display </param>
        /// <param name="Current_Page"> Current page within the item</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Current_User"> Currently logged on user </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Item_List"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Stats_Date_Range"> Object contains the start and end dates for the statistical data in the database </param>
        /// <param name="Search_History"> List of recent searches performed against this digital library </param>
        /// <param name="Icon_Dictionary"> Dictionary of information about every wordmark/icon in this digital library, used to build the wordmarks subpage </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the main home page are organized </param>
        /// <param name="Public_Folder"> Object contains the information about the public folder to display </param>
        /// <param name="Aggregation_Aliases"> List of all existing aliases for existing aggregations </param>
        /// <param name="Web_Skin_Collection"> Collection of all the web skins </param>
        /// <param name="Checked_Items"> List of all items which are currently checked out for single fair use and the IP address currently viewing the item</param>
        /// <param name="IP_Restrictions"> Any possible restriction on item access by IP ranges </param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of static web content pages </param>
        /// <param name="Items_In_Title"> List of items within the current title ( used for the Item Group display )</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 Html_MainWriter(SobekCM_Navigation_Object Current_Mode,
            Item_Aggregation Hierarchy_Object,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Item_Aggregation_Child_Page Browse_Object,
            SobekCM_Item Current_Item,
            Page_TreeNode Current_Page,
            SobekCM_Skin_Object HTML_Skin,
            User_Object Current_User,
            Language_Support_Info Translator,
            Aggregation_Code_Manager Code_Manager,
            Item_Lookup_Object Item_List,
            Statistics_Dates Stats_Date_Range,
            Recent_Searches Search_History,
            Dictionary<string, Wordmark_Icon> Icon_Dictionary,
            List<Thematic_Heading> Thematic_Headings,
            Public_User_Folder Public_Folder,
            Dictionary<string, string> Aggregation_Aliases,
            SobekCM_Skin_Collection Web_Skin_Collection,
            Checked_Out_Items_List Checked_Items,
            IP_Restriction_Ranges IP_Restrictions,
            Portal_List URL_Portals,
            SobekCM_SiteMap Site_Map,
            SobekCM_Items_In_Title Items_In_Title,
            HTML_Based_Content Static_Web_Content,
            Custom_Tracer Tracer )
            : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,  Current_Item, Current_Page, Static_Web_Content)
        {
            // Save parameters
            htmlSkin = HTML_Skin;
            translator = Translator;
            codeManager = Code_Manager;
            itemList = Item_List;
            statsDateRange = Stats_Date_Range;
            searchHistory = Search_History;
            currentUser = Current_User;
            iconList = Icon_Dictionary;
            thematicHeadings = Thematic_Headings;
            publicFolder = Public_Folder;
            aggregationAliases = Aggregation_Aliases;
            webSkins = Web_Skin_Collection;
            checkedItems = Checked_Items;
            ipRestrictionInfo = IP_Restrictions;
            urlPortals = URL_Portals;
            siteMap = Site_Map;
            itemsInTitle = Items_In_Title;

            // Set some defaults

            // Handle basic events which may be fired by the internal header
            if (HttpContext.Current.Request.Form["internal_header_action"] != null)
            {
                // Pull the action value
                string internalHeaderAction = HttpContext.Current.Request.Form["internal_header_action"].Trim();

                // Was this to hide or show the header?
                if ((internalHeaderAction == "hide") || (internalHeaderAction == "show"))
                {
                    // Pull the current visibility from the session
                    bool shown = !((HttpContext.Current.Session["internal_header"] != null) && (HttpContext.Current.Session["internal_header"].ToString() == "hidden"));
                    if ((internalHeaderAction == "hide") && (shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "hidden";
                        currentMode.Redirect();
                        return;
                    }
                    if ((internalHeaderAction == "show") && (!shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "shown";
                        currentMode.Redirect();
                        return;
                    }
                }
            }

            try
            {

                // Create the html sub writer now
                switch (Current_Mode.Mode)
                {
                    case Display_Mode_Enum.Internal:
                        subwriter = new Internal_HtmlSubwriter(iconList, currentUser, codeManager);
                        break;

                    case Display_Mode_Enum.Statistics:
                        subwriter = new Statistics_HtmlSubwriter(searchHistory, codeManager, statsDateRange);
                        break;

                    case Display_Mode_Enum.Preferences:
                        subwriter = new Preferences_HtmlSubwriter(currentMode);
                        break;

                    case Display_Mode_Enum.Error:
                        subwriter = new Error_HtmlSubwriter(false);
                        // Send the email now
                        if (currentMode.Caught_Exception != null)
                        {
                            if (currentMode.Error_Message.Length == 0)
                                currentMode.Error_Message = "Unknown exception caught";
                            Email_Information(currentMode.Error_Message, currentMode.Caught_Exception, Tracer, false);
                        }
                        break;

                    case Display_Mode_Enum.Legacy_URL:
                        subwriter = new LegacyUrl_HtmlSubwriter();
                        break;

                    case Display_Mode_Enum.Item_Print:
                        subwriter = new Print_Item_HtmlSubwriter(currentItem, codeManager, translator, currentMode);
                        break;

                    case Display_Mode_Enum.Contact:

                        StringBuilder builder = new StringBuilder();
                        builder.Append("\n\nSUBMISSION INFORMATION\n");
                        builder.Append("\tDate:\t\t\t\t" + DateTime.Now.ToString() + "\n");
                        string lastMode = String.Empty;
                        try
                        {
                            if (HttpContext.Current.Session["Last_Mode"] != null)
                                lastMode = HttpContext.Current.Session["Last_Mode"].ToString();
                            builder.Append("\tIP Address:\t\t\t" + HttpContext.Current.Request.UserHostAddress + "\n");
                            builder.Append("\tHost Name:\t\t\t" + HttpContext.Current.Request.UserHostName + "\n");
                            builder.Append("\tBrowser:\t\t\t" + HttpContext.Current.Request.Browser.Browser + "\n");
                            builder.Append("\tBrowser Platform:\t\t" + HttpContext.Current.Request.Browser.Platform + "\n");
                            builder.Append("\tBrowser Version:\t\t" + HttpContext.Current.Request.Browser.Version + "\n");
                            builder.Append("\tBrowser Language:\t\t");
                            bool first = true;
                            string[] languages = HttpContext.Current.Request.UserLanguages;
                            if (languages != null)
                                foreach (string thisLanguage in languages)
                                {
                                    if (first)
                                    {
                                        builder.Append(thisLanguage);
                                        first = false;
                                    }
                                    else
                                    {
                                        builder.Append(", " + thisLanguage);
                                    }
                                }

                            builder.Append("\n\nHISTORY\n");
                            if (HttpContext.Current.Session["LastSearch"] != null)
                                builder.Append("\tLast Search:\t\t" + HttpContext.Current.Session["LastSearch"] + "\n");
                            if (HttpContext.Current.Session["LastResults"] != null)
                                builder.Append("\tLast Results:\t\t" + HttpContext.Current.Session["LastResults"] + "\n");
                            if (HttpContext.Current.Session["Last_Mode"] != null)
                                builder.Append("\tLast Mode:\t\t\t" + HttpContext.Current.Session["Last_Mode"] + "\n");
                            builder.Append("\tURL:\t\t\t\t" + HttpContext.Current.Items["Original_URL"]);
                        }
                        catch
                        {

                        }
                        subwriter = new Contact_HtmlSubwriter(lastMode, builder.ToString(), currentMode, hierarchyObject);
                        break;

                    case Display_Mode_Enum.Contact_Sent:
                        subwriter = new Contact_HtmlSubwriter(String.Empty, String.Empty, currentMode, hierarchyObject);
                        break;

                    case Display_Mode_Enum.Simple_HTML_CMS:
                        subwriter = new Web_Content_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, htmlBasedContent, siteMap);
                        break;

                    case Display_Mode_Enum.My_Sobek:
                        subwriter = new MySobek_HtmlSubwriter(results_statistics, paged_results, codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, currentItem, currentUser, iconList, statsDateRange, webSkins, Tracer);
                        break;

                    case Display_Mode_Enum.Administrative:
                        subwriter = new Admin_HtmlSubwriter(codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, aggregationAliases, webSkins, currentUser, ipRestrictionInfo, iconList, urlPortals, thematicHeadings, Tracer);
                        break;

                    case Display_Mode_Enum.Results:
                        subwriter = new Search_Results_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser);
                        break;

                    case Display_Mode_Enum.Public_Folder:
                        subwriter = new Public_Folder_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser, publicFolder);
                        break;

                    case Display_Mode_Enum.Search:
                    case Display_Mode_Enum.Aggregation:
                        subwriter = new Aggregation_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, translator, thisBrowseObject, results_statistics, paged_results, codeManager, itemList, thematicHeadings, currentUser, htmlBasedContent, Tracer);
                        break;

                    case Display_Mode_Enum.Item_Display:
                        if ((!currentMode.Invalid_Item) && (currentItem != null))
                        {
                            bool show_toc = false;
                            if (HttpContext.Current.Session["Show TOC"] != null)
                            {
                                Boolean.TryParse(HttpContext.Current.Session["Show TOC"].ToString(), out show_toc);
                            }

                            // Check that this item is not checked out by another user
                            bool itemCheckedOutByOtherUser = false;
                            if (currentItem.Behaviors.CheckOut_Required)
                            {
                                if (!checkedItems.Check_Out(currentItem.Web.ItemID, HttpContext.Current.Request.UserHostAddress))
                                {
                                    itemCheckedOutByOtherUser = true;
                                }
                            }

                            // Check to see if this is IP restricted
                            string restriction_message = String.Empty;
                            if (currentItem.Behaviors.IP_Restriction_Membership > 0)
                            {
                                if (HttpContext.Current != null)
                                {
                                    int user_mask = (int)HttpContext.Current.Session["IP_Range_Membership"];
                                    int comparison = currentItem.Behaviors.IP_Restriction_Membership & user_mask;
                                    if (comparison == 0)
                                    {
                                        int restriction = currentItem.Behaviors.IP_Restriction_Membership;
                                        int restriction_counter = 0;
                                        while (restriction % 2 != 1)
                                        {
                                            restriction = restriction >> 1;
                                            restriction_counter++;
                                        }
                                        restriction_message = ipRestrictionInfo[restriction_counter].Item_Restricted_Statement;
                                    }
                                }
                            }

                            // Create the item viewer writer
                            subwriter = new Item_HtmlSubwriter(currentItem, currentPage, currentUser, codeManager, translator, show_toc, (SobekCM_Library_Settings.JP2ServerUrl.Length > 0), currentMode, hierarchyObject, restriction_message, itemsInTitle, Tracer);
                            ((Item_HtmlSubwriter)subwriter).Item_Checked_Out_By_Other_User = itemCheckedOutByOtherUser;
                        }
                        else
                        {
                            // Create the invalid item html subwrite and write the HTML
                            subwriter = new Error_HtmlSubwriter(true);
                        }
                        break;

                }
            }
            catch (Exception ee)
            {
                // Send to the dashboard
                if ((HttpContext.Current.Request.UserHostAddress == "127.0.0.1") || (HttpContext.Current.Request.UserHostAddress == HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"]) || (HttpContext.Current.Request.Url.ToString().IndexOf("localhost") >= 0))
                {
                    Tracer.Add_Trace("Html_MainWriter.Constructor", "Exception caught!", Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Html_MainWriter.Constructor", ee.Message, Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Html_MainWriter.Constructor", ee.StackTrace, Custom_Trace_Type_Enum.Error);

                    // Wrap this into the SobekCM Exception
                    SobekCM_Traced_Exception newException = new SobekCM_Traced_Exception("Exception caught while building the mode-specific HTML Subwriter", ee, Tracer);

                    // Save this to the session state, and then forward to the dashboard
                    HttpContext.Current.Session["Last_Exception"] = newException;
                    HttpContext.Current.Response.Redirect("dashboard.aspx", false);
                    Current_Mode.Request_Completed = true;

                    return;
                }
                else
                {
                    subwriter = new Error_HtmlSubwriter(false);
                }
            }

            if (subwriter != null)
            {
                subwriter.Mode = currentMode;
                subwriter.Skin = htmlSkin;
                subwriter.Current_Aggregation = hierarchyObject;
            }
        }
        /// <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 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> Gets the browse or info object and any other needed data for display ( resultset or text to display) </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Aggregation_Object"> Item Aggregation object</param>
        /// <param name="Base_Directory"> Base directory location under which the the CMS/info source file will be found</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="Browse_Object"> [OUT] Stores all the information about this browse or info </param>
        /// <param name="Complete_Result_Set_Info"> [OUT] Information about the entire set of results </param>
        /// <param name="Paged_Results"> [OUT] List of search results for the requested page of results </param>
        /// <param name="Browse_Info_Display_Text"> [OUT] Static HTML-based content to be displayed if this is browing a staticly created html source file </param>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        /// <remarks> This attempts to pull the objects from the cache.  If unsuccessful, it builds the objects from the
        /// database and hands off to the <see cref="Cached_Data_Manager" /> to store in the cache </remarks>
        public bool Get_Browse_Info(SobekCM_Navigation_Object Current_Mode,
                                    Item_Aggregation Aggregation_Object,
                                    string Base_Directory,
                                    Custom_Tracer Tracer,
                                    out Item_Aggregation_Browse_Info Browse_Object,
                                    out Search_Results_Statistics Complete_Result_Set_Info,
                                    out List<iSearch_Title_Result> Paged_Results,
                                    out HTML_Based_Content Browse_Info_Display_Text )
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_Assistant.Get_Browse_Info", String.Empty);
            }

            // Set output initially to null
            Browse_Object = null;
            Paged_Results = null;
            Complete_Result_Set_Info = null;
            Browse_Info_Display_Text = null;

            // First, make sure the browse submode is valid
            if ((Aggregation_Object.Aggregation_ID == -1) && (Current_Mode.Mode == Display_Mode_Enum.Simple_HTML_CMS))
            {
                string source = Base_Directory + "design\\info";
                string[] matching_file = Directory.GetFiles(source, Current_Mode.Info_Browse_Mode + ".*");
                if (matching_file.Length > 0)
                {
                    Browse_Object = new Item_Aggregation_Browse_Info(Item_Aggregation_Browse_Info.Browse_Info_Type.Info, Item_Aggregation_Browse_Info.Source_Type.Static_HTML, Current_Mode.Info_Browse_Mode, matching_file[0], Current_Mode.Info_Browse_Mode);
                }
            }
            else
            {
                Browse_Object = Aggregation_Object.Get_Browse_Info_Object(Current_Mode.Info_Browse_Mode);
            }
            if (Browse_Object == null)
            {
                Current_Mode.Error_Message = "Unable to retrieve browse/info item '" + Current_Mode.Info_Browse_Mode + "'";
                return false;
            }

            // Is this a table result, or a string?
            switch (Browse_Object.Data_Type)
            {
                case Item_Aggregation_Browse_Info.Result_Data_Type.Table:

                    // Set the current sort to ZERO, if currently set to ONE and this is an ALL BROWSE.
                    // Those two sorts are the same in this case
                    int sort = Current_Mode.Sort;
                    if ((Current_Mode.Sort == 0) && (Browse_Object.Code == "all"))
                        sort = 1;

                    // Special code if this is a JSON browse
                    string browse_code = Current_Mode.Info_Browse_Mode;
                    if (Current_Mode.Writer_Type == Writer_Type_Enum.JSON)
                    {
                        browse_code = browse_code + "_JSON";
                        sort = 12;
                    }

                    // Determine if this is a special search type which returns more rows and is not cached.
                    // This is used to return the results as XML and DATASET
                    bool special_search_type = false;
                    int results_per_page = 20;
                    if ((Current_Mode.Writer_Type == Writer_Type_Enum.XML) || (Current_Mode.Writer_Type == Writer_Type_Enum.DataSet))
                    {
                        results_per_page = 1000;
                        special_search_type = true;
                        sort = 2; // Sort by BibID always for these
                    }

                    // Set the flags for how much data is needed.  (i.e., do we need to pull ANYTHING?  or
                    // perhaps just the next page of results ( as opposed to pulling facets again).
                    bool need_browse_statistics = true;
                    bool need_paged_results = true;
                    if (!special_search_type)
                    {
                        // Look to see if the browse statistics are available on any cache for this browse
                        Complete_Result_Set_Info = Cached_Data_Manager.Retrieve_Browse_Result_Statistics(Aggregation_Object.Code, browse_code, Tracer);
                        if (Complete_Result_Set_Info != null)
                            need_browse_statistics = false;

                        // Look to see if the paged results are available on any cache..
                        Paged_Results = Cached_Data_Manager.Retrieve_Browse_Results(Aggregation_Object.Code, browse_code, Current_Mode.Page, sort, Tracer);
                        if (Paged_Results != null)
                            need_paged_results = false;
                    }

                    // Was a copy found in the cache?
                    if ((!need_browse_statistics) && ( !need_paged_results ))
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("SobekCM_Assistant.Get_Browse_Info", "Browse statistics and paged results retrieved from cache");
                        }
                    }
                    else
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("SobekCM_Assistant.Get_Browse_Info", "Building results information");
                        }

                        // Try to pull more than one page, so we can cache the next page or so
                        List<List<iSearch_Title_Result>> pagesOfResults;

                        // Get from the hierarchy object
                        if (Current_Mode.Writer_Type == Writer_Type_Enum.JSON)
                        {
                            Multiple_Paged_Results_Args returnArgs = SobekCM_Database.Get_Item_Aggregation_Browse_Paged(Current_Mode.Aggregation, "1900-01-01", false, 20, Current_Mode.Page, 0, need_browse_statistics, Aggregation_Object.Facets, need_browse_statistics, Tracer);
                            if (need_browse_statistics)
                            {
                                Complete_Result_Set_Info = returnArgs.Statistics;
                            }
                            pagesOfResults = returnArgs.Paged_Results;
                            if ((pagesOfResults != null) && (pagesOfResults.Count > 0))
                                Paged_Results = pagesOfResults[0];
                        }
                        else
                        {
                            Multiple_Paged_Results_Args returnArgs = Aggregation_Object.Get_Browse_Results(Browse_Object, Current_Mode.Page, sort, results_per_page, !special_search_type, need_browse_statistics, Tracer);
                            if (need_browse_statistics)
                            {
                                Complete_Result_Set_Info = returnArgs.Statistics;
                            }
                            pagesOfResults = returnArgs.Paged_Results;
                            if ((pagesOfResults != null) && (pagesOfResults.Count > 0))
                                Paged_Results = pagesOfResults[0];
                        }

                        // Save the overall result set statistics to the cache if something was pulled
                        if (!special_search_type)
                        {
                            if ((need_browse_statistics) && (Complete_Result_Set_Info != null))
                            {
                                Cached_Data_Manager.Store_Browse_Result_Statistics(Aggregation_Object.Code, browse_code, Complete_Result_Set_Info, Tracer);
                            }

                            // Save the overall result set statistics to the cache if something was pulled
                            if ((need_paged_results) && (Paged_Results != null))
                            {
                                Cached_Data_Manager.Store_Browse_Results(Aggregation_Object.Code, browse_code, Current_Mode.Page, sort, pagesOfResults, Tracer);
                            }
                        }
                    }
                    break;

                case Item_Aggregation_Browse_Info.Result_Data_Type.Text:
                    Browse_Info_Display_Text = Browse_Object.Get_Static_Content(Current_Mode.Language, Current_Mode.Base_URL, SobekCM_Library_Settings.Base_Design_Location + Aggregation_Object.objDirectory, Tracer);
                    break;
            }
            return true;
        }
        /// <summary> Gets the simple CMS/info object and text to display </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Base_Directory"> Base directory location under which the the CMS/info source file will be found</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="Simple_Web_Content"> [OUT] Built browse object which contains information like title, banner, etc.. and the entire text to be displayed </param>
        /// <param name="Site_Map"> [OUT] Optional navigational site map object related to this page </param>
        /// <returns>TRUE if successful, otherwise FALSE </returns>
        /// <remarks> This always pulls the data directly from disk; this text is not cached. </remarks>
        public bool Get_Simple_Web_Content_Text(SobekCM_Navigation_Object Current_Mode, string Base_Directory, Custom_Tracer Tracer, out HTML_Based_Content Simple_Web_Content, out SobekCM_SiteMap Site_Map )
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_Assistant.Get_Simple_Web_Content_Text", String.Empty);
            }

            Site_Map = null;

            string source = Current_Mode.Page_By_FileName;
            Simple_Web_Content = HTML_Based_Content_Reader.Read_HTML_File(source, true, Tracer);

            if (Simple_Web_Content == null)
            {
                Current_Mode.Error_Message = "Unable to retrieve simple text item '" + Current_Mode.Info_Browse_Mode.Replace("_","\\") + "'";
                return false;
            }

            if ( Simple_Web_Content.Static_Text.Length == 0 )
            {
                Current_Mode.Error_Message = "Unable to read the file for display";
                return false;
            }

            // Now, check for any "server-side include" directorives in the source text
            int include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE");
            while(( include_index > 0 ) && ( Simple_Web_Content.Static_Text.IndexOf("%>", include_index ) > 0 ))
            {
                int include_finish_index = Simple_Web_Content.Static_Text.IndexOf("%>", include_index) + 2;
                string include_statement = Simple_Web_Content.Static_Text.Substring(include_index, include_finish_index - include_index);
                string include_statement_upper = include_statement.ToUpper();
                int file_index = include_statement_upper.IndexOf("FILE");
                string filename_to_include = String.Empty;
                if (file_index > 0)
                {
                    // Pull out the possible file name
                    string possible_file_name = include_statement.Substring(file_index + 4);
                    int file_start = -1;
                    int file_end = -1;
                    int char_index = 0;

                    // Find the start of the file information
                    while ((file_start < 0) && (char_index < possible_file_name.Length))
                    {
                        if ((possible_file_name[char_index] != '"') && (possible_file_name[char_index] != '=') && (possible_file_name[char_index] != ' '))
                        {
                            file_start = char_index;
                        }
                        else
                        {
                            char_index++;
                        }
                    }

                    // Find the end of the file information
                    if (file_start >= 0)
                    {
                        char_index++;
                        while ((file_end < 0) && (char_index < possible_file_name.Length))
                        {
                            if ((possible_file_name[char_index] == '"') || (possible_file_name[char_index] == ' ') || (possible_file_name[char_index] == '%'))
                            {
                                file_end = char_index;
                            }
                            else
                            {
                                char_index++;
                            }
                        }
                    }

                    // Get the filename
                    if ((file_start > 0) && (file_end > 0))
                    {
                        filename_to_include = possible_file_name.Substring(file_start, file_end - file_start);
                    }
                }

                // Remove the include and either place in the text from the indicated file,
                // or just remove
                if ((filename_to_include.Length > 0 ) && (File.Exists(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + filename_to_include)))
                {
                    // Define the value for the include text
                    string include_text;

                    // Look in the cache for this
                    object returnValue = HttpContext.Current.Cache.Get("INCLUDE_" + filename_to_include );
                    if (returnValue != null)
                    {
                        include_text = returnValue.ToString();
                    }
                    else
                    {
                        try
                        {
                            // Pull from the file
                            StreamReader reader = new StreamReader(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + filename_to_include);
                            include_text = reader.ReadToEnd();
                            reader.Close();

                            // Store on the cache for two minutes, if no indication not to
                            if ( include_statement_upper.IndexOf("NOCACHE") < 0 )
                                HttpContext.Current.Cache.Insert("INCLUDE_" + filename_to_include, include_text, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(2));
                        }
                        catch(Exception)
                        {
                            include_text = "Unable to read the soruce file ( " + filename_to_include + " )";
                        }
                    }

                    // Replace the text with the include file
                    Simple_Web_Content.Static_Text = Simple_Web_Content.Static_Text.Replace(include_statement, include_text);
                    include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE", include_index + include_text.Length - 1 );
                }
                else
                {
                    // No suitable name was found, or it doesn't exist so just remove the INCLUDE completely
                    Simple_Web_Content.Static_Text = Simple_Web_Content.Static_Text.Replace(include_statement, "");
                    include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE", include_index );
                }
            }

            // Look for a site map
            if (Simple_Web_Content.SiteMap.Length > 0)
            {
                // Look in the cache first
                Site_Map = Cached_Data_Manager.Retrieve_Site_Map(Simple_Web_Content.SiteMap, Tracer);

                // If this was NULL, pull it
                if (Site_Map == null)
                {
                    // Only continue if the file exists
                    if (File.Exists(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + Simple_Web_Content.SiteMap))
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("SobekCM_Assistant.Get_Simple_Web_Content_Text", "Reading site map file");
                        }

                        // Try to read this sitemap file
                        Site_Map = SobekCM_SiteMap_Reader.Read_SiteMap_File(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + Simple_Web_Content.SiteMap);

                        // If the sitemap file was succesfully read, cache it
                        if (Site_Map != null)
                        {
                            Cached_Data_Manager.Store_Site_Map(Site_Map, Simple_Web_Content.SiteMap, Tracer);
                        }
                    }
                }
            }

            // Since this is not cached, we can apply the individual user settings to the static text which was read right here
            Simple_Web_Content.Static_Text = Simple_Web_Content.Apply_Settings_To_Static_Text(Simple_Web_Content.Static_Text, null, Current_Mode.Skin, Current_Mode.Base_Skin, Current_Mode.Base_URL, Current_Mode.URL_Options(), Tracer);

            return true;
        }
        private static HTML_Based_Content Text_To_HTML_Based_Content( string Display_Text , bool Retain_Entire_Display_Text, string Source)
        {
            // Create the values to hold the information
                string code = String.Empty;
                string title = String.Empty;
                string author = String.Empty;
                string description = String.Empty;
                string thumbnail = String.Empty;
                string keyword = String.Empty;
                string banner = String.Empty;
                string date = String.Empty;
                string sitemap = String.Empty;
                string webskin = String.Empty;

                // StringBuilder keeps track of any other information in the head that should be retained
                StringBuilder headBuilder = new StringBuilder();

                // Try to read the head using XML
                int head_start = Display_Text.IndexOf("<head>", StringComparison.OrdinalIgnoreCase);
                int head_end = Display_Text.IndexOf("</head>", StringComparison.OrdinalIgnoreCase);
                bool read_as_xml = false;
                if ((head_start >= 0) && (head_end > head_start))
                {
                    try
                    {
                        string head_xml = Display_Text.Substring(head_start, (head_end - head_start) + 7);
                        XmlTextReader xmlReader = new XmlTextReader(new StringReader(head_xml));
                        while (xmlReader.Read())
                        {
                            if (xmlReader.NodeType != XmlNodeType.Element) continue;

                            switch (xmlReader.Name.ToUpper())
                            {
                                case "LINK":
                                    headBuilder.Append("<link ");
                                    int attributeCount = xmlReader.AttributeCount;
                                    for (int i = 0; i < attributeCount; i++)
                                    {
                                        xmlReader.MoveToAttribute(i);
                                        headBuilder.Append(xmlReader.Name + "=\"" + xmlReader.Value + "\" ");
                                    }
                                    headBuilder.AppendLine(" />");
                                    break;

                                case "TITLE":
                                    xmlReader.Read();
                                    title = xmlReader.Value;
                                    break;

                                case "CODE":
                                    xmlReader.Read();
                                    code = xmlReader.Value.ToLower();
                                    break;

                                case "META":
                                    string name_type = String.Empty;
                                    string content_type = String.Empty;
                                    if (xmlReader.MoveToAttribute("name"))
                                    {
                                        name_type = xmlReader.Value;
                                    }
                                    if (xmlReader.MoveToAttribute("content"))
                                    {
                                        content_type = xmlReader.Value;
                                    }
                                    if ((name_type.Length > 0) && (content_type.Length > 0))
                                    {
                                        switch (name_type.ToUpper())
                                        {
                                            case "BANNER":
                                                banner = content_type;
                                                break;

                                            case "TITLE":
                                                title = content_type;
                                                break;

                                            case "THUMBNAIL":
                                                thumbnail = content_type;
                                                break;

                                            case "AUTHOR":
                                                author = content_type;
                                                break;

                                            case "DATE":
                                                date = content_type;
                                                break;

                                            case "KEYWORDS":
                                                keyword = content_type;
                                                break;

                                            case "DESCRIPTION":
                                                description = content_type;
                                                break;

                                            case "CODE":
                                                code = content_type.ToLower();
                                                break;

                                            case "SITEMAP":
                                                sitemap = content_type;
                                                break;

                                            case "WEBSKIN":
                                                webskin = content_type;
                                                break;
                                        }
                                    }
                                    break;
                            }
                        }
                        read_as_xml = true;
                    }
                    catch
                    {
                        read_as_xml = false;
                    }
                }

                // Read this the old way if unable to read via XML for some reason
                if (!read_as_xml)
                {
                    // Get the title and code

                        string header_info = Display_Text.Substring(0, Display_Text.IndexOf("<body>"));
                        if (header_info.IndexOf("<title>") > 0)
                        {
                            string possible_title = header_info.Substring(header_info.IndexOf("<title>"));
                            possible_title = possible_title.Substring(7, possible_title.IndexOf("</title>") - 7);
                            title = possible_title.Trim();
                        }
                        if (header_info.IndexOf("<code>") > 0)
                        {
                            string possible_code = header_info.Substring(header_info.IndexOf("<code>"));
                            possible_code = possible_code.Substring(6, possible_code.IndexOf("</code>") - 6);
                            code = possible_code.Trim();
                        }

                    // See if the banner should be displayed (default is only option righht now)
                    if (Display_Text.IndexOf("<meta name=\"banner\" content=\"default\"") > 0)
                    {
                        banner = "default";
                    }
                }

                // Create return value
            HTML_Based_Content returnValue = new HTML_Based_Content {Code = code, Title = title};
            if ( author.Length > 0 )
                    returnValue.Author = author;
                if ( banner.Length > 0 )
                    returnValue.Banner = banner;
                if ( date.Length > 0 )
                    returnValue.Date = date;
                if ( description.Length > 0 )
                    returnValue.Description = description;
                if ( keyword.Length > 0 )
                    returnValue.Keywords = keyword;
                if ( thumbnail.Length > 0 )
                    returnValue.Thumbnail = thumbnail;
                if (sitemap.Length > 0)
                    returnValue.SiteMap = sitemap;
                if (webskin.Length > 0)
                    returnValue.Web_Skin = webskin;
                if ( headBuilder.Length > 0 )
                    returnValue.Extra_Head_Info = headBuilder.ToString();

                // Should the actual display text be retained?
                if (Retain_Entire_Display_Text)
                {
                    int start_body = Display_Text.IndexOf("<body>") + 6;
                    int end_body = Display_Text.IndexOf("</body>");
                    if ((start_body > 0) && (end_body > start_body))
                    {
                        returnValue.Static_Text = Display_Text.Substring(start_body, end_body - start_body) + " ";

                        if (( Source.Length > 0 ) && ( returnValue.Static_Text.IndexOf("<%LASTMODIFIED%>") > 0))
                        {
                            FileInfo fileInfo = new FileInfo(Source);
                            DateTime lastWritten = fileInfo.LastWriteTime;
                            returnValue.Static_Text = returnValue.Static_Text.Replace("<%LASTMODIFIED%>", lastWritten.ToLongDateString());
                        }
                    }
                }

                return returnValue;
        }
        /// <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>
 public Static_Browse_Info_AggregationViewer(Item_Aggregation_Browse_Info Browse_Object, HTML_Based_Content Static_Web_Content )
     : base(null, null)
 {
     browseObject = Browse_Object;
     staticWebContent = Static_Web_Content;
 }
        /// <summary> Constructor for a new instance of the Text_MainWriter class </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
        /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
        /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
        /// <param name="Current_Item"> Current item to display </param>
        /// <param name="Current_Page"> Current page within the item</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Current_User"> Currently logged on user </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Item_List"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Stats_Date_Range"> Object contains the start and end dates for the statistical data in the database </param>
        /// <param name="Search_History"> List of recent searches performed against this digital library </param>
        /// <param name="Icon_Dictionary"> Dictionary of information about every wordmark/icon in this digital library, used to build the wordmarks subpage </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the main home page are organized </param>
        /// <param name="Public_Folder"> Object contains the information about the public folder to display </param>
        /// <param name="Aggregation_Aliases"> List of all existing aliases for existing aggregations </param>
        /// <param name="Web_Skin_Collection"> Collection of all the web skins </param>
        /// <param name="Checked_Items"> List of all items which are currently checked out for single fair use and the IP address currently viewing the item</param>
        /// <param name="IP_Restrictions"> Any possible restriction on item access by IP ranges </param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of static web content pages </param>
        /// <param name="Items_In_Title"> List of items within the current title ( used for the Item Group display )</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>
        public Html_MainWriter(SobekCM_Navigation_Object Current_Mode,
            Item_Aggregation Hierarchy_Object,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Item_Aggregation_Browse_Info Browse_Object,
            SobekCM_Item Current_Item,
            Page_TreeNode Current_Page,
            SobekCM_Skin_Object HTML_Skin,
            User_Object Current_User,
            Language_Support_Info Translator,
            Aggregation_Code_Manager Code_Manager,
            Item_Lookup_Object Item_List,
            Statistics_Dates Stats_Date_Range,
            Recent_Searches Search_History,
            Dictionary<string, Wordmark_Icon> Icon_Dictionary,
            List<Thematic_Heading> Thematic_Headings,
            Public_User_Folder Public_Folder,
            Dictionary<string, string> Aggregation_Aliases,
            SobekCM_Skin_Collection Web_Skin_Collection,
            Checked_Out_Items_List Checked_Items,
            IP_Restriction_Ranges IP_Restrictions,
            Portal_List URL_Portals,
            SobekCM_SiteMap Site_Map,
            SobekCM_Items_In_Title Items_In_Title,
            HTML_Based_Content Static_Web_Content )
            : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,  Current_Item, Current_Page, Static_Web_Content)
        {
            // Save parameters
            htmlSkin = HTML_Skin;
            translator = Translator;
            codeManager = Code_Manager;
            itemList = Item_List;
            statsDateRange = Stats_Date_Range;
            searchHistory = Search_History;
            currentUser = Current_User;
            iconList = Icon_Dictionary;
            thematicHeadings = Thematic_Headings;
            publicFolder = Public_Folder;
            aggregationAliases = Aggregation_Aliases;
            webSkins = Web_Skin_Collection;
            checkedItems = Checked_Items;
            ipRestrictionInfo = IP_Restrictions;
            urlPortals = URL_Portals;
            siteMap = Site_Map;
            itemsInTitle = Items_In_Title;

            // Set some defaults
            finishPageInAddFinalHtmlMethod = false;

            // Handle basic events which may be fired by the internal header

            if (HttpContext.Current.Request.Form["internal_header_action"] != null)
            {
                // Pull the action value
                string internalHeaderAction = HttpContext.Current.Request.Form["internal_header_action"].Trim();

                // Was this to hide or show the header?
                if ((internalHeaderAction == "hide") || (internalHeaderAction == "show"))
                {
                    // Pull the current visibility from the session
                    bool shown = true;
                    if ((HttpContext.Current.Session["internal_header"] != null) && (HttpContext.Current.Session["internal_header"].ToString() == "hidden"))
                    {
                        shown = false;
                    }
                    if ((internalHeaderAction == "hide") && (shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "hidden";
                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL(), true);
                    }
                    if ((internalHeaderAction == "show") && (!shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "shown";
                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL(), true);
                    }
                }
            }
        }
Пример #13
0
        private static HTML_Based_Content Text_To_HTML_Based_Content(string Display_Text, bool Retain_Entire_Display_Text, string Source)
        {
            // Create the values to hold the information
            string code        = String.Empty;
            string title       = String.Empty;
            string author      = String.Empty;
            string description = String.Empty;
            string thumbnail   = String.Empty;
            string keyword     = String.Empty;
            string banner      = String.Empty;
            string date        = String.Empty;
            string sitemap     = String.Empty;
            string webskin     = String.Empty;

            // StringBuilder keeps track of any other information in the head that should be retained
            StringBuilder headBuilder = new StringBuilder();

            // Try to read the head using XML
            int  head_start  = Display_Text.IndexOf("<head>", StringComparison.OrdinalIgnoreCase);
            int  head_end    = Display_Text.IndexOf("</head>", StringComparison.OrdinalIgnoreCase);
            bool read_as_xml = false;

            if ((head_start >= 0) && (head_end > head_start))
            {
                try
                {
                    string        head_xml  = Display_Text.Substring(head_start, (head_end - head_start) + 7);
                    XmlTextReader xmlReader = new XmlTextReader(new StringReader(head_xml));
                    while (xmlReader.Read())
                    {
                        if (xmlReader.NodeType != XmlNodeType.Element)
                        {
                            continue;
                        }

                        switch (xmlReader.Name.ToUpper())
                        {
                        case "LINK":
                            headBuilder.Append("<link ");
                            int attributeCount = xmlReader.AttributeCount;
                            for (int i = 0; i < attributeCount; i++)
                            {
                                xmlReader.MoveToAttribute(i);
                                headBuilder.Append(xmlReader.Name + "=\"" + xmlReader.Value + "\" ");
                            }
                            headBuilder.AppendLine(" />");
                            break;

                        case "TITLE":
                            xmlReader.Read();
                            title = xmlReader.Value;
                            break;

                        case "CODE":
                            xmlReader.Read();
                            code = xmlReader.Value.ToLower();
                            break;

                        case "META":
                            string name_type    = String.Empty;
                            string content_type = String.Empty;
                            if (xmlReader.MoveToAttribute("name"))
                            {
                                name_type = xmlReader.Value;
                            }
                            if (xmlReader.MoveToAttribute("content"))
                            {
                                content_type = xmlReader.Value;
                            }
                            if ((name_type.Length > 0) && (content_type.Length > 0))
                            {
                                switch (name_type.ToUpper())
                                {
                                case "BANNER":
                                    banner = content_type;
                                    break;

                                case "TITLE":
                                    title = content_type;
                                    break;

                                case "THUMBNAIL":
                                    thumbnail = content_type;
                                    break;

                                case "AUTHOR":
                                    author = content_type;
                                    break;

                                case "DATE":
                                    date = content_type;
                                    break;

                                case "KEYWORDS":
                                    keyword = content_type;
                                    break;

                                case "DESCRIPTION":
                                    description = content_type;
                                    break;

                                case "CODE":
                                    code = content_type.ToLower();
                                    break;

                                case "SITEMAP":
                                    sitemap = content_type;
                                    break;

                                case "WEBSKIN":
                                    webskin = content_type;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    read_as_xml = true;
                }
                catch
                {
                    read_as_xml = false;
                }
            }

            // Read this the old way if unable to read via XML for some reason
            if (!read_as_xml)
            {
                // Get the title and code

                string header_info = Display_Text.Substring(0, Display_Text.IndexOf("<body>"));
                if (header_info.IndexOf("<title>") > 0)
                {
                    string possible_title = header_info.Substring(header_info.IndexOf("<title>"));
                    possible_title = possible_title.Substring(7, possible_title.IndexOf("</title>") - 7);
                    title          = possible_title.Trim();
                }
                if (header_info.IndexOf("<code>") > 0)
                {
                    string possible_code = header_info.Substring(header_info.IndexOf("<code>"));
                    possible_code = possible_code.Substring(6, possible_code.IndexOf("</code>") - 6);
                    code          = possible_code.Trim();
                }

                // See if the banner should be displayed (default is only option righht now)
                if (Display_Text.IndexOf("<meta name=\"banner\" content=\"default\"") > 0)
                {
                    banner = "default";
                }
            }

            // Create return value
            HTML_Based_Content returnValue = new HTML_Based_Content {
                Code = code, Title = title
            };

            if (author.Length > 0)
            {
                returnValue.Author = author;
            }
            if (banner.Length > 0)
            {
                returnValue.Banner = banner;
            }
            if (date.Length > 0)
            {
                returnValue.Date = date;
            }
            if (description.Length > 0)
            {
                returnValue.Description = description;
            }
            if (keyword.Length > 0)
            {
                returnValue.Keywords = keyword;
            }
            if (thumbnail.Length > 0)
            {
                returnValue.Thumbnail = thumbnail;
            }
            if (sitemap.Length > 0)
            {
                returnValue.SiteMap = sitemap;
            }
            if (webskin.Length > 0)
            {
                returnValue.Web_Skin = webskin;
            }
            if (headBuilder.Length > 0)
            {
                returnValue.Extra_Head_Info = headBuilder.ToString();
            }

            // Should the actual display text be retained?
            if (Retain_Entire_Display_Text)
            {
                int start_body = Display_Text.IndexOf("<body>") + 6;
                int end_body   = Display_Text.IndexOf("</body>");
                if ((start_body > 0) && (end_body > start_body))
                {
                    returnValue.Static_Text = Display_Text.Substring(start_body, end_body - start_body) + " ";

                    if ((Source.Length > 0) && (returnValue.Static_Text.IndexOf("<%LASTMODIFIED%>") > 0))
                    {
                        FileInfo fileInfo    = new FileInfo(Source);
                        DateTime lastWritten = fileInfo.LastWriteTime;
                        returnValue.Static_Text = returnValue.Static_Text.Replace("<%LASTMODIFIED%>", lastWritten.ToLongDateString());
                    }
                }
            }

            return(returnValue);
        }
        private void Save_Page_7_Postback(NameValueCollection Form)
        {
            string action = Form["admin_aggr_action"];
            if (!String.IsNullOrEmpty(action))
            {
                if ((action.IndexOf("delete_") == 0) && ( action.Length > 7 ))
                {
                    string code_to_delete = action.Substring(7);
                    itemAggregation.Remove_Child_Page(code_to_delete);

                    // Save to the admins session
                    HttpContext.Current.Session["Edit_Aggregation_" + itemAggregation.Code] = itemAggregation;
                }

                if (action == "save_childpage")
                {
                    childPageCode = Form["admin_aggr_code"];
                    childPageLabel = Form["admin_aggr_label"];
                    childPageVisibility = Form["admin_aggr_visibility"];
                    childPageParent = Form["admin_aggr_parent"];

                    // Convert to the integer id for the parent and begin to do checking
                    List<string> errors = new List<string>();

                    // Validate the code
                    if (childPageCode.Length > 20)
                    {
                        errors.Add("New child page code must be twenty characters long or less");
                    }
                    else if (childPageCode.Length == 0)
                    {
                        errors.Add("You must enter a CODE for this child page");

                    }
                    else if (SobekCM_Library_Settings.Reserved_Keywords.Contains(childPageCode.ToLower()))
                    {
                        errors.Add("That code is a system-reserved keyword.  Try a different code.");
                    }
                    else if (itemAggregation.Child_Page_By_Code(childPageCode.ToUpper()) != null)
                    {
                        errors.Add("New code must be unique... <i>" + childPageCode + "</i> already exists");
                    }

                    if (childPageLabel.Trim().Length == 0)
                        errors.Add("You must enter a LABEL for this child page");
                    if (childPageVisibility.Trim().Length == 0)
                        errors.Add("You must select a VISIBILITY for this child page");

                    if (errors.Count > 0)
                    {
                        // Create the error message
                        actionMessage = "ERROR: Invalid entry for new item child page<br />";
                        foreach (string error in errors)
                            actionMessage = actionMessage + "<br />" + error;
                    }
                    else
                    {
                        Item_Aggregation_Child_Page newPage = new Item_Aggregation_Child_Page {Code = childPageCode, Parent_Code = childPageParent, Source = Item_Aggregation_Child_Page.Source_Type.Static_HTML };
                        newPage.Add_Label(childPageLabel, SobekCM_Library_Settings.Default_UI_Language);
                        switch (childPageVisibility)
                        {
                            case "none":
                                newPage.Browse_Type = Item_Aggregation_Child_Page.Visibility_Type.NONE;
                                break;

                            case "browse":
                                newPage.Browse_Type = Item_Aggregation_Child_Page.Visibility_Type.MAIN_MENU;
                                break;

                            case "browseby":
                                newPage.Browse_Type = Item_Aggregation_Child_Page.Visibility_Type.METADATA_BROWSE_BY;
                                break;
                        }
                        string html_source_dir = aggregationDirectory + "\\html\\browse";
                        if (!Directory.Exists(html_source_dir))
                            Directory.CreateDirectory(html_source_dir);
                        string html_source_file = html_source_dir + "\\" + childPageCode + "_" + Web_Language_Enum_Converter.Enum_To_Code(SobekCM_Library_Settings.Default_UI_Language) + ".html";
                        if (!File.Exists(html_source_file))
                        {
                            HTML_Based_Content htmlContent = new HTML_Based_Content();
                            htmlContent.Static_Text = "<br /><br />This is a new browse page.<br /><br />" + childPageLabel + "<br /><br />The code for this browse is: " + childPageCode;
                            htmlContent.Author = user.Full_Name;
                            htmlContent.Date = DateTime.Now.ToLongDateString();
                            htmlContent.Title = childPageLabel;
                            htmlContent.Save_To_File(html_source_file);
                        }
                        newPage.Add_Static_HTML_Source("html\\browse\\" + childPageCode + "_" + Web_Language_Enum_Converter.Enum_To_Code(SobekCM_Library_Settings.Default_UI_Language) + ".html", SobekCM_Library_Settings.Default_UI_Language);

                        itemAggregation.Add_Child_Page(newPage);

                        // Save to the admins session
                        HttpContext.Current.Session["Edit_Aggregation_" + itemAggregation.Code] = itemAggregation;

                    }
                }
            }
        }
        private void Save_Child_Page_Postback(NameValueCollection Form)
        {
            string code = currentMode.My_Sobek_SubMode.Substring(2);
            Item_Aggregation_Child_Page childPage = itemAggregation.Child_Page_By_Code(code);

            // Check for action flag
            string action = Form["admin_aggr_action"];
            if (action == "add_version")
            {
                try
                {
                    string language = Form["admin_aggr_new_version_lang"];
                    string title = Form["admin_aggr_new_version_label"];
                    string copyFrom = Form["admin_aggr_new_version_copy"];

                    string file = "html\\browse\\" + childPage.Code + "_" + language + ".html";
                    string fileDir = aggregationDirectory + "\\" + file;
                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(language);

                    // Create the source file FIRST
                    string copyFromFull = aggregationDirectory + "\\" + copyFrom;
                    if ((copyFrom.Length > 0) && (File.Exists(copyFromFull)))
                    {
                        File.Copy(copyFromFull, fileDir, true );
                    }
                    else if ( !File.Exists(fileDir))
                    {
                        HTML_Based_Content htmlContent = new HTML_Based_Content();
                        htmlContent.Static_Text = "<br /><br />This is a new " + Web_Language_Enum_Converter.Enum_To_Name(languageEnum) + " browse page.<br /><br />" + title + "<br /><br />The code for this browse is: " + childPage.Code;
                        htmlContent.Author = user.Full_Name;
                        htmlContent.Date = DateTime.Now.ToLongDateString();
                        htmlContent.Title = title;
                        htmlContent.Save_To_File(fileDir);
                    }

                    // Add to this child page
                    childPage.Add_Label(title, languageEnum);
                    childPage.Add_Static_HTML_Source(file, languageEnum);

                }
                catch
                {
                    actionMessage = "Error adding new version to this child page";
                }

            }
            else if ((action.IndexOf("delete_") == 0) && ( action.Length > 7 ))
            {
                string delete_code = action.Substring(7);
                childPage.Remove_Language(Web_Language_Enum_Converter.Code_To_Enum(delete_code));

            }
        }