/// <summary> Compares the collection view type and the search type from the current http request </summary>
        /// <param name="searchType1"> Search type from the list of collection views and searches </param>
        /// <param name="searchType2"> Search type from the current http request </param>
        /// <returns> TRUE if they are analagous, otherwise FALSE </returns>
        public static bool Do_Search_Types_Match(Item_Aggregation.CollectionViewsAndSearchesEnum searchType1, Search_Type_Enum searchType2)
        {
            switch (searchType1)
            {
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search:
                    return searchType2 == Search_Type_Enum.Advanced;

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search:
                    return searchType2 == Search_Type_Enum.Basic;

                case Item_Aggregation.CollectionViewsAndSearchesEnum.FullText_Search:
                    return searchType2 == Search_Type_Enum.Full_Text;

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Search:
                    return searchType2 == Search_Type_Enum.Map;

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Newspaper_Search:
                    return searchType2 == Search_Type_Enum.Newspaper;

                case Item_Aggregation.CollectionViewsAndSearchesEnum.dLOC_FullText_Search:
                    return searchType2 == Search_Type_Enum.dLOC_Full_Text;

                default:
                    return false;
            }
        }
        /// <summary> Returns a built collection viewer matching request </summary>
        /// <param name="SearchType"> Type of search from the current http request </param>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request </param>
        /// <param name="Current_User"> Currently logged on user, if there is one </param>
        /// <returns> Collection viewer that extends the <see cref="abstractAggregationViewer"/> class. </returns>
        public static abstractAggregationViewer Get_Viewer(Search_Type_Enum SearchType, Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode, User_Object Current_User)
        {
            switch (SearchType)
            {
                case Search_Type_Enum.Advanced:
                    return new Advanced_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Basic:
                    if ((Current_Aggregation.Front_Banner_Image(Current_Mode.Language ).Length > 0) && (Current_Aggregation.Highlights.Count > 0))
                    {
                        return new Rotating_Highlight_Search_AggregationViewer(Current_Aggregation, Current_Mode);
                    }
                    return new Basic_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Full_Text:
                    return new Full_Text_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Newspaper:
                    return new Newspaper_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Map:
                    return new Map_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.dLOC_Full_Text:
                    return new dLOC_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                default:
                    return null;
            }
        }
        /// <summary> Returns the HTML for one element within tab which appears over the search box in the collection view </summary>
        /// <param name="ThisView"> Collection view type for this tab </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request, to see if the tab is currently selected or not and determine current skin language </param>
        /// <param name="Translations"> Language support object for writing the name of the view in the appropriate interface language </param>
        /// <returns> HTML to display the tab, including the link if it is not currently selected </returns>
        public static string Menu_Get_Nav_Bar_HTML(Item_Aggregation.CollectionViewsAndSearchesEnum ThisView, SobekCM_Navigation_Object Current_Mode, Language_Support_Info Translations )
        {
            string skinCode = Current_Mode.Base_Skin;

            switch (ThisView)
            {
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search:
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search_YearRange:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Advanced, Translations.Get_Translation("ADVANCED SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search:
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search_YearRange:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Basic, Translations.Get_Translation("BASIC SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Search:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Map, Translations.Get_Translation("MAP SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Search_Beta:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Map_Beta, Translations.Get_Translation("MAP SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Newspaper_Search:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Newspaper, Translations.Get_Translation("NEWSPAPER SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Admin_View:
                    return String.Empty; // HTML_Helper(Skin_Code, SobekCM.Library.Navigation.Search_Type_Enum.Admin_View, Translations.Get_Translation("ADMIN", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.DLOC_FullText_Search:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.dLOC_Full_Text, Translations.Get_Translation("TEXT SEARCH", Current_Mode.Language), Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.FullText_Search:
                    return Menu_HTML_Helper(skinCode, Search_Type_Enum.Full_Text, Translations.Get_Translation("TEXT SEARCH", Current_Mode.Language), Current_Mode);
            }

            return String.Empty;
        }
        /// <summary> Returns a built collection viewer matching request </summary>
        /// <param name="ViewType"> Aggregation view type </param>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request </param>
        /// <returns> Collection viewer that extends the <see cref="abstractAggregationViewer"/> class. </returns>
        public static abstractAggregationViewer Get_Viewer(Item_Aggregation.CollectionViewsAndSearchesEnum ViewType, Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode )
        {
            switch (ViewType)
            {
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search:
                    return new Advanced_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search:
                    string frontBannerImage = Current_Aggregation.Front_Banner_Image(Current_Mode.Language);
                    if ((frontBannerImage.Length > 0) && (Current_Aggregation.Highlights.Count > 0))
                    {
                        return new Rotating_Highlight_Search_AggregationViewer(Current_Aggregation, Current_Mode);
                    }
                    return new Basic_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.FullText_Search:
                    return new Full_Text_Search_AggregationViewer(Current_Aggregation, Current_Mode );

                case Item_Aggregation.CollectionViewsAndSearchesEnum.No_Home_Search:
                    return new No_Search_AggregationViewer();

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Newspaper_Search:
                    return new Newspaper_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Search:
                    return new Map_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.dLOC_FullText_Search:
                    return new dLOC_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                default:
                    return null;
            }
        }
        /// <summary> Returns the HTML for one tab which appears over the search box in the collection view </summary>
        /// <param name="thisView"> Collection view type for this tab </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request, to see if the tab is currently selected or not and determine current skin language </param>
        /// <param name="Translations"> Language support object for writing the name of the view in the appropriate interface language </param>
        /// <param name="Downward_Tabs"> Flag indicates if this tab faces downward, rather than the default upward </param>
        /// <returns> HTML to display the tab, including the link if it is not currently selected </returns>
        public static string Get_Nav_Bar_HTML( Item_Aggregation.CollectionViewsAndSearchesEnum thisView, SobekCM_Navigation_Object Current_Mode, Language_Support_Info Translations, bool Downward_Tabs )
        {
            string skinCode = Current_Mode.Base_Skin;

            switch (thisView)
            {
                case Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search:
                    if (Current_Mode.Is_Robot)
                    {
                        return "<img src=\"" + Current_Mode.Base_URL + "design/skins/" + skinCode + "/tabs/cL.gif\" border=\"0\" class=\"tab_image\" alt=\"\" /><span class=\"tab\"> ADVANCED SEARCH </span><img src=\"" + Current_Mode.Base_URL + "design/skins/" + skinCode + "/tabs/cR.gif\" border=\"0\" class=\"tab_image\" alt=\"\" />" + Environment.NewLine ;
                    }
                    return HTML_Helper(skinCode, Search_Type_Enum.Advanced, Translations.Get_Translation("ADVANCED SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Basic_Search:
                    return HTML_Helper(skinCode, Search_Type_Enum.Basic, Translations.Get_Translation("BASIC SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Map_Search:
                    return HTML_Helper(skinCode, Search_Type_Enum.Map, Translations.Get_Translation("MAP SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Newspaper_Search:
                    return HTML_Helper(skinCode, Search_Type_Enum.Newspaper, Translations.Get_Translation("NEWSPAPER SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.Admin_View:
                    return String.Empty; // HTML_Helper(Skin_Code, SobekCM.Library.Navigation.Search_Type_Enum.Admin_View, Translations.Get_Translation("ADMIN", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.dLOC_FullText_Search:
                    return HTML_Helper(skinCode, Search_Type_Enum.dLOC_Full_Text, Translations.Get_Translation("TEXT SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);

                case Item_Aggregation.CollectionViewsAndSearchesEnum.FullText_Search:
                    return HTML_Helper(skinCode, Search_Type_Enum.Full_Text, Translations.Get_Translation("TEXT SEARCH", Current_Mode.Language), Current_Mode, Downward_Tabs);
            }

            return String.Empty;
        }
        /// <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 dLOC_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public dLOC_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            textBoxValue = String.Empty;
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String.Replace(",newspaper", "");
            }

            // Determine the complete script action name
            Display_Mode_Enum displayMode = currentMode.Mode;
            Aggregation_Type_Enum aggrType = currentMode.Aggregation_Type;
            Search_Type_Enum searchType = currentMode.Search_Type;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Type = Search_Type_Enum.Full_Text;
            string search_string = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            arg2 = String.Empty;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            arg1 = currentMode.Redirect_URL();
            currentMode.Mode = Display_Mode_Enum.Aggregation;
            currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();

            scriptActionName = "dloc_search_sobekcm('" + arg1 + "', '" + browse_url + "');";

            currentMode.Mode = displayMode;
            currentMode.Aggregation_Type = aggrType;
            currentMode.Search_Type = searchType;
            currentMode.Search_String = search_string;
            currentMode.Info_Browse_Mode = String.Empty;
        }
        /// <summary> Constructor for a new instance of the Advanced_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Advanced_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            // Compute the redirect stem to use
            string fields = currentMode.Search_Fields;
            string searchCollections = currentMode.SubAggregation;
            Display_Mode_Enum lastMode = currentMode.Mode;
            currentMode.SubAggregation = String.Empty;
            string searchString = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            string redirectStem = currentMode.Redirect_URL();
            currentMode.Search_String = searchString;
            currentMode.Search_Fields = fields;
            currentMode.SubAggregation = searchCollections;
            currentMode.Mode = lastMode;

            // If there are children under this hierarchy that can be selected
            //script_action_name = "Javascript:advanced_select_search_sobekcm('" + redirect_stem + "', '" + sub_code + "')";
            //script_include_name = "<script src=\"" + currentMode.Base_URL + "default/scripts/sobekcm_search.js\" type=\"text/javascript\"></script>";

            scriptActionName = "Javascript:advanced_search_sobekcm('" + redirectStem + "')";
            scriptIncludeName = "<script src=\"" + currentMode.Base_URL + "default/scripts/sobekcm_search.js\" type=\"text/javascript\"></script>";
        }
        /// <summary> Reads the item aggregation configuration file and populates the new data into the
        /// item aggregation object </summary>
        /// <param name="HierarchyObject"> Item aggregation object to populate</param>
        /// <param name="FileLocation"> Full name of the item aggregation configuration XML file </param>
        public void Add_Info_From_XML_File(Item_Aggregation HierarchyObject, string FileLocation )
        {
            // Get the directory from the file location
            string directory = (new FileInfo(FileLocation)).DirectoryName;

            // Load this XML file
            XmlDocument hierarchyXml = new XmlDocument();
            hierarchyXml.Load(FileLocation);

            // create the node reader
            XmlNodeReader nodeReader = new XmlNodeReader(hierarchyXml);

            // Read all the nodes
            while (nodeReader.Read())
            {
                // If this is the beginning tag for an element, assign the next values accordingly
                if (nodeReader.NodeType == XmlNodeType.Element)
                {
                    // Get the node name, trimmed and to upper
                    string nodeName = nodeReader.Name.Trim().ToUpper();

                    // switch the rest based on the tag name
                    switch (nodeName)
                    {
                        case "HI:SETTINGS":
                            read_settings(nodeReader, HierarchyObject);
                            break;

                        case "HI:HOME":
                            read_home(nodeReader, HierarchyObject);
                            break;

                        case "HI:BANNER":
                            read_banners(nodeReader, HierarchyObject);
                            break;

                        case "HI:DIRECTIVES":
                            read_directives(nodeReader, HierarchyObject, directory);
                            break;

                        case "HI:HIGHLIGHTS":
                            read_highlights(nodeReader, HierarchyObject);
                            break;

                        case "HI:BROWSE":
                            read_browse(true, nodeReader, HierarchyObject);
                            break;

                        case "HI:INFO":
                            read_browse(false, nodeReader, HierarchyObject);
                            break;

                        case "HI:RESULTS":
                            read_results_specs(nodeReader, HierarchyObject);
                            break;
                    }
                }
            }
        }
 /// <summary> Constructor for a new instance of the Xml_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>
 public Xml_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)
     : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object, Current_Item, Current_Page, null)
 {
 }
 /// <summary> Constructor for a new instance of the Dataset_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>
 public Dataset_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)
     : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,  Current_Item, Current_Page, null)
 {
     // All work done in base class
 }
 /// <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_Browse_Info 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
 }
        private static void read_banners(XmlNodeReader nodeReader, Item_Aggregation hierarchyObject )
        {
            while (nodeReader.Read())
            {
                // If this is the beginning tag for an element, assign the next values accordingly
                if (nodeReader.NodeType == XmlNodeType.Element)
                {
                    // Get the node name, trimmed and to upper
                    string nodeName = nodeReader.Name.Trim().ToUpper();

                    // switch the rest based on the tag name
                    switch (nodeName)
                    {
                        case "HI:SOURCE":
                            // Check for any attributes to this banner node
                            string lang = String.Empty;
                            bool special = false;

                            if (nodeReader.HasAttributes)
                            {

                                if (nodeReader.MoveToAttribute("lang"))
                                {
                                    lang = nodeReader.Value.Trim().ToUpper();
                                }
                                if (nodeReader.MoveToAttribute("type"))
                                {
                                    if (nodeReader.Value.Trim().ToUpper() == "HIGHLIGHT")
                                        special = true;
                                }
                            }

                            // Now read the banner information and add to the aggregation object
                            nodeReader.Read();
                            if (special)
                            {
                                hierarchyObject.Add_Front_Banner_Image(nodeReader.Value, Web_Language_Enum_Converter.Code_To_Enum( lang));
                            }
                            else
                            {
                                hierarchyObject.Add_Banner_Image(nodeReader.Value, Web_Language_Enum_Converter.Code_To_Enum(lang));
                            }

                            break;
                    }
                }

                if ((nodeReader.NodeType == XmlNodeType.EndElement) && (nodeReader.Name.Trim().ToUpper() == "HI:BANNER"))
                {
                    return;
                }
            }
        }
 /// <summary> Constructor for a new instance of the Json_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="All_Items_Lookup"> Lookup object used to pull basic information about any item loaded into this library </param>
 /// <param name="Current_Image_Root"> Current root directory to pull images and metadata for digital resources </param>
 public Json_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,
     Item_Lookup_Object All_Items_Lookup,
     string Current_Image_Root)
     : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,   Current_Item, Current_Page, null)
 {
     allItems = All_Items_Lookup;
     currentGreenstoneImageRoot = Current_Image_Root;
 }
        /// <summary> Constructor for a new instance of the Basic_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Rotating_Highlight_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            // Determine the sub text to use
            const string SUB_CODE = "s=";
            Sharing_Buttons_HTML = String.Empty;

            // Save the search term
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String;
            }

            // Determine the complete script action name
            Display_Mode_Enum displayMode = currentMode.Mode;
            Aggregation_Type_Enum aggrType = currentMode.Aggregation_Type;
            Search_Type_Enum searchType = currentMode.Search_Type;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Type = Search_Type_Enum.Basic;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            string search_string = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            arg2 = String.Empty;
            arg1 = currentMode.Redirect_URL();
            currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();
            currentMode.Info_Browse_Mode = String.Empty;
            currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
            if ((!currentMode.Show_Selection_Panel) || (Current_Aggregation.Children_Count == 0))
            {
                scriptActionName = "basic_search_sobekcm('" + arg1 + "', '" + browse_url + "')";
             }
            else
            {
                scriptActionName = "basic_select_search_sobekcm('" + arg1 + "', '" + SUB_CODE + "')";
                arg2 = SUB_CODE;
             }
            currentMode.Mode = displayMode;
            currentMode.Aggregation_Type = aggrType;
            currentMode.Search_Type = searchType;
            currentMode.Search_String = search_string;

            // Get the front banner
            frontBannerInfo = Current_Aggregation.Front_Banner_Image(currentMode.Language);
        }
        /// <summary> Constructor for a new instance of the Newspaper_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Newspaper_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            // Determine the sub text to use
            const string SUB_CODE = "s=";

            // Save the search term
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String;
            }

            // Compute the redirect stem to use
            string fields = currentMode.Search_Fields;
            string search_string = currentMode.Search_String;
            Aggregation_Type_Enum aggrType = currentMode.Aggregation_Type;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            currentMode.Home_Type = Home_Type_Enum.List;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            string redirect_stem = currentMode.Redirect_URL().Replace("&m=hhh", "").Replace("m=hht", "").Replace("&m=lhh", "").Replace("m=lht", "");
            currentMode.Mode = Display_Mode_Enum.Aggregation;
            currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();
            currentMode.Search_String = search_string;
            currentMode.Search_Fields = fields;
            currentMode.Aggregation_Type = aggrType;
            currentMode.Info_Browse_Mode = String.Empty;

            // Write the advanced search box
            arg2 = String.Empty;
            arg1 = redirect_stem;

            if ((Current_Aggregation.Children_Count > 0) && (currentMode.Show_Selection_Panel))
            {
                scriptActionName = "newspaper_select_search_sobekcm('" + arg1 + "', '" + SUB_CODE + "', '" + browse_url + "');";
                arg2 = SUB_CODE;
            }
            else
            {
                scriptActionName = "newspaper_search_sobekcm('" + arg1 + "');";
            }
        }
 /// <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 Basic_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Rotating_Highlight_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            // Determine the sub text to use
            const string subCode = "s=";
            Sharing_Buttons_HTML = String.Empty;

            // Save the search term
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String;
            }

            // Determine the complete script action name
            Display_Mode_Enum displayMode = currentMode.Mode;
            Search_Type_Enum searchType = currentMode.Search_Type;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Type = Search_Type_Enum.Basic;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            string search_string = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            arg2 = String.Empty;
            arg1 = currentMode.Redirect_URL();
            currentMode.Mode = Display_Mode_Enum.Aggregation_Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();
            currentMode.Info_Browse_Mode = String.Empty;
            currentMode.Mode = Display_Mode_Enum.Aggregation_Home;
            if ((!currentMode.Show_Selection_Panel) || (Current_Aggregation.Children_Count == 0))
            {
                scriptActionName = "basic_search_sobekcm('" + arg1 + "', '" + browse_url + "')";
                scriptIncludeName = "<script src=\"" + currentMode.Base_URL + "default/scripts/sobekcm_search.js\" type=\"text/javascript\"></script>";
            }
            else
            {
                scriptActionName = "basic_select_search_sobekcm('" + arg1 + "', '" + subCode + "')";
                arg2 = subCode;
                scriptIncludeName = "<script src=\"" + currentMode.Base_URL + "default/scripts/sobekcm_search.js\" type=\"text/javascript\"></script>";
            }
            currentMode.Mode = displayMode;
            currentMode.Search_Type = searchType;
            currentMode.Search_String = search_string;
        }
        /// <summary> Constructor for a new instance of the Full_Text_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Full_Text_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            // Determine the sub text to use
            const string SUB_CODE = "s=";

            // Save the search term
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String;
            }

            // Determine the complete script action name
            Display_Mode_Enum displayMode = currentMode.Mode;
            Search_Type_Enum searchType = currentMode.Search_Type;
            Aggregation_Type_Enum aggrType = currentMode.Aggregation_Type;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Type = Search_Type_Enum.Full_Text;
            string search_string = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            arg2 = String.Empty;
            arg1 = currentMode.Redirect_URL();
            currentMode.Mode = Display_Mode_Enum.Aggregation;
            currentMode.Aggregation_Type = Aggregation_Type_Enum.Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();
            currentMode.Mode = Display_Mode_Enum.Search;
            if ((!currentMode.Show_Selection_Panel) || (Current_Aggregation.Children_Count == 0))
            {
                scriptActionName = "fulltext_search_sobekcm('" + arg1 + "', '" + browse_url + "');";
            }
            else
            {
                scriptActionName = "fulltext_select_search_sobekcm('" + arg1 + "', '" + SUB_CODE + "')";
                arg2 = SUB_CODE;
            }
            currentMode.Mode = displayMode;
            currentMode.Aggregation_Type = aggrType;
            currentMode.Search_Type = searchType;
            currentMode.Search_String = search_string;
            currentMode.Info_Browse_Mode = String.Empty;
        }
        /// <summary> Constructor for a new instance of the Metadata_Browse_AggregationViewer class </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Aggregation"> Current item aggregation object to display </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Metadata_Browse_AggregationViewer(SobekCM_Navigation_Object Current_Mode, Item_Aggregation Current_Aggregation, Custom_Tracer Tracer)
            : base(Current_Aggregation, Current_Mode)
        {
            string defaultBrowseBy = Current_Aggregation.Default_BrowseBy;

            // If there is not info browse mode listed, use the default
            if (Current_Mode.Info_Browse_Mode.Length == 0)
                Current_Mode.Info_Browse_Mode = defaultBrowseBy;
            if ((Current_Mode.Info_Browse_Mode.Length == 0) && (Current_Aggregation.Has_Browse_By_Pages))
                Current_Mode.Info_Browse_Mode = Current_Aggregation.Browse_By_Pages(Current_Mode.Language)[0].Code;

            // Get this browse
            browseObject = Current_Aggregation.Get_Browse_Info_Object(Current_Mode.Info_Browse_Mode);

            // Was this a metadata browseby, or just a static html?
            if (( browseObject == null ) || ( browseObject.Source != Item_Aggregation_Browse_Info.Source_Type.Static_HTML))
            {
                // Determine the correct metadata code
                string metadata_code = Current_Mode.Info_Browse_Mode.Trim().Replace("_", " ");
                Current_Mode.Info_Browse_Mode = metadata_code;

                // Only get values if there was a metadata code
                if (metadata_code.Length > 0)
                {
                    // Check the cache for this value
                    List<string> cacheInstance = Cached_Data_Manager.Retrieve_Aggregation_Metadata_Browse(Current_Mode.Aggregation, Current_Mode.Info_Browse_Mode, Tracer);

                    if (cacheInstance != null)
                    {
                        results = cacheInstance;
                    }
                    else
                    {
                        results = SobekCM_Database.Get_Item_Aggregation_Metadata_Browse(Current_Mode.Aggregation, Current_Mode.Info_Browse_Mode, Tracer);
                        Cached_Data_Manager.Store_Aggregation_Metadata_Browse(Current_Mode.Aggregation, Current_Mode.Info_Browse_Mode, results, Tracer);
                    }
                }
            }
        }
 /// <summary> Constructor for a new instance of the Advanced_Search_AggregationViewer class </summary>
 /// <param name="Current_Aggregation"> Current item aggregation object </param>
 /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
 public Advanced_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
     : base(Current_Aggregation, Current_Mode)
 {
     // Compute the redirect stem to use
     string fields = currentMode.Search_Fields;
     string searchCollections = currentMode.SubAggregation;
     Display_Mode_Enum lastMode = currentMode.Mode;
     Aggregation_Type_Enum aggrType = currentMode.Aggregation_Type;
     currentMode.SubAggregation = String.Empty;
     string searchString = currentMode.Search_String;
     currentMode.Search_String = String.Empty;
     currentMode.Search_Fields = String.Empty;
     currentMode.Mode = Display_Mode_Enum.Results;
     currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
     string redirectStem = currentMode.Redirect_URL();
     currentMode.Search_String = searchString;
     currentMode.Search_Fields = fields;
     currentMode.SubAggregation = searchCollections;
     currentMode.Mode = lastMode;
     currentMode.Aggregation_Type = aggrType;
     scriptActionName = "advanced_search_sobekcm('" + redirectStem + "')";
 }
        /// <summary> Constructor for a new instance of the dLOC_Search_AggregationViewer class </summary>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public dLOC_Search_AggregationViewer(Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode)
            : base(Current_Aggregation, Current_Mode)
        {
            textBoxValue = String.Empty;
            if (currentMode.Search_String.Length > 0)
            {
                textBoxValue = currentMode.Search_String.Replace(",newspaper", "");
            }

            // Determine the complete script action name
            Display_Mode_Enum displayMode = currentMode.Mode;
            Search_Type_Enum searchType = currentMode.Search_Type;
            currentMode.Mode = Display_Mode_Enum.Results;
            currentMode.Search_Type = Search_Type_Enum.Full_Text;
            string search_string = currentMode.Search_String;
            currentMode.Search_String = String.Empty;
            currentMode.Search_Fields = String.Empty;
            arg2 = String.Empty;
            currentMode.Search_Precision = Search_Precision_Type_Enum.Inflectional_Form;
            arg1 = currentMode.Redirect_URL();
            currentMode.Mode = Display_Mode_Enum.Aggregation_Browse_Info;
            currentMode.Info_Browse_Mode = "all";
            browse_url = currentMode.Redirect_URL();

            //if (( !currentMode.Show_Selection_Panel) || ( hierarchyObject.Codes.Length == 0 ))
            //{
            scriptActionName = "dloc_search_sobekcm('" + arg1 + "', '" + browse_url + "');";
            scriptIncludeName = "<script src=\"" + currentMode.Base_URL + "default/scripts/sobekcm_search.js\" type=\"text/javascript\"></script>";
            //}
            //else
            //{
            //    script_action_name = "Javascript:dloc_select_search_sobekcm('" + currentMode.Redirect_URL() + "', '" + sub_code + "')";
            //    script_include_name = "<script src=\"" + currentMode.Base_URL + "default/scripts/dloc_select_search_sobekcm.js\" type=\"text/javascript\"></script>";
            //}
            currentMode.Mode = displayMode;
            currentMode.Search_Type = searchType;
            currentMode.Search_String = search_string;
            currentMode.Info_Browse_Mode = String.Empty;
        }
        /// <summary> Returns a built collection viewer matching request </summary>
        /// <param name="SearchType"> Type of search from the current http request </param>
        /// <param name="Current_Aggregation"> Current item aggregation object </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request </param>
        /// <param name="Current_User"> Currently logged on user, if there is one </param>
        /// <returns> Collection viewer that extends the <see cref="abstractAggregationViewer"/> class. </returns>
        public static abstractAggregationViewer Get_Viewer(Search_Type_Enum SearchType, Item_Aggregation Current_Aggregation, SobekCM_Navigation_Object Current_Mode, User_Object Current_User)
        {
            switch (SearchType)
            {
                case Search_Type_Enum.Advanced:
                    if ( Current_Aggregation.Views_And_Searches.Contains(Item_Aggregation.CollectionViewsAndSearchesEnum.Advanced_Search_YearRange))
                        return new Advanced_Search_YearRange_AggregationViewer(Current_Aggregation, Current_Mode);
                    return new Advanced_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Basic:
                    Item_Aggregation_Front_Banner frontBannerImage = Current_Aggregation.Front_Banner_Image(Current_Mode.Language);
                    if ((frontBannerImage != null ) && (Current_Aggregation.Highlights.Count > 0))
                    {
                        return new Rotating_Highlight_Search_AggregationViewer(Current_Aggregation, Current_Mode);
                    }
                    return new Basic_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Full_Text:
                    return new Full_Text_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Newspaper:
                    return new Newspaper_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Map:
                    return new Map_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.Map_Beta:
                    return new Map_Search_AggregationViewer_Beta(Current_Aggregation, Current_Mode);

                case Search_Type_Enum.dLOC_Full_Text:
                    return new dLOC_Search_AggregationViewer(Current_Aggregation, Current_Mode);

                default:
                    return null;
            }
        }
 /// <summary> Constructor for a new instance of the Private_Items_AggregationViewer class </summary>
 /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
 /// <param name="Current_Aggregation"> Current item aggregation object to display </param>
 /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
 public Private_Items_AggregationViewer(SobekCM_Navigation_Object Current_Mode, Item_Aggregation Current_Aggregation, Custom_Tracer Tracer)
     : base(Current_Aggregation, Current_Mode)
 {
     privateItems = SobekCM_Database.Tracking_Get_Aggregation_Private_Items(currentCollection.Code, (int) RESULTS_PER_PAGE, currentMode.Page, currentMode.Sort, Tracer);
 }
        /// <summary> Adds the ALL ITEMS and NEW ITEMS browses to the item aggregation, if the display options and last added
        /// item date call for it </summary>
        /// <param name="ThisObject"> Item aggregation to which to add the ALL ITEMS and NEW ITEMS browse</param>
        /// <remarks>This method is always called while building an item aggregation, irregardless of whether there is an
        /// item aggregation configuration XML file or not.</remarks>
        protected static void Add_All_New_Browses(Item_Aggregation ThisObject)
        {
            // If this is the main home page for this site, do not show ALL since we cannot browse ALL items
            if (!ThisObject.Can_Browse_Items )
                return;

            // If this is in the display options, and the item browses
            if ((ThisObject.Display_Options.Length == 0) || (ThisObject.Display_Options.IndexOf("I") >= 0))
            {
                // Add the ALL browse, if there should be one
                ThisObject.Add_Child_Page(Item_Aggregation_Child_Page.Visibility_Type.MAIN_MENU, "all", String.Empty, "All Items");

                // Add the NEW search, if the ALL search exists
                if ((ThisObject.Get_Browse_Info_Object("all") != null) && (ThisObject.Show_New_Item_Browse))
                {
                    ThisObject.Add_Child_Page(Item_Aggregation_Child_Page.Visibility_Type.MAIN_MENU, "new", String.Empty, "Recently Added Items");
                }
            }
            else
            {
                // Add the ALL browse as an info
                ThisObject.Add_Child_Page(Item_Aggregation_Child_Page.Visibility_Type.NONE, "all", String.Empty, "All Items");
            }
        }
        /// <summary> Stores the item aggregation object to the cache or caching server </summary>
        /// <param name="Aggregation_Code"> Code for the item aggregation to store </param>
        /// <param name="Language_Code"> Current language code (item aggregation instances are currently language-specific)</param>
        /// <param name="StoreObject"> Item aggregation object to store for later retrieval </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        public static void Store_Item_Aggregation(string Aggregation_Code, string Language_Code, Item_Aggregation StoreObject, Custom_Tracer Tracer)
        {
            // If the cache is disabled, just return before even tracing
            if (Disabled)
                return;

            // Determine the key
            string key = "AGGR_" + Aggregation_Code;
            if ((Language_Code.Length > 0) && (Language_Code != "en"))
                key = key + "_" + Language_Code;

            // Check the number of item aggregations currently locally cached
            int items_cached = 0;
            int local_expiration = 15;
            if (Aggregation_Code != "all")
            {
                local_expiration = 1;
                if ((LOCALLY_CACHED_AGGREGATION_LIMIT > 0) && ( caching_serving_enabled ))
                {
                    items_cached += HttpContext.Current.Cache.Cast<DictionaryEntry>().Count(ThisItem => ThisItem.Key.ToString().IndexOf("AGGR_") == 0);
                }
            }

            // Locally cache if this doesn't exceed the limit
            if ((items_cached < LOCALLY_CACHED_AGGREGATION_LIMIT) || (Aggregation_Code == "all") || (!caching_serving_enabled))
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("Cached_Data_Manager.Store_Item_Aggregation", "Adding object '" + key + "' to the local cache with expiration of " + local_expiration + " minute(s)");
                }

                HttpContext.Current.Cache.Insert(key, StoreObject, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(local_expiration));
            }

            // try to store in the caching server, if enabled
            if ((caching_serving_enabled) && ( Aggregation_Code != "all" ))
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("Cached_Data_Manager.Store_Item_Aggregation", "Adding object '" + key + "' to the caching server");
                }

                AppFabric_Manager.Add(key, StoreObject, Tracer);
            }
        }
        /// <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> Gets a fully built item aggregation object for a particular aggregation code and language code.  </summary>
        /// <param name="AggregationCode">Code for this aggregation object</param>
        /// <param name="Language_Code">Code for the language for this aggregation object</param>
        /// <param name="CacheInstance">Instance of this item aggregation pulled from cache (or NULL)</param>
        /// <param name="IsRobot">Flag tells if this request is from a robot (which will vary cacheing time)</param>
        /// <param name="StoreInCache"> Flag indicates if this should be stored in the cache once built </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <returns>Fully built item aggregation object for the particular aggregation code and language code</returns>
        /// <remarks>Item aggregation object is also placed in the cache.<br /><br />
        /// Building of an item aggregation always starts by pulling the item from the database ( either <see cref="SobekCM_Database.Get_Item_Aggregation"/> or <see cref="SobekCM_Database.Get_Main_Aggregation"/> ).<br /><br />
        /// Then, either the Item Aggregation XML file is read (if present) or the entire folder hierarchy is analyzed to find the browses, infos, banners, etc..</remarks>
        public static Item_Aggregation Get_Item_Aggregation(string AggregationCode, string Language_Code, Item_Aggregation CacheInstance, bool IsRobot, bool StoreInCache, Custom_Tracer Tracer)
        {
            // Does this exist in the cache?
            if (CacheInstance == null)
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Creating '" + AggregationCode + "' item aggregation");
                }

                // Get the information about this collection and this entry point
                Item_Aggregation hierarchyObject;
                if ((AggregationCode.Length > 0) && (AggregationCode != "all"))
                    hierarchyObject = SobekCM_Database.Get_Item_Aggregation(AggregationCode, false, IsRobot, Tracer);
                else
                    hierarchyObject = SobekCM_Database.Get_Main_Aggregation(Tracer);

                // If no value was returned, don't do anything else here
                if (hierarchyObject != null)
                {
                    // Add all the values to this object
                    string xmlDataFile = SobekCM_Library_Settings.Base_Design_Location + hierarchyObject.ObjDirectory + "\\" + hierarchyObject.Code + ".xml";
                    if (File.Exists(xmlDataFile))
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Reading XML Configuration File");
                        }

                        // Add the ALL and NEW browses
                        Add_All_New_Browses(hierarchyObject);

                        // Add all the other data from the XML file
                        Item_Aggregation_XML_Reader reader = new Item_Aggregation_XML_Reader();
                        reader.Add_Info_From_XML_File(hierarchyObject, xmlDataFile);
                    }
                    else
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Adding banner, home, and all/new browse information");
                        }

                        Add_HTML(hierarchyObject);
                        Add_All_New_Browses(hierarchyObject);
                        if (!IsRobot)
                        {
                            if (Tracer != null)
                            {
                                Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Scanning Design Directory for browse and info files");
                            }
                            Add_Browse_Files(hierarchyObject, Tracer);
                        }

                        // Since there was no configuration file, save one
                        hierarchyObject.Write_Configuration_File(SobekCM_Library_Settings.Base_Design_Location + hierarchyObject.ObjDirectory);
                    }

                    // Now, save this to the cache
                    if ((!IsRobot) && ( StoreInCache ))
                    {
                        Cached_Data_Manager.Store_Item_Aggregation(AggregationCode, Language_Code, hierarchyObject, Tracer);
                    }
                    else
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Skipping storing item aggregation on cache due to robot flag");
                        }
                    }

                    // Return this built hierarchy object
                    return hierarchyObject;
                }

                if (Tracer != null)
                {
                    Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "NULL value returned from database");
                }
                return null;
            }

            if (Tracer != null)
            {
                Tracer.Add_Trace("Item_Aggregation_Builder.Get_Item_Aggregation", "Found '" + AggregationCode + "' item aggregation in cache");
            }

            // Get the HTML element and search fields and return all this
            return CacheInstance;
        }
        /// <summary> Finds the home page source file and banner images or html for this item aggregation </summary>
        /// <param name="ThisObject"> Item aggregation to add the home page link and banner html </param>
        /// <remarks>This method is only called if the item aggregation does not have an existing XML configuration file. </remarks>
        protected static void Add_HTML( Item_Aggregation ThisObject )
        {
            // Just use the standard home text
            if ( File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text.html"))
                ThisObject.Add_Home_Page_File(  "html/home/text.html", SobekCM_Library_Settings.Default_UI_Language );
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_en.html"))
                ThisObject.Add_Home_Page_File("html/home/text_en.html",  Web_Language_Enum.English );
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_fr.html"))
                ThisObject.Add_Home_Page_File("html/home/text_fr.html", Web_Language_Enum.French);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_es.html"))
                ThisObject.Add_Home_Page_File("html/home/text_es.html", Web_Language_Enum.Spanish);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/home/text_sp.html"))
                ThisObject.Add_Home_Page_File("html/home/text_sp.html", Web_Language_Enum.Spanish);

            // Just use the standard banner image
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll.jpg"))
                ThisObject.Add_Banner_Image("images/banners/coll.jpg", SobekCM_Library_Settings.Default_UI_Language);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_en.jpg"))
                ThisObject.Add_Banner_Image("images/banners/coll_en.jpg", Web_Language_Enum.English);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_fr.jpg"))
                ThisObject.Add_Banner_Image("images/banners/coll_fr.jpg", Web_Language_Enum.French);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_es.jpg"))
                ThisObject.Add_Banner_Image("images/banners/coll_es.jpg", Web_Language_Enum.Spanish);
            if (File.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "images/banners/coll_sp.jpg"))
                ThisObject.Add_Banner_Image("images/banners/coll_sp.jpg", Web_Language_Enum.Spanish);
        }
        /// <summary> Checks the appropriate design folders to add any existing browse or info pages to the item aggregation </summary>
        /// <param name="ThisObject"> Item aggregation object to add the browse and info pages to</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks>This method is only called if the item aggregation does not have an existing XML configuration file.</remarks>
        protected static void Add_Browse_Files( Item_Aggregation ThisObject, Custom_Tracer Tracer  )
        {
            // Collect the list of items in the browse folder
            if (Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/browse"))
            {
                string[] files = Directory.GetFiles(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/browse", "*.htm*");
                foreach (string thisFile in files)
                {
                    // Get the new browse info object
                    Item_Aggregation_Child_Page newBrowse = Get_Item_Aggregation_Browse_Info(thisFile, Item_Aggregation_Child_Page.Visibility_Type.MAIN_MENU, Tracer);
                    if (newBrowse != null)
                    {
                        ThisObject.Add_Child_Page(newBrowse);
                    }
                }
            }

            // Collect the list of items in the info folder
            if (Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/info"))
            {
                string[] files = Directory.GetFiles(SobekCM_Library_Settings.Base_Design_Location + ThisObject.ObjDirectory + "html/info", "*.htm*");
                foreach (string thisFile in files)
                {
                    // Get the title for this file
                    // Get the new browse info object
                    Item_Aggregation_Child_Page newInfo = Get_Item_Aggregation_Browse_Info(thisFile, Item_Aggregation_Child_Page.Visibility_Type.NONE, Tracer);
                    if (newInfo != null)
                    {
                        ThisObject.Add_Child_Page(newInfo);
                    }
                }
            }
        }