/// <summary> Constructor for a new instance of the AggregationViewBag class </summary>
 /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
 /// <param name="Results_Statistics"> Information about the entire set of results for a browse </param>
 /// <param name="Paged_Results"> Single page of results for a 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="Static_Web_Content"> HTML content-based aggregation browse or info.  These are objects which are read from a static HTML file and much of the head information must be maintained </param>
 public AggregationViewBag(Item_Aggregation Hierarchy_Object,
     Search_Results_Statistics Results_Statistics,
     List<iSearch_Title_Result> Paged_Results,
     Item_Aggregation_Child_Page Browse_Object,
     HTML_Based_Content Static_Web_Content)
 {
     this.Hierarchy_Object = Hierarchy_Object;
     this.Results_Statistics = Results_Statistics;
     this.Paged_Results = Paged_Results;
     this.Browse_Object = Browse_Object;
     this.Static_Web_Content = Static_Web_Content;
 }
        /// <summary> Returns a built collection viewer matching request </summary>
        /// <param name="ViewType"> Web content view type </param>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <param name="StaticPage"> Static page info for this request </param>
        /// <returns> Web content viewer that extends the <see cref="abstractWebContentViewer"/> class. </returns>
        public static abstractWebContentViewer Get_Viewer(WebContent_Type_Enum ViewType, RequestCache RequestSpecificValues, HTML_Based_Content StaticPage )
        {
            switch (ViewType)
            {
                case WebContent_Type_Enum.Delete_Verify:
                    return new Delete_Verify_WebContentViewer(RequestSpecificValues, StaticPage);

                case WebContent_Type_Enum.Manage_Menu:
                    return new Manage_Menu_WebContentViewer(RequestSpecificValues, StaticPage);

                case WebContent_Type_Enum.Milestones:
                    return new Work_History_WebContentViewer(RequestSpecificValues, StaticPage);

                case WebContent_Type_Enum.Permissions:
                    return new User_Permissions_WebContentViewer(RequestSpecificValues, StaticPage);

                case WebContent_Type_Enum.Usage:
                    return new Usage_Statistics_WebContentViewer(RequestSpecificValues, StaticPage);

                default:
                    return null;
            }
        }
 /// <summary> Constructor for objects which implement this abstract class  </summary>
 /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
 /// <param name="StaticPage"> Static page info for this request </param>
 protected abstractWebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage )
 {
     this.RequestSpecificValues = RequestSpecificValues;
     this.StaticPage = StaticPage;
 }
        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 (UI_ApplicationCache_Gateway.Settings.Static.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
                    {
                        Complete_Item_Aggregation_Child_Page newPage = new Complete_Item_Aggregation_Child_Page { Code = childPageCode, Parent_Code = childPageParent, Source_Data_Type = Item_Aggregation_Child_Source_Data_Enum.Static_HTML };
                        newPage.Add_Label(childPageLabel, UI_ApplicationCache_Gateway.Settings.System.Default_UI_Language);
                        switch (childPageVisibility)
                        {
                            case "none":
                                newPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.None;
                                newPage.Parent_Code = String.Empty;
                                break;

                            case "browse":
                                newPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.Main_Menu;
                                break;

                            case "browseby":
                                newPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.Metadata_Browse_By;
                                newPage.Parent_Code = String.Empty;
                                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(UI_ApplicationCache_Gateway.Settings.System.Default_UI_Language) + ".html";
                        if (!File.Exists(html_source_file))
                        {
                            HTML_Based_Content htmlContent = new HTML_Based_Content
                            {
                                Content = "<br /><br />This is a new browse page.<br /><br />" + childPageLabel + "<br /><br />The code for this browse is: " + childPageCode,
                                Author = RequestSpecificValues.Current_User.Full_Name,
                                Date = DateTime.Now.ToLongDateString(),
                                Title = childPageLabel
                            };
                            htmlContent.Save_To_File(html_source_file);
                        }
                        newPage.Add_Static_HTML_Source("html\\browse\\" + childPageCode + "_" + Web_Language_Enum_Converter.Enum_To_Code(UI_ApplicationCache_Gateway.Settings.System.Default_UI_Language) + ".html", UI_ApplicationCache_Gateway.Settings.System.Default_UI_Language);

                        itemAggregation.Add_Child_Page(newPage);

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

                    }
                }
            }
        }
 /// <summary> Constructor for a new instance of the Manage_Menu_WebContentViewer class </summary>
 /// <param name="RequestSpecificValues">  All the necessary, non-global data specific to the current request  </param>
 /// <param name="StaticPage"> Static page info for this request </param>
 public Manage_Menu_WebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage )
     : base(RequestSpecificValues, StaticPage)
 {
 }
        /// <summary> Stores the special missing web content page, used when a requested resource is missing (engine and client side) </summary>
        /// <param name="StoreObject"> Fully built web content page (or redirect) object </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        public void Store_Special_Missing_Page(HTML_Based_Content StoreObject, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager_WebContentServices.Store_Special_Missing_Page");
            }

            // If the cache is disabled, just return before even tracing
            if (settings.Disabled)
            {
                if (Tracer != null) Tracer.Add_Trace("CachedDataManager_WebContentServices.Store_Special_Missing_Page", "Caching is disabled");
                return;
            }

            // Determine the key
            const string KEY = "WEBCONTENT|DETAILS|!MISSING!";

            const int LOCAL_EXPIRATION = 5;

            // Locally cache if this doesn't exceed the limit
            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager_WebContentServices.Store_Special_Missing_Page", "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));
        }
        /// <summary>
        /// Store_s the content of the aggregation_ HTM l_ based_.
        /// </summary>
        /// <param name="Aggregation_Code">The aggregation_ code.</param>
        /// <param name="Language">The language.</param>
        /// <param name="ChildPageCode">The child page code.</param>
        /// <param name="StoreObject">The store object.</param>
        /// <param name="Tracer">The tracer.</param>
        public void Store_Aggregation_HTML_Based_Content(string Aggregation_Code, Web_Language_Enum Language, string ChildPageCode, HTML_Based_Content StoreObject, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager_AggregationServices.Store_Aggregation_HTML_Based_Content", "Entering Store_Aggregation_HTML_Based_Content method");
            }

            // If the cache is disabled, just return before even tracing
            if (settings.Disabled)
            {
                if (Tracer != null) Tracer.Add_Trace("CachedDataManager_AggregationServices.Store_Aggregation_HTML_Based_Content", "Caching is disabled");
                return;
            }

            // Determine the key
            string key = "AGGR|" + Aggregation_Code.ToUpper() + "|" + Web_Language_Enum_Converter.Enum_To_Code(Language) + "|" + ChildPageCode;

            // Check the number of item aggregationPermissions currently locally cached
            const int LOCAL_EXPIRATION = 15;

            // Locally cache if this doesn't exceed the limit
            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager_AggregationServices.Store_Aggregation_HTML_Based_Content", "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));
        }
 /// <summary>  Constructor for a new instance of the Work_History_WebContentViewer class  </summary>
 /// <param name="RequestSpecificValues">  All the necessary, non-global data specific to the current request  </param>
 /// <param name="StaticPage"> Static page info for this request </param>
 public Work_History_WebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage)
     : base(RequestSpecificValues, StaticPage)
 {
 }
        /// <summary> Get top-level web content, static HTML, by URL </summary>
        /// <param name="Response"></param>
        /// <param name="UrlSegments"></param>
        /// <param name="QueryString"></param>
        /// <param name="Protocol"></param>
        /// <param name="IsDebug"></param>
        public void Get_HTML_Based_Content_By_URL(HttpResponse Response, List<string> UrlSegments, NameValueCollection QueryString, Microservice_Endpoint_Protocol_Enum Protocol, bool IsDebug )
        {
            Custom_Tracer tracer = new Custom_Tracer();

            tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_URL","Compute web content id from url segments");

            if (Engine_ApplicationCache_Gateway.WebContent_Hierarchy == null)
            {
                tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_URL", "Unable to pull web content hierarchy from engine application cache");

                Response.ContentType = "text/plain";
                Response.Output.WriteLine("Unable to pull web content hierarchy from engine application cache");
                Response.StatusCode = 500;

                // If this was debug mode, then just write the tracer
                if (IsDebug)
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("DEBUG MODE DETECTED");
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(tracer.Text_Trace);
                }

                return;
            }

            // Look this up from the web content hierarchy object
            WebContent_Hierarchy_Node matchedNode = Engine_ApplicationCache_Gateway.WebContent_Hierarchy.Find(UrlSegments);
            if (matchedNode == null)
            {
                tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_URL", "Requested page does not exist");

                Response.ContentType = "text/plain";
                Response.Output.WriteLine("Requested page does not exist");
                Response.StatusCode = 404;

                // If this was debug mode, then just write the tracer
                if (IsDebug)
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("DEBUG MODE DETECTED");
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(tracer.Text_Trace);
                }
                return;
            }

            // Declare the return object and look this up in the cache by ID
            HTML_Based_Content returnValue = CachedDataManager.WebContent.Retrieve_Page_Details(matchedNode.WebContentID, tracer);

            // If nothing was retrieved, built it
            if (returnValue == null)
            {
                // If there was a redirect, just return a very lightly built object
                if (!String.IsNullOrEmpty(matchedNode.Redirect))
                {
                    returnValue = new HTML_Based_Content
                    {
                        Redirect = matchedNode.Redirect,
                        WebContentID = matchedNode.WebContentID
                    };
                }
                else
                {
                    // Get the details from the database
                    WebContent_Basic_Info basicInfo = Engine_Database.WebContent_Get_Page(matchedNode.WebContentID, tracer);
                    if (basicInfo == null)
                    {
                        Response.ContentType = "text/plain";
                        Response.Output.WriteLine("Unable to pull web content data from the database");
                        Response.StatusCode = 500;
                        return;
                    }

                    // Build the HTML content
                    WebContentEndpointErrorEnum errorType;
                    returnValue = read_source_file(basicInfo, tracer, out errorType);
                    if (returnValue == null)
                    {
                        // If this was debug mode, then just write the tracer
                        if (IsDebug)
                        {
                            Response.ContentType = "text/plain";
                            Response.Output.WriteLine("DEBUG MODE DETECTED");
                            Response.Output.WriteLine();
                            Response.Output.WriteLine(tracer.Text_Trace);
                        }

                        switch (errorType)
                        {
                            case WebContentEndpointErrorEnum.Error_Reading_File:
                                Response.ContentType = "text/plain";
                                Response.Output.WriteLine("Unable to read existing source file");
                                Response.StatusCode = 500;
                                return;

                            case WebContentEndpointErrorEnum.No_File_Found:
                                Response.ContentType = "text/plain";
                                Response.Output.WriteLine("Source file does not exist");
                                Response.StatusCode = 404;
                                return;

                            default:
                                Response.ContentType = "text/plain";
                                Response.Output.WriteLine("Error occurred");
                                Response.StatusCode = 500;
                                return;
                        }
                    }
                }

                // Now, store in the cache
                CachedDataManager.WebContent.Store_Page_Details(returnValue, tracer);
            }
            else
            {
                tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_URL", "Object found in the cache");
            }

            // If this was debug mode, then just write the tracer
            if ( IsDebug )
            {
                tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_URL", "Debug mode detected");
                Response.ContentType = "text/plain";
                Response.Output.WriteLine("DEBUG MODE DETECTED");
                Response.Output.WriteLine();
                Response.Output.WriteLine(tracer.Text_Trace);

                return;
            }

            // Get the JSON-P callback function
            string json_callback = "parseWebContent";
            if ((Protocol == Microservice_Endpoint_Protocol_Enum.JSON_P) && (!String.IsNullOrEmpty(QueryString["callback"])))
            {
                json_callback = QueryString["callback"];
            }

            // Use the base class to serialize the object according to request protocol
            Serialize(returnValue, Response, Protocol, json_callback);
        }
        /// <summary> Constructor for a new instance of the WebContent_Single_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public WebContent_Single_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            RequestSpecificValues.Tracer.Add_Trace("WebContent_Single_AdminViewer.Constructor", String.Empty);

            // If not logged in, send to main home page
            if ((RequestSpecificValues.Current_User == null) || (!RequestSpecificValues.Current_User.LoggedOn))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // If no web content id was provided, send back
            if ( !RequestSpecificValues.Current_Mode.WebContentID.HasValue )
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Set some defaults and get the web content id
            actionMessage = String.Empty;
            webContentId = RequestSpecificValues.Current_Mode.WebContentID.Value;

            try
            {

                // Load the web content, either currenlty from the session (if already editing this aggregation )
                // or by reading all the appropriate XML and reading data from the database
                object possibleEditWebContent = HttpContext.Current.Session["Edit_WebContent|" + webContentId];
                HTML_Based_Content cachedInstance = possibleEditWebContent as HTML_Based_Content;
                if (cachedInstance != null)
                {
                    webContent = cachedInstance;
                }
                else
                {
                    webContent = SobekEngineClient.WebContent.Get_HTML_Based_Content(webContentId, false, RequestSpecificValues.Tracer);
                }

                // If unable to retrieve this aggregation, send to home
                if (webContent == null)
                {
                    RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                    UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                    return;
                }

                // If the current user cannot edit this, go back
                if (!webContent.Can_Edit(RequestSpecificValues.Current_User))
                {
                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                    RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                    UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                    return;
                }

                // Get the web content directory and ensure it exists
                webContentDirectory = UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "webcontent\\" + webContent.UrlSegments.Replace("/", "\\");
                if (!Directory.Exists(webContentDirectory))
                    Directory.CreateDirectory(webContentDirectory);

                // Determine the page
                page = 1;
                if (!String.IsNullOrEmpty(RequestSpecificValues.Current_Mode.My_Sobek_SubMode))
                {
                    //if (RequestSpecificValues.Current_Mode.My_Sobek_SubMode == "b")   RESERVED FOR LANGUAGE SUPPORT
                    //    page = 2;
                    //else if (RequestSpecificValues.Current_Mode.My_Sobek_SubMode == "c")  RESERVED FOR SITEMAP SUPPORT
                    //    page = 3;
                    if (RequestSpecificValues.Current_Mode.My_Sobek_SubMode == "d")
                        page = 4;
                    else if (RequestSpecificValues.Current_Mode.My_Sobek_SubMode == "e")
                        page = 5;
                }

                // If this is a postback, handle any events first
                if (RequestSpecificValues.Current_Mode.isPostBack)
                {
                    try
                    {
                        // Pull the standard values
                        NameValueCollection form = HttpContext.Current.Request.Form;

                        // Get the curret action
                        string action = form["admin_webcontent_save"];

                        // If no action, then we should return to the current tab page
                        if (action.Length == 0)
                            action = RequestSpecificValues.Current_Mode.My_Sobek_SubMode;

                        // If this is to cancel, handle that here; no need to handle post-back from the
                        // editing form page first
                        if (action == "z")
                        {
                            // Clear the aggregation from the sessions
                            HttpContext.Current.Session["Edit_WebContent|" + webContentId] = null;

                            // Redirect the RequestSpecificValues.Current_User
                            string url = webContent.URL(UI_ApplicationCache_Gateway.Settings.Servers.Base_URL);
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                            HttpContext.Current.Response.Redirect(url, false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            return;
                        }

                        // Save the returned values, depending on the page
                        switch (page)
                        {
                            case 1:
                                Save_Page_General_Postback(form);
                                break;

                                //case 2: RESERVED FOR LANGUAGE SUPPORT
                                //    Save_Page_2_Postback(form);
                                //    break;

                                //case 3: RESERVED FOR SITEMAP SUPPORT
                                //    Save_Page_3_Postback(form);
                                //    break;

                            case 4:
                                Save_Child_Pages_Postback(form);
                                break;

                            case 5:
                                Save_Uploads_Postback(form);
                                break;
                        }

                        // Should this be saved to the database?
                        if ((action == "save") || (action == "save_exit"))
                        {
                            // Set the date on the page to today
                            webContent.Date = DateTime.Now.ToShortDateString();

                            // Send the update to the endgine
                            RestResponseMessage response = SobekEngineClient.WebContent.Update_HTML_Based_Content(webContent, RequestSpecificValues.Current_User.Full_Name, RequestSpecificValues.Tracer);

                            // Clear the cache
                            CachedDataManager.WebContent.Clear_Page_Details(webContent.WebContentID.Value);

                            if (action == "save_exit")
                            {
                                RequestSpecificValues.Current_Mode.Request_Completed = true;
                                HttpContext.Current.Response.Redirect(webContent.URL(RequestSpecificValues.Current_Mode.Base_URL), false);
                                HttpContext.Current.ApplicationInstance.CompleteRequest();
                                return;
                            }

                        }
                        else
                        {
                            // In some cases, skip this part
                            if (((page == 8) && (action == "h")) || ((page == 7) && (action == "g")))
                                return;

                            // Save to the admins session
                            HttpContext.Current.Session["Edit_WebContent|" + webContentId] = webContent;
                            RequestSpecificValues.Current_Mode.My_Sobek_SubMode = action;
                            HttpContext.Current.Response.Redirect(UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode), false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            RequestSpecificValues.Current_Mode.Request_Completed = true;
                        }
                    }
                    catch ( Exception ee )
                    {
                        actionMessage = "Unable to correctly parse postback data.  " + ee.Message;
                    }
                }
            }
            catch (Exception ee)
            {
                storedException = ee;
            }
        }
Exemplo n.º 11
0
 /// <summary> Constructor for a new instance of the RequestCache 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="Public_Folder"> Object contains the information about the public folder to display </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 RequestCache(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,
     Web_Skin_Object HTML_Skin,
     User_Object Current_User,
     Public_User_Folder Public_Folder,
     SobekCM_SiteMap Site_Map,
     SobekCM_Items_In_Title Items_In_Title,
     HTML_Based_Content Static_Web_Content,
     Custom_Tracer Tracer)
 {
     this.Current_Mode = Current_Mode;
     this.Hierarchy_Object = Hierarchy_Object;
     this.Results_Statistics = Results_Statistics;
     this.Paged_Results = Paged_Results;
     this.Browse_Object = Browse_Object;
     this.Current_Item = Current_Item;
     this.Current_Page = Current_Page;
     this.HTML_Skin = HTML_Skin;
     this.Current_User = Current_User;
     this.Public_Folder = Public_Folder;
     this.Site_Map = Site_Map;
     this.Items_In_Title = Items_In_Title;
     this.Static_Web_Content = Static_Web_Content;
     this.Tracer = Tracer;
 }
        private static HTML_Based_Content Text_To_HTML_Based_Content(string Display_Text, bool Retain_Entire_Display_Text, string Source, Custom_Tracer Tracer)
        {
            // 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;
            bool   includeMenu = false;
            string sobekControlledJavascript = String.Empty;
            string sobekControlledCss        = String.Empty;

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

            HTML_Based_Content returnValue = new HTML_Based_Content();

            if (Tracer != null)
            {
                Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Converting source file content into object");
            }

            // 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);

            if ((head_start >= 0) && (head_end > head_start))
            {
                bool read_as_xml;
                try
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Attempting to read the html head as XML");
                    }

                    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":
                            // Was this the controlled link?
                            if ((xmlReader.MoveToAttribute("id")) && (xmlReader.Value == "SobekCmControlledCss"))
                            {
                                if (xmlReader.MoveToAttribute("href"))
                                {
                                    sobekControlledCss = xmlReader.Value;
                                }
                            }
                            else
                            {
                                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 "SCRIPT":
                            // Was this the controlled link?
                            if ((xmlReader.MoveToAttribute("id")) && (xmlReader.Value == "SobekCmControlledJavascript"))
                            {
                                if (xmlReader.MoveToAttribute("src"))
                                {
                                    sobekControlledJavascript = xmlReader.Value;
                                }
                            }
                            else
                            {
                                headBuilder.Append("<script ");
                                int attributeCount = xmlReader.AttributeCount;
                                for (int i = 0; i < attributeCount; i++)
                                {
                                    xmlReader.MoveToAttribute(i);
                                    headBuilder.Append(xmlReader.Name + "=\"" + xmlReader.Value + "\" ");
                                }
                                headBuilder.AppendLine("></script>");
                            }
                            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;

                                case "MENU":
                                    if (String.Compare(content_type, "true", StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        includeMenu = true;
                                    }
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    read_as_xml = true;
                }
                catch
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Was unable to read the html head as XML");
                    }
                    read_as_xml = false;
                }


                // Read this the old way if unable to read via XML for some reason
                if (!read_as_xml)
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Attempting to parse html head for title, code, and banner information");
                    }

                    // 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
                if (code.Length > 0)
                {
                    returnValue.Code = code;
                }
                if (title.Length > 0)
                {
                    returnValue.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();
                }
                if (includeMenu)
                {
                    returnValue.IncludeMenu = true;
                }
                if (sobekControlledCss.Length > 0)
                {
                    returnValue.CssFile = sobekControlledCss;
                }
                if (sobekControlledJavascript.Length > 0)
                {
                    returnValue.JavascriptFile = sobekControlledJavascript;
                }
            }
            else
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "No html head found in source file");
                }
            }

            // Should the actual display text be retained?
            if (Retain_Entire_Display_Text)
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Reading the entire display text and saving in the object");
                }

                int start_body = Display_Text.IndexOf("<body>");
                int end_body   = Display_Text.IndexOf("</body>");
                if ((start_body > 0) && (end_body > start_body))
                {
                    start_body         += 6;
                    returnValue.Content = Display_Text.Substring(start_body, end_body - start_body) + " ";

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

            return(returnValue);
        }
        /// <summary> Helper method retrieves HTML web content </summary>
        /// <param name="BasicInfo"> Basic information from the database for this endpoint, including the URL segments </param>
        /// <param name="Tracer"></param>
        /// <param name="ErrorType"> Any error enocuntered during the process </param>
        /// <returns> Built HTML content object, or NULL </returns>
        private static HTML_Based_Content read_source_file(WebContent_Basic_Info BasicInfo, Custom_Tracer Tracer, out WebContentEndpointErrorEnum ErrorType)
        {
            // Set a default error message first
            ErrorType = WebContentEndpointErrorEnum.NONE;

            // Build the directory to look for the static content
            StringBuilder possibleInfoModeBuilder = new StringBuilder(BasicInfo.Level1);
            if (!String.IsNullOrEmpty(BasicInfo.Level2))
            {
                possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level2);
                if (!String.IsNullOrEmpty(BasicInfo.Level3))
                {
                    possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level3);
                    if (!String.IsNullOrEmpty(BasicInfo.Level4))
                    {
                        possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level4);
                        if (!String.IsNullOrEmpty(BasicInfo.Level5))
                        {
                            possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level5);
                            if (!String.IsNullOrEmpty(BasicInfo.Level6))
                            {
                                possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level6);
                                if (!String.IsNullOrEmpty(BasicInfo.Level7))
                                {
                                    possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level7);
                                    if (!String.IsNullOrEmpty(BasicInfo.Level8))
                                    {
                                        possibleInfoModeBuilder.Append(Path.DirectorySeparatorChar + BasicInfo.Level8);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            string possible_info_mode = possibleInfoModeBuilder.ToString().Replace("'", "").Replace("\"", "");
            string filename = possible_info_mode;
            string base_source = Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent";
            string source = base_source;
            string found_source = null;

            if ((possible_info_mode.IndexOf("\\") > 0) || (possible_info_mode.IndexOf("/") > 0))
            {
                source = source + "\\" + possible_info_mode.Replace("/", "\\");
                string[] split = source.Split("\\".ToCharArray());
                filename = split[split.Length - 1];
                source = source.Substring(0, source.Length - filename.Length);
            }

            // Start to build the return value
            HTML_Based_Content simpleWebContent = null;

            // If the designated source exists, look for the files
            if (Directory.Exists(source))
            {
                // This may point to the default html in the parent directory
                if ((Directory.Exists(source + "\\" + filename)) && (File.Exists(source + "\\" + filename + "\\default.html")))
                {
                    found_source = Path.Combine(source, filename, "default.html");
                    Tracer.Add_Trace("WebContentServices.get_html_content", "Found source file: " + found_source);
                }

                // If this was found, build it and return it
                if (!String.IsNullOrEmpty(found_source))
                {
                    simpleWebContent = HTML_Based_Content_Reader.Read_HTML_File(found_source, true, Tracer);
                }
            }

            // If NULL then this valid web content page has no source!
            if (simpleWebContent == null)
            {
                simpleWebContent = new HTML_Based_Content();
                if (!String.IsNullOrEmpty(found_source))
                {
                    Tracer.Add_Trace("WebContentServices.get_html_content", "Error reading source file");
                    Tracer.Add_Trace("WebContentServices.get_html_content", found_source);
                    simpleWebContent.Title = "EXCEPTION ENCOUNTERED";
                    simpleWebContent.Build_Exception = "Found web content file, but it was apparently corrupted.  Error reading file " + found_source;
                    ErrorType = WebContentEndpointErrorEnum.Error_Reading_File;
                    simpleWebContent.Content = "<strong>Error reading the existing source file.  It may be corrupt.</strong>";
                    simpleWebContent.ContentSource = simpleWebContent.Source;
                }
                else
                {
                    Tracer.Add_Trace("WebContentServices.get_html_content", "No valid source file found!");
                    Tracer.Add_Trace("WebContentServices.get_html_content", found_source);
                    simpleWebContent.Title = "EXCEPTION ENCOUNTERED";
                    simpleWebContent.Build_Exception = "No valid source file found!";
                    simpleWebContent.Content = "<strong>No valid source file found, despite the fact this is a valid web content page in the database!</strong>";
                    simpleWebContent.ContentSource = simpleWebContent.Source;
                    ErrorType = WebContentEndpointErrorEnum.No_File_Found;
                }
            }

            // Copy over the primary key and URL segments for this web content
            simpleWebContent.WebContentID = BasicInfo.WebContentID;
            simpleWebContent.Level1 = BasicInfo.Level1;
            simpleWebContent.Level2 = BasicInfo.Level2;
            simpleWebContent.Level3 = BasicInfo.Level3;
            simpleWebContent.Level4 = BasicInfo.Level4;
            simpleWebContent.Level5 = BasicInfo.Level5;
            simpleWebContent.Level6 = BasicInfo.Level6;
            simpleWebContent.Level7 = BasicInfo.Level7;
            simpleWebContent.Level8 = BasicInfo.Level8;
            if ((BasicInfo.Locked.HasValue) && (BasicInfo.Locked.Value)) simpleWebContent.Locked = true;

            // Now, check for any "server-side include" directorives in the source text
            int include_index = simpleWebContent.Content.IndexOf("<%INCLUDE");
            while ((include_index > 0) && (simpleWebContent.Content.IndexOf("%>", include_index, StringComparison.Ordinal) > 0))
            {
                int include_finish_index = simpleWebContent.Content.IndexOf("%>", include_index, StringComparison.Ordinal) + 2;
                string include_statement = simpleWebContent.Content.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(Engine_ApplicationCache_Gateway.Settings.Servers.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(Engine_ApplicationCache_Gateway.Settings.Servers.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
                    simpleWebContent.Content = simpleWebContent.Content.Replace(include_statement, include_text);
                    include_index = simpleWebContent.Content.IndexOf("<%INCLUDE", include_index + include_text.Length - 1, StringComparison.Ordinal);
                }
                else
                {
                    // No suitable name was found, or it doesn't exist so just remove the INCLUDE completely
                    simpleWebContent.Content = simpleWebContent.Content.Replace(include_statement, "");
                    include_index = simpleWebContent.Content.IndexOf("<%INCLUDE", include_index, StringComparison.Ordinal);
                }
            }

            // Now, return the web content object, with the text
            return simpleWebContent;
        }
        private static HTML_Based_Content Text_To_HTML_Based_Content(string Display_Text, bool Retain_Entire_Display_Text, string Source, Custom_Tracer Tracer )
        {
            // 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;
            bool includeMenu = false;
            string sobekControlledJavascript = String.Empty;
            string sobekControlledCss = String.Empty;

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

            HTML_Based_Content returnValue = new HTML_Based_Content();

            if (Tracer != null)
            {
                Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Converting source file content into object" );
            }

            // 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);
            if ((head_start >= 0) && (head_end > head_start))
            {
                bool read_as_xml;
                try
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Attempting to read the html head as XML");
                    }

                    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":
                                // Was this the controlled link?
                                if ((xmlReader.MoveToAttribute("id")) && (xmlReader.Value == "SobekCmControlledCss"))
                                {
                                    if (xmlReader.MoveToAttribute("href"))
                                        sobekControlledCss = xmlReader.Value;
                                }
                                else
                                {
                                    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 "SCRIPT":
                                // Was this the controlled link?
                                if ((xmlReader.MoveToAttribute("id")) && (xmlReader.Value == "SobekCmControlledJavascript"))
                                {
                                    if (xmlReader.MoveToAttribute("src"))
                                        sobekControlledJavascript = xmlReader.Value;
                                }
                                else
                                {
                                    headBuilder.Append("<script ");
                                    int attributeCount = xmlReader.AttributeCount;
                                    for (int i = 0; i < attributeCount; i++)
                                    {
                                        xmlReader.MoveToAttribute(i);
                                        headBuilder.Append(xmlReader.Name + "=\"" + xmlReader.Value + "\" ");
                                    }
                                    headBuilder.AppendLine("></script>");
                                }
                                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;

                                        case "MENU":
                                            if (String.Compare(content_type, "true", StringComparison.OrdinalIgnoreCase) == 0)
                                                includeMenu = true;
                                            break;
                                    }
                                }
                                break;
                        }
                    }
                    read_as_xml = true;
                }
                catch
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Was unable to read the html head as XML");
                    }
                    read_as_xml = false;
                }

                // Read this the old way if unable to read via XML for some reason
                if (!read_as_xml)
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Attempting to parse html head for title, code, and banner information");
                    }

                    // 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
                if (code.Length > 0)
                    returnValue.Code = code;
                if (title.Length > 0)
                    returnValue.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();
                if (includeMenu)
                    returnValue.IncludeMenu = true;
                if (sobekControlledCss.Length > 0)
                    returnValue.CssFile = sobekControlledCss;
                if (sobekControlledJavascript.Length > 0)
                    returnValue.JavascriptFile = sobekControlledJavascript;
            }
            else
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "No html head found in source file");
                }
            }

            // Should the actual display text be retained?
            if (Retain_Entire_Display_Text)
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Text_To_HTML_Based_Content", "Reading the entire display text and saving in the object");
                }

                int start_body = Display_Text.IndexOf("<body>");
                int end_body = Display_Text.IndexOf("</body>");
                if ((start_body > 0) && (end_body > start_body))
                {
                    start_body += 6;
                    returnValue.Content = Display_Text.Substring(start_body, end_body - start_body) + " ";

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

            return returnValue;
        }
        /// <summary> Update an existing web content page or redirect </summary>
        /// <param name="Content"> Newly updated HTML content to be put back on the server </param>
        /// <param name="User"> Name of the user that performed the work </param>
        /// <param name="Tracer"></param>
        /// <returns> Message </returns>
        public RestResponseMessage Update_HTML_Based_Content(HTML_Based_Content Content, string User, Custom_Tracer Tracer)
        {
            // Add a beginning trace
            Tracer.Add_Trace("SobekEngineClient_WebContentServices.Update_HTML_Based_Content", "Add a new or update an existing web content page or redirect");

            // Get the endpoint
            MicroservicesClient_Endpoint endpoint = GetEndpointConfig("WebContent.Update_HTML_Based_Content", Tracer);

            // Using the correct protocol, encode the Content
            string contentString = String.Empty;
            switch (endpoint.Protocol)
            {
                case Microservice_Endpoint_Protocol_Enum.JSON:
                case Microservice_Endpoint_Protocol_Enum.JSON_P:
                    contentString = JSON.Serialize(Content);
                    break;

                case Microservice_Endpoint_Protocol_Enum.PROTOBUF:
                    using (MemoryStream memStream = new MemoryStream())
                    {
                        Serializer.Serialize(memStream, Content);
                        contentString = Encoding.ASCII.GetString(memStream.ToArray());
                    }
                    break;

                case Microservice_Endpoint_Protocol_Enum.XML:
                    XmlSerializer x = new XmlSerializer(Content.GetType());
                    StringBuilder bldr = new StringBuilder();
                    using (StringWriter stringWriter = new StringWriter(bldr))
                    {
                        x.Serialize(stringWriter, Content);
                        contentString = bldr.ToString();
                    }
                    break;
            }

            // Create the post data
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("User", User),
                new KeyValuePair<string, string>("Content", contentString)
            };

            // Format the URL
            string url = String.Format(endpoint.URL, Content.WebContentID);

            // Call out to the endpoint and return the deserialized object
            return Deserialize<RestResponseMessage>(url, endpoint.Protocol, postData, "POST", Tracer);
        }
        /// <summary> Get top-level web content, static HTML, by primary key from the database </summary>
        /// <param name="Response"></param>
        /// <param name="UrlSegments"></param>
        /// <param name="QueryString"></param>
        /// <param name="Protocol"></param>
        /// <param name="IsDebug"></param>
        public void Get_HTML_Based_Content_By_ID(HttpResponse Response, List<string> UrlSegments, NameValueCollection QueryString, Microservice_Endpoint_Protocol_Enum Protocol, bool IsDebug)
        {
            Custom_Tracer tracer = new Custom_Tracer();

            // Add a trace
            tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_ID", "Get content based on the primary key");

            // Must at least have one URL segment for the ID
            if (UrlSegments.Count > 0)
            {
                int webContentId;
                if (!Int32.TryParse(UrlSegments[0], out webContentId))
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("Invalid parameter - expects primary key integer value to the web content object (WebContentID) as part of URL");
                    Response.StatusCode = 500;

                    // If this was debug mode, then write the tracer
                    if (IsDebug)
                    {
                        Response.Output.WriteLine();
                        Response.Output.WriteLine();
                        Response.Output.WriteLine("DEBUG MODE DETECTED");
                        Response.Output.WriteLine();
                        Response.Output.WriteLine(tracer.Text_Trace);
                    }
                    return;
                }

                // Declare the return object and look this up in the cache by ID
                HTML_Based_Content returnValue = CachedDataManager.WebContent.Retrieve_Page_Details(webContentId, tracer);

                // If nothing was retrieved, build it
                if (returnValue == null)
                {

                    // Try to read and return the html based content
                    // Get the details from the database
                    WebContent_Basic_Info basicInfo = Engine_Database.WebContent_Get_Page(webContentId, tracer);
                    if (basicInfo == null)
                    {
                        Response.ContentType = "text/plain";
                        Response.Output.WriteLine("Unable to pull web content data from the database");
                        Response.StatusCode = 500;
                        return;
                    }

                    // If this has a redirect, return
                    if (!String.IsNullOrEmpty(basicInfo.Redirect))
                    {
                        returnValue = new HTML_Based_Content
                        {
                            Title = basicInfo.Title,
                            Level1 = basicInfo.Level1,
                            Level2 = basicInfo.Level2,
                            Level3 = basicInfo.Level3,
                            Level4 = basicInfo.Level4,
                            Level5 = basicInfo.Level5,
                            Level6 = basicInfo.Level6,
                            Level7 = basicInfo.Level7,
                            Level8 = basicInfo.Level8,
                            Locked = basicInfo.Locked,
                            Description = basicInfo.Summary,
                            Redirect = basicInfo.Redirect,
                            WebContentID = basicInfo.WebContentID
                        };
                    }
                    else
                    {
                        // Build the HTML content
                        WebContentEndpointErrorEnum errorType;
                        returnValue = read_source_file(basicInfo, tracer, out errorType);
                        if (returnValue == null)
                        {
                            // If this was debug mode, then just write the tracer
                            if (IsDebug)
                            {
                                Response.ContentType = "text/plain";
                                Response.Output.WriteLine("DEBUG MODE DETECTED");
                                Response.Output.WriteLine();
                                Response.Output.WriteLine(tracer.Text_Trace);
                            }

                            switch (errorType)
                            {
                                case WebContentEndpointErrorEnum.Error_Reading_File:
                                    Response.ContentType = "text/plain";
                                    Response.Output.WriteLine("Unable to read existing source file");
                                    Response.StatusCode = 500;
                                    return;

                                case WebContentEndpointErrorEnum.No_File_Found:
                                    Response.ContentType = "text/plain";
                                    Response.Output.WriteLine("Source file does not exist");
                                    Response.StatusCode = 404;
                                    return;

                                default:
                                    Response.ContentType = "text/plain";
                                    Response.Output.WriteLine("Error occurred");
                                    Response.StatusCode = 500;
                                    return;
                            }
                        }
                    }

                    // Now, store in the cache
                    CachedDataManager.WebContent.Store_Page_Details(returnValue, tracer);
                }
                else
                {
                    tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_ID", "Object found in the cache");
                }

                // If this was debug mode, then just write the tracer
                if (IsDebug)
                {
                    tracer.Add_Trace("WebContentServices.Get_HTML_Based_Content_By_ID", "Debug mode detected");
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("DEBUG MODE DETECTED");
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(tracer.Text_Trace);

                    return;
                }

                // Get the JSON-P callback function
                string json_callback = "parseWebContent";
                if ((Protocol == Microservice_Endpoint_Protocol_Enum.JSON_P) && (!String.IsNullOrEmpty(QueryString["callback"])))
                {
                    json_callback = QueryString["callback"];
                }

                // Use the base class to serialize the object according to request protocol
                Serialize(returnValue, Response, Protocol, json_callback);
            }
            else
            {
                Response.ContentType = "text/plain";
                Response.Output.WriteLine("Invalid parameter - expects primary key integer value to the web content object (WebContentID) as part of URL");
                Response.StatusCode = 500;
            }
        }
 /// <summary>  Constructor for a new instance of the Usage_Statistics_WebContentViewer class  </summary>
 /// <param name="RequestSpecificValues">  All the necessary, non-global data specific to the current request  </param>
 /// <param name="StaticPage"> Static page info for this request </param>
 public Usage_Statistics_WebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage)
     : base(RequestSpecificValues, StaticPage)
 {
 }
        // <summary> Delete a non-aggregational top-level web content, static HTML page or redirect </summary>
        /// <param name="Response"></param>
        /// <param name="UrlSegments"></param>
        /// <param name="Protocol"></param>
        /// <param name="RequestForm"></param>
        /// <param name="IsDebug"></param>
        public void Update_HTML_Based_Content(HttpResponse Response, List<string> UrlSegments, Microservice_Endpoint_Protocol_Enum Protocol, NameValueCollection RequestForm, bool IsDebug)
        {
            Custom_Tracer tracer = new Custom_Tracer();

            // Add a trace
            tracer.Add_Trace("WebContentServices.AddUpdate_HTML_Based_Content");

            // Validate the web content id exists in the URL
            int webcontentId;
            if ((UrlSegments.Count == 0) || (!Int32.TryParse(UrlSegments[0], out webcontentId)))
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "Invalid URL.  WebContentID missing from URL"), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            // Get and validate the required USER (string) posted request object
            if ((RequestForm["User"] == null) || (String.IsNullOrEmpty(RequestForm["User"])))
            {
                Serialize( new RestResponseMessage(ErrorRestTypeEnum.InputError, "Required posted object 'User' is missing") , Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }
            string user = RequestForm["User"];

            // Get and validate the required CONTENT (HTML_Based_Content) posted request objects
            if ((RequestForm["Content"] == null) || (String.IsNullOrEmpty(RequestForm["Content"])))
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "Required posted object 'Content' is missing"), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            string contentString = RequestForm["Content"];
            HTML_Based_Content content = null;
            try
            {
                switch (Protocol)
                {
                    case Microservice_Endpoint_Protocol_Enum.JSON:
                    case Microservice_Endpoint_Protocol_Enum.JSON_P:
                        content = JSON.Deserialize<HTML_Based_Content>(contentString);
                        break;

                    case Microservice_Endpoint_Protocol_Enum.PROTOBUF:
                        // Deserialize using the Protocol buffer-net library
                        byte[] byteArray = Encoding.ASCII.GetBytes(contentString);
                        MemoryStream mstream = new MemoryStream(byteArray);
                        content = Serializer.Deserialize<HTML_Based_Content>(mstream);
                        break;

                    case Microservice_Endpoint_Protocol_Enum.XML:
                        byte[] byteArray2 = Encoding.UTF8.GetBytes(contentString);
                        MemoryStream mstream2 = new MemoryStream(byteArray2);
                        XmlSerializer x = new XmlSerializer(typeof(Content));
                        content = (HTML_Based_Content)x.Deserialize(mstream2);
                        break;
                }
            }
            catch (Exception ee)
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "Unable to deserialize 'Content' parameter to HTML_Based_Content: " + ee.Message), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            // If content wasnot successfully deserialized, return error
            if ( content == null )
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "Unable to deserialize 'Content' parameter to HTML_Based_Content"), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            // Level1 must be neither NULL nor empty
            if (String.IsNullOrEmpty(content.Level1))
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "Level1 of the content cannot be null or empty"), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            // Valiodate the web content id in the URL matches the object
            if (webcontentId != content.WebContentID)
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.InputError, "WebContentID from URL does not match Content posted object"), Response, Protocol, null);
                Response.StatusCode = 400;
                return;
            }

            // You can't change the URL segments, so pull the current object to ensure that wasn't done
            HTML_Based_Content currentContent = CachedDataManager.WebContent.Retrieve_Page_Details(webcontentId, tracer);

            // If nothing was retrieved, build it
            if (currentContent == null)
            {
                // Try to read and return the html based content
                // Get the details from the database
                WebContent_Basic_Info basicInfo = Engine_Database.WebContent_Get_Page(webcontentId, tracer);
                if (basicInfo == null)
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("Unable to pull web content data from the database");
                    Response.StatusCode = 500;
                    return;
                }

                // Set the content levels from the database object
                content.Level1 = basicInfo.Level1;
                content.Level2 = basicInfo.Level2;
                content.Level3 = basicInfo.Level3;
                content.Level4 = basicInfo.Level4;
                content.Level5 = basicInfo.Level5;
                content.Level6 = basicInfo.Level6;
                content.Level7 = basicInfo.Level7;
                content.Level8 = basicInfo.Level8;

                // If this has a redirect, return
                if (!String.IsNullOrEmpty(basicInfo.Redirect))
                {
                    currentContent = new HTML_Based_Content
                    {
                        Title = basicInfo.Title,
                        Level1 = basicInfo.Level1,
                        Level2 = basicInfo.Level2,
                        Level3 = basicInfo.Level3,
                        Level4 = basicInfo.Level4,
                        Level5 = basicInfo.Level5,
                        Level6 = basicInfo.Level6,
                        Level7 = basicInfo.Level7,
                        Level8 = basicInfo.Level8,
                        Locked = basicInfo.Locked,
                        Description = basicInfo.Summary,
                        Redirect = basicInfo.Redirect,
                        WebContentID = basicInfo.WebContentID
                    };
                }
                else
                {
                    // Build the HTML content
                    WebContentEndpointErrorEnum errorType;
                    currentContent = read_source_file(basicInfo, tracer, out errorType);
                }
            }

            // If the current value was pulled, determine what has been changed for the database note
            string changeMessage = "Updated web page";
            if (currentContent != null)
            {
                // If the redirect changed, just make that the message
                string currRedirect = String.Empty;
                string newRedirect = String.Empty;
                if (!String.IsNullOrEmpty(content.Redirect)) newRedirect = content.Redirect;
                if (!String.IsNullOrEmpty(currentContent.Redirect)) currRedirect = currentContent.Redirect;
                if (String.Compare(newRedirect, currRedirect, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    if ((newRedirect.Length > 0) && (currRedirect.Length > 0))
                    {
                        changeMessage = "Changed redirect URL";
                    }
                    else if ( newRedirect.Length == 0 )
                    {
                        changeMessage = "Removed redirect URL";
                    }
                    else
                    {
                        changeMessage = "Added redirect URL";
                    }
                }
                else if (!AreEqual(content.ContentSource, currentContent.ContentSource))
                {
                    changeMessage = "Updated the text/html";
                }
                else
                {
                    List<string> updatesBuilderList = new List<string>();
                    if (!AreEqual(content.Author, currentContent.Author)) updatesBuilderList.Add("Author");
                    if (!AreEqual(content.Banner, currentContent.Banner)) updatesBuilderList.Add("Banner");
                    if (!AreEqual(content.CssFile, currentContent.CssFile)) updatesBuilderList.Add("Stylesheet");
                    if (!AreEqual(content.Description, currentContent.Description)) updatesBuilderList.Add("Description");
                    if (!AreEqual(content.Extra_Head_Info, currentContent.Extra_Head_Info)) updatesBuilderList.Add("Header Data");
                    if (!AreEqual(content.JavascriptFile, currentContent.JavascriptFile)) updatesBuilderList.Add("Javascript");
                    if (!AreEqual(content.Keywords, currentContent.Keywords)) updatesBuilderList.Add("Keywords");
                    if (!AreEqual(content.SiteMap, currentContent.SiteMap)) updatesBuilderList.Add("Tree Nav Group");
                    if (!AreEqual(content.Title, currentContent.Title)) updatesBuilderList.Add("Title");
                    if (!AreEqual(content.Web_Skin, currentContent.Web_Skin)) updatesBuilderList.Add("Web Skin");

                    if (updatesBuilderList.Count > 0)
                    {
                        if (updatesBuilderList.Count == 1)
                        {
                            changeMessage = "Updated the " + updatesBuilderList[0];
                        }
                        if (updatesBuilderList.Count == 2)
                        {
                            changeMessage = "Updated the " + updatesBuilderList[0] + " and " + updatesBuilderList[1];
                        }
                        if (updatesBuilderList.Count > 2)
                        {
                            StringBuilder updatesBuilder = new StringBuilder("Updated the ");
                            for (int i = 0; i < updatesBuilderList.Count; i++)
                            {
                                if (i == 0)
                                    updatesBuilder.Append(updatesBuilderList[0]);
                                else if (i < updatesBuilderList.Count - 1)
                                {
                                    updatesBuilder.Append(", " + updatesBuilderList[i]);
                                }
                                else
                                {
                                    updatesBuilder.Append(", and " + updatesBuilderList[i]);
                                }
                            }
                            changeMessage = updatesBuilder.ToString();
                        }
                    }
                }
            }

            // Get the location for this HTML file to be saved
            StringBuilder dirBuilder = new StringBuilder(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent\\" + content.Level1);
            if (!String.IsNullOrEmpty(content.Level2))
            {
                dirBuilder.Append("\\" + content.Level2);
                if (!String.IsNullOrEmpty(content.Level3))
                {
                    dirBuilder.Append("\\" + content.Level3);
                    if (!String.IsNullOrEmpty(content.Level4))
                    {
                        dirBuilder.Append("\\" + content.Level4);
                        if (!String.IsNullOrEmpty(content.Level5))
                        {
                            dirBuilder.Append("\\" + content.Level5);
                            if (!String.IsNullOrEmpty(content.Level6))
                            {
                                dirBuilder.Append("\\" + content.Level6);
                                if (!String.IsNullOrEmpty(content.Level7))
                                {
                                    dirBuilder.Append("\\" + content.Level7);
                                    if (!String.IsNullOrEmpty(content.Level8))
                                    {
                                        dirBuilder.Append("\\" + content.Level8);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Ensure this directory exists
            if (!Directory.Exists(dirBuilder.ToString()))
            {
                try
                {
                    Directory.CreateDirectory(dirBuilder.ToString());
                }
                catch (Exception)
                {
                    Serialize(new RestResponseMessage(ErrorRestTypeEnum.Exception, "Unable to create the directory for this web content page"), Response, Protocol, null);
                    Response.StatusCode = 500;
                    return;
                }
            }

            // Save the HTML file to the file system
            try
            {
                string fileName = Path.Combine(dirBuilder.ToString(), "default.html");

                // Make a backup from today, if none made yet
                if (File.Exists(fileName))
                {
                    DateTime lastWrite = (new FileInfo(fileName)).LastWriteTime;
                    string new_file = fileName.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(fileName, new_file);
                }

                // Save the updated file
                content.Save_To_File(fileName);
            }
            catch (Exception)
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.Exception, "Unable to save HTML file for this web content page"), Response, Protocol, null);
                Response.StatusCode = 500;
                return;
            }

            // Save to the database
            bool success;
            try
            {
                success = Engine_Database.WebContent_Edit_Page(webcontentId, content.Title, content.Description, content.Redirect, user, changeMessage, tracer);
                Engine_ApplicationCache_Gateway.WebContent_Hierarchy.Add_Single_Node(webcontentId, content.Redirect, content.Level1, content.Level2, content.Level3, content.Level4, content.Level5, content.Level6, content.Level7, content.Level8);
            }
            catch (Exception)
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.Exception, "Unable to save the information for the web content page to the database"), Response, Protocol, null);
                Response.StatusCode = 500;
                return;
            }

            // Clear the cache
            CachedDataManager.WebContent.Clear_Page_Details(webcontentId);

            // If this was a failure, return a message
            if (!success)
            {
                Serialize(new RestResponseMessage(ErrorRestTypeEnum.Exception, "Unable to save the updated information to the database"), Response, Protocol, null);
                Response.StatusCode = 500;
                return;
            }

            // Build return value
            RestResponseMessage message = new RestResponseMessage(ErrorRestTypeEnum.Successful, "Updated web page details");

            // Set the URL
            StringBuilder urlBuilder = new StringBuilder(Engine_ApplicationCache_Gateway.Settings.Servers.Base_URL + "/" + content.Level1);
            if (!String.IsNullOrEmpty(content.Level2))
            {
                urlBuilder.Append("/" + content.Level2);
                if (!String.IsNullOrEmpty(content.Level3))
                {
                    urlBuilder.Append("/" + content.Level3);
                    if (!String.IsNullOrEmpty(content.Level4))
                    {
                        urlBuilder.Append("/" + content.Level4);
                        if (!String.IsNullOrEmpty(content.Level5))
                        {
                            urlBuilder.Append("/" + content.Level5);
                            if (!String.IsNullOrEmpty(content.Level6))
                            {
                                urlBuilder.Append("/" + content.Level6);
                                if (!String.IsNullOrEmpty(content.Level7))
                                {
                                    urlBuilder.Append("/" + content.Level7);
                                    if (!String.IsNullOrEmpty(content.Level8))
                                    {
                                        urlBuilder.Append("/" + content.Level8);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            message.URI = urlBuilder.ToString();

            // Use the base class to serialize the object according to request protocol
            Serialize(message, Response, Protocol, null);
        }
        /// <summary> Constructor for a new instance of the WebContent_Add_New_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public WebContent_Add_New_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            RequestSpecificValues.Tracer.Add_Trace("WebContent_Add_New_AdminViewer.Constructor", String.Empty);

            // Set some defaults
            actionMessage = String.Empty;

            // Ensure the user is the system admin or portal admin
            if ((RequestSpecificValues.Current_User == null) || ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Portal_Admin)))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // If this is posted back, look for the reset
            if (RequestSpecificValues.Current_Mode.isPostBack)
            {
                // Pull the standard values
                NameValueCollection form = HttpContext.Current.Request.Form;

                // Get the values from the form
                if (form["admin_webcontent_title"] != null) title = form["admin_webcontent_title"];
                if (form["admin_webcontent_desc"] != null) description = form["admin_webcontent_desc"];
                if (form["admin_webcontent_redirect"] != null) redirect_url = form["admin_webcontent_redirect"];
                if (form["admin_webcontent_skin"] != null) webSkin = form["admin_webcontent_skin"];
                inheritFromParent = form["admin_webcontent_inherit"] != null;

                // Get the level values from the form
                if ((form["admin_webcontent_level1"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level1"])))
                {
                    level1 = form["admin_webcontent_level1"];
                    if ((form["admin_webcontent_level2"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level2"])))
                    {
                        level2 = form["admin_webcontent_level2"];
                        if ((form["admin_webcontent_level3"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level3"])))
                        {
                            level3 = form["admin_webcontent_level3"];
                            if ((form["admin_webcontent_level4"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level4"])))
                            {
                                level4 = form["admin_webcontent_level4"];
                                if ((form["admin_webcontent_level5"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level5"])))
                                {
                                    level5 = form["admin_webcontent_level5"];
                                    if ((form["admin_webcontent_level6"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level6"])))
                                    {
                                        level6 = form["admin_webcontent_level6"];
                                        if ((form["admin_webcontent_level7"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level7"])))
                                        {
                                            level7 = form["admin_webcontent_level7"];
                                            if ((form["admin_webcontent_level8"] != null) && (!String.IsNullOrEmpty(form["admin_webcontent_level8"])))
                                            {
                                                level8 = form["admin_webcontent_level8"];
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // Perform validation
                actionMessage = String.Empty;
                if ((String.IsNullOrEmpty(title)) || (String.IsNullOrEmpty(level1)))
                {
                    actionMessage = "Error - required fields are missing<br />";
                    if (String.IsNullOrEmpty(title))
                        actionMessage = actionMessage + " &nbsp; &nbsp; &nbsp; TITLE is a required field.<br />";
                    if (String.IsNullOrEmpty(level1))
                        actionMessage = actionMessage + " &nbsp; &nbsp; &nbsp; LEVEL1 is a required field.<br />";
                }

                string save_value = HttpContext.Current.Request.Form["admin_webcontent_save"];
                if ((!String.IsNullOrEmpty(save_value)) && (save_value == "save"))
                {
                    // Just ensure everything is emptied out
                    if (String.IsNullOrEmpty(actionMessage))
                    {
                        // Build this web content page
                        HTML_Based_Content newContent = new HTML_Based_Content
                        {
                            WebContentID = -1,
                            Level1 = level1,
                            Level2 = level2,
                            Level3 = level3,
                            Level4 = level4,
                            Level5 = level5,
                            Level6 = level6,
                            Level7 = level7,
                            Level8 = level8,
                            Title = title,
                            Description = description,
                            Web_Skin = webSkin,
                            Author = RequestSpecificValues.Current_User.Full_Name,
                            Date = DateTime.Now.ToShortDateString()
                        };

                        if (!String.IsNullOrEmpty(description))
                        {
                            newContent.Content = "<h2>" + title + "</h2>" + Environment.NewLine + "<p>" + description + "</p>";
                        }
                        else
                        {
                            newContent.Content = "<h2>" + title + "</h2>" + Environment.NewLine + "<p>New web content page text goes here.</p>";
                        }
                        newContent.ContentSource = newContent.Content;

                        // Call the engine endpoint to put this
                        RestResponseMessage msg = SobekEngineClient.WebContent.Add_HTML_Based_Content(newContent, RequestSpecificValues.Current_User.Full_Name, inheritFromParent, RequestSpecificValues.Tracer);

                        // Clear the hierarchy
                        CachedDataManager.WebContent.Clear_Hierarchy();
                        UI_ApplicationCache_Gateway.WebContent_Hierarchy_Clear();

                        // If successful, just send to it
                        if (msg != null)
                        {
                            if (msg.ErrorTypeEnum == ErrorRestTypeEnum.Successful)
                            {
                                if (String.IsNullOrEmpty(msg.URI))
                                {
                                    actionMessage = "Page added, but new URI was not returned";
                                }
                                else
                                {
                                    RequestSpecificValues.Current_Mode.Request_Completed = true;
                                    HttpContext.Current.Response.Redirect(msg.URI, false);
                                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                                    return;
                                }
                            }
                            else
                            {
                                actionMessage = "ERROR: " + msg.Message;
                            }
                        }
                        else
                        {
                            actionMessage = "ERROR: Exception deserializing the REST response message.";
                        }

                    }
                }
            }
            else
            {
                // Get any level filter information from the query string
                if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l1"]))
                {
                    level1 = HttpContext.Current.Request.QueryString["l1"];

                    if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l2"]))
                    {
                        level2 = HttpContext.Current.Request.QueryString["l2"];

                        if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l3"]))
                        {
                            level3 = HttpContext.Current.Request.QueryString["l3"];

                            if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l4"]))
                            {
                                level4 = HttpContext.Current.Request.QueryString["l4"];

                                if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l5"]))
                                {
                                    level5 = HttpContext.Current.Request.QueryString["l5"];
                                    if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l6"]))
                                    {
                                        level6 = HttpContext.Current.Request.QueryString["l6"];
                                        if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l7"]))
                                        {
                                            level7 = HttpContext.Current.Request.QueryString["l7"];
                                            if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["l8"]))
                                            {
                                                level8 = HttpContext.Current.Request.QueryString["l8"];
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary> Add the HTML to be displayed below the search box </summary>
        /// <param name="Output"> Textwriter to write the HTML for this viewer</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> This writes the HTML from the static browse or info page here  </remarks>
        public override void Add_Secondary_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("Metadata_Browse_AggregationViewer.Add_Secondary_HTML", "Adding HTML");
            }

            // Get collection of (public) browse bys linked to this aggregation
            ReadOnlyCollection<Item_Aggregation_Child_Page> public_browses = ViewBag.Hierarchy_Object.Browse_By_Pages;

            // Determine if this is an internal user and create list of internal user browses
            List<string> internal_browses = new List<string>();
            if ((RequestSpecificValues.Current_User != null) && ((RequestSpecificValues.Current_User.Is_Internal_User) || (RequestSpecificValues.Current_User.Is_Aggregation_Curator(RequestSpecificValues.Current_Mode.Aggregation))))
            {
                // Just add every metadata field here
                foreach (Item_Aggregation_Metadata_Type field in ViewBag.Hierarchy_Object.Browseable_Fields  )
                {
                    internal_browses.Add(field.DisplayTerm);
                }
            }

            // Retain the original short code (or the first public code)
            string original_browse_mode = RequestSpecificValues.Current_Mode.Info_Browse_Mode.ToLower();

            // Get any paging URL and retain original page
            int current_page = RequestSpecificValues.Current_Mode.Page.HasValue ? RequestSpecificValues.Current_Mode.Page.Value : 1;
            RequestSpecificValues.Current_Mode.Page = 1;
            string page_url = UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode, false);
            string url_options = UrlWriterHelper.URL_Options(RequestSpecificValues.Current_Mode);
            if (url_options.Length > 0)
                url_options = "?" + url_options.Replace("&", "&amp");

            if ((public_browses.Count > 1) || (internal_browses.Count > 0 ))
            {
                Output.WriteLine("<table>");
                Output.WriteLine("<tr style=\"vertical-align:top;\">");
                Output.WriteLine("<td id=\"sbkMebv_FacetOuterColumn\">");
                Output.WriteLine("<div class=\"sbkMebv_FacetColumn\">");
                Output.WriteLine("<div class=\"sbkMebv_FacetColumnTitle\">BROWSE BY:</div>");
                Output.WriteLine("<br />");

                if (public_browses.Count > 0)
                {
                    // Sort these by title
                    SortedList<string, Item_Aggregation_Child_Page> sortedBrowses = new SortedList<string, Item_Aggregation_Child_Page>();
                    foreach (Item_Aggregation_Child_Page thisBrowse in public_browses)
                    {
                        if (thisBrowse.Source_Data_Type == Item_Aggregation_Child_Source_Data_Enum.Static_HTML)
                        {
                            sortedBrowses[thisBrowse.Code.ToLower()] = thisBrowse;
                        }
                        else
                        {
                            Metadata_Search_Field facetField = UI_ApplicationCache_Gateway.Settings.Metadata_Search_Field_By_Name(thisBrowse.Code);
                            if (facetField != null)
                            {
                                string facetName = facetField.Display_Term;

                                if (internal_browses.Contains(facetName))
                                    internal_browses.Remove(facetName);

                                sortedBrowses[facetName.ToLower()] = thisBrowse;
                            }
                        }
                    }

                    Output.WriteLine(internal_browses.Count > 0 ? "<b> &nbsp;Public Browses</b><br />" : "<b> &nbsp;Browses</b><br />");

                    Output.WriteLine("<div class=\"sbkMebv_FacetBox\">");
                    foreach (Item_Aggregation_Child_Page thisBrowse in sortedBrowses.Values)
                    {
                        // Static HTML or metadata browse by?
                        if (thisBrowse.Source_Data_Type == Item_Aggregation_Child_Source_Data_Enum.Static_HTML)
                        {
                            if (original_browse_mode != thisBrowse.Code)
                            {
                                RequestSpecificValues.Current_Mode.Info_Browse_Mode = thisBrowse.Code;
                                Output.WriteLine("<a href=\"" + UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode).Replace("&", "&amp") + "\">" + thisBrowse.Label + "</a><br />");
                            }
                            else
                            {
                                Output.WriteLine(thisBrowse.Label + "<br />");
                            }
                        }
                        else
                        {
                            Metadata_Search_Field facetField = UI_ApplicationCache_Gateway.Settings.Metadata_Search_Field_By_Display_Name(thisBrowse.Code);
                            if (thisBrowse.Code.ToLower().Replace("_", " ") != original_browse_mode.Replace("_", " "))
                            {
                                RequestSpecificValues.Current_Mode.Info_Browse_Mode = thisBrowse.Code.ToLower().Replace(" ", "_");
                                Output.WriteLine("<a href=\"" + UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode).Replace("&", "&amp") + "\">" + facetField.Display_Term + "</a><br />");
                            }
                            else
                            {
                                Output.WriteLine(facetField.Display_Term + "<br />");
                            }
                        }
                    }

                    Output.WriteLine("</div>");
                    Output.WriteLine("<br />");
                }

                if (internal_browses.Count > 0)
                {
                    Output.WriteLine("<b> &nbsp;Internal Browses</b><br />");
                    Output.WriteLine("<div class=\"sbkMebv_FacetBox\">");

                    foreach (string thisShort in internal_browses)
                    {
                        Metadata_Search_Field facetField = UI_ApplicationCache_Gateway.Settings.Metadata_Search_Field_By_Facet_Name(thisShort);
                        if (facetField != null)
                        {
                            if (thisShort.ToLower() != original_browse_mode)
                            {
                                RequestSpecificValues.Current_Mode.Info_Browse_Mode = thisShort.ToLower().Replace(" ", "_");
                                Output.WriteLine("<a href=\"" + UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode).Replace("&", "&amp") + "\">" + facetField.Display_Term + "</a><br />");
                            }
                            else
                            {
                                Output.WriteLine(facetField.Display_Term + "<br />");
                            }
                        }
                    }

                    Output.WriteLine("</div>");
                    Output.WriteLine("<br />");
                }
                Output.WriteLine("<br />");
                Output.WriteLine("<br />");
                Output.WriteLine("<br />");
                Output.WriteLine("<br />");
                Output.WriteLine("<br />");
                Output.WriteLine("</div>");
                Output.WriteLine("</td>");
                Output.WriteLine("<td>");
            }
            Output.WriteLine("<div class=\"sbkMebv_ResultsPanel\" id=\"main-content\" role=\"main\">");

            RequestSpecificValues.Current_Mode.Info_Browse_Mode = original_browse_mode;

            // Was this static or metadata browse by?
            if ((browseObject != null) && (browseObject.Source_Data_Type == Item_Aggregation_Child_Source_Data_Enum.Static_HTML))
            {
                // Read the content file for this browse
                string source_file = UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + ViewBag.Hierarchy_Object.ObjDirectory.Replace("/", "\\") + browseObject.Source;
                HTML_Based_Content staticBrowseContent = HTML_Based_Content_Reader.Read_HTML_File( source_file, true, Tracer );
                if (staticBrowseContent == null)
                {
                    staticBrowseContent = new HTML_Based_Content("Unable to find source file!\n\n" + ViewBag.Hierarchy_Object.ObjDirectory.Replace("/", "\\") + browseObject.Source, browseObject.Code );
                }

                // Apply current user settings for this
                string browseInfoDisplayText = staticBrowseContent.Apply_Settings_To_Static_Text(staticBrowseContent.Content, ViewBag.Hierarchy_Object, RequestSpecificValues.HTML_Skin.Skin_Code, RequestSpecificValues.HTML_Skin.Base_Skin_Code, RequestSpecificValues.Current_Mode.Base_URL, UrlWriterHelper.URL_Options(RequestSpecificValues.Current_Mode), Tracer);

                // Is this an admin?
                bool isAdmin = (RequestSpecificValues.Current_User != null) && (RequestSpecificValues.Current_User.Is_Aggregation_Admin(ViewBag.Hierarchy_Object.Code));
                Aggregation_Type_Enum aggrType = RequestSpecificValues.Current_Mode.Aggregation_Type;

                // Output the adjusted home html
                if (isAdmin)
                {
                    Output.WriteLine("<div id=\"sbkSbia_MainTextEditable\">");
                    Output.WriteLine(browseInfoDisplayText);
                    RequestSpecificValues.Current_Mode.Aggregation_Type = Aggregation_Type_Enum.Child_Page_Edit;
                    Output.WriteLine("  <div id=\"sbkSbia_EditableTextLink\"><a href=\"" + UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode) + "\" title=\"Edit this page's text\"><img src=\"" + Static_Resources_Gateway.Edit_Gif + "\" alt=\"\" />edit content</a></div>");
                    RequestSpecificValues.Current_Mode.Aggregation_Type = aggrType;
                    Output.WriteLine("</div>");
                    Output.WriteLine();

                    Output.WriteLine("<script>");
                    Output.WriteLine("  $(\"#sbkSbia_MainTextEditable\").mouseover(function() { $(\"#sbkSbia_EditableTextLink\").css(\"display\",\"inline-block\"); });");
                    Output.WriteLine("  $(\"#sbkSbia_MainTextEditable\").mouseout(function() { $(\"#sbkSbia_EditableTextLink\").css(\"display\",\"none\"); });");
                    Output.WriteLine("</script>");
                    Output.WriteLine();

                }
                else
                {
                    Output.WriteLine("<div id=\"sbkSbia_MainText\">");
                    Output.WriteLine(browseInfoDisplayText);
                    Output.WriteLine("</div>");
                }
            }
            else
            {

                //Output the results
                if (( results != null ) && (results.Count > 0))
                {
                    // Determine which letters appear
                    List<char> letters_appearing = new List<char>();
                    char last_char = '\n';
                    if (results.Count > 100)
                    {
                        foreach (string thisValue in results)
                        {
                            if (thisValue.Length > 0)
                            {
                                char this_first_char = Char.ToLower(thisValue[0]);
                                int ascii = this_first_char;

                                if (ascii < 97)
                                    this_first_char = 'a';
                                if (ascii > 122)
                                    this_first_char = 'z';

                                if (this_first_char != last_char)
                                {
                                    if (!letters_appearing.Contains(this_first_char))
                                    {
                                        letters_appearing.Add(this_first_char);
                                    }
                                    last_char = this_first_char;
                                }
                            }
                        }
                    }

                    // Get the search URL
                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Results;
                    RequestSpecificValues.Current_Mode.Search_Precision = Search_Precision_Type_Enum.Exact_Match;
                    RequestSpecificValues.Current_Mode.Search_Type = Search_Type_Enum.Advanced;
                    Metadata_Search_Field facetField = UI_ApplicationCache_Gateway.Settings.Metadata_Search_Field_By_Display_Name(original_browse_mode);
                    RequestSpecificValues.Current_Mode.Search_Fields = facetField.Web_Code;
                    RequestSpecificValues.Current_Mode.Search_String = "\"<%TERM%>\"";
                    string search_url = UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode);

                    Output.WriteLine("<br />");

                    if (results.Count < 100)
                    {
                        foreach (string thisResult in results)
                        {
                            Output.WriteLine("<a href=\"" + search_url.Replace("%3c%25TERM%25%3e", thisResult.Trim().Replace(",", "%2C").Replace("&", "%26").Replace("\"", "%22").Replace("&", "&amp")) + "\">" + thisResult.Replace("\"", "&quot;").Replace("&", "&amp;") + "</a><br />");
                        }
                    }
                    else if (results.Count < 500)
                    {
                        // Determine the actual page first
                        int first_valid_page = -1;
                        if ((letters_appearing.Contains('a')) || (letters_appearing.Contains('b')))
                        {
                            first_valid_page = 1;
                        }

                        if ((letters_appearing.Contains('c')) || (letters_appearing.Contains('d')) || (letters_appearing.Contains('e')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 2;
                        }

                        if ((letters_appearing.Contains('f')) || (letters_appearing.Contains('g')) || (letters_appearing.Contains('h')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 3;
                        }

                        if ((letters_appearing.Contains('i')) || (letters_appearing.Contains('j')) || (letters_appearing.Contains('k')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 4;
                        }

                        if ((letters_appearing.Contains('l')) || (letters_appearing.Contains('m')) || (letters_appearing.Contains('n')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 5;
                        }

                        if ((letters_appearing.Contains('o')) || (letters_appearing.Contains('p')) || (letters_appearing.Contains('q')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 6;
                        }

                        if ((letters_appearing.Contains('r')) || (letters_appearing.Contains('s')) || (letters_appearing.Contains('t')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 7;
                        }

                        if ((letters_appearing.Contains('u')) || (letters_appearing.Contains('v')) || (letters_appearing.Contains('w')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 8;
                        }

                        if ((letters_appearing.Contains('x')) || (letters_appearing.Contains('y')) || (letters_appearing.Contains('z')))
                        {
                            if (first_valid_page < 0)
                                first_valid_page = 9;
                        }

                        // Define the limits of the page value
                        if ((current_page < first_valid_page) || (current_page > 9))
                            current_page = first_valid_page;

                        // Add the links for paging through results
                        Output.WriteLine("<div class=\"sbkMebv_NavRow\">");
                        if ((letters_appearing.Contains('a')) || (letters_appearing.Contains('b')))
                        {
                            if (current_page == 1)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">AB</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/1" + url_options + "\" class=\"mbb1\">AB</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">AB</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('c')) || (letters_appearing.Contains('d')) || (letters_appearing.Contains('e')))
                        {
                            if (current_page == 2)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">CDE</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/2" + url_options + "\">CDE</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">CDE</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('f')) || (letters_appearing.Contains('g')) || (letters_appearing.Contains('h')))
                        {
                            if (current_page == 3)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">FGH</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/3" + url_options + "\">FGH</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">FGH</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('i')) || (letters_appearing.Contains('j')) || (letters_appearing.Contains('k')))
                        {
                            if (current_page == 4)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">IJK</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/4" + url_options + "\">IJK</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">IJK</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('l')) || (letters_appearing.Contains('m')) || (letters_appearing.Contains('n')))
                        {
                            if (current_page == 5)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">LMN</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/5" + url_options + "\">LMN</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">LMN</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('o')) || (letters_appearing.Contains('p')) || (letters_appearing.Contains('q')))
                        {
                            if (current_page == 6)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">OPQ</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/6" + url_options + "\">OPQ</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">OPQ</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('r')) || (letters_appearing.Contains('s')) || (letters_appearing.Contains('t')))
                        {
                            if (current_page == 7)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">RST</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/7" + url_options + "\">RST</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">RST</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('u')) || (letters_appearing.Contains('v')) || (letters_appearing.Contains('w')))
                        {
                            if (current_page == 8)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">UVW</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/8" + url_options + "\">UVW</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\">UVW</span> &nbsp; ");
                        }

                        if ((letters_appearing.Contains('x')) || (letters_appearing.Contains('y')) || (letters_appearing.Contains('z')))
                        {
                            if (current_page == 9)
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">XYZ</span> &nbsp; ");
                            }
                            else
                            {
                                Output.WriteLine("<a href=\"" + page_url + "/9" + url_options + "\">XYZ</a> &nbsp; ");
                            }
                        }
                        else
                        {
                            Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\" >XYZ</span> &nbsp; ");
                        }

                        Output.WriteLine("</div>");

                        Output.WriteLine("<br />");
                        Output.WriteLine("<br />");

                        // Find the start character and last character, per the page
                        char first_char = ' ';
                        char stop_char = 'c';
                        switch (current_page)
                        {
                            case 2:
                                first_char = 'c';
                                stop_char = 'f';
                                break;

                            case 3:
                                first_char = 'f';
                                stop_char = 'i';
                                break;

                            case 4:
                                first_char = 'i';
                                stop_char = 'l';
                                break;

                            case 5:
                                first_char = 'l';
                                stop_char = 'o';
                                break;

                            case 6:
                                first_char = 'o';
                                stop_char = 'r';
                                break;

                            case 7:
                                first_char = 'r';
                                stop_char = 'u';
                                break;

                            case 8:
                                first_char = 'u';
                                stop_char = 'x';
                                break;

                            case 9:
                                first_char = 'x';
                                stop_char = '}';
                                break;
                        }

                        // Add the pertinent rows
                        foreach (string thisValue in results)
                        {
                            if (thisValue.Length > 0)
                            {
                                char this_first_char = Char.ToLower(thisValue[0]);
                                if ((this_first_char >= first_char) && (this_first_char < stop_char))
                                {
                                    Output.WriteLine("<a href=\"" + search_url.Replace("%3c%25TERM%25%3e", thisValue.Trim().Replace(",", "%2C").Replace("&", "%26").Replace("\"", "%22")).Replace("&","&amp;") + "\">" + thisValue.Replace("\"", "&quot;").Replace("&","&amp;") + "</a><br />");
                                }
                            }
                        }

                    }
                    else
                    {
                        // Determine the first valid page
                        char label_char = 'a';
                        int first_valid_page = -1;
                        int counter = 1;
                        while (label_char <= 'z')
                        {
                            if (letters_appearing.Contains(label_char))
                            {
                                if (first_valid_page < 0)
                                    first_valid_page = counter;
                            }

                            counter++;
                            label_char = (char)((label_char) + 1);
                        }

                        // Define the limits of the page value
                        if ((current_page < first_valid_page) || (current_page > 26))
                            current_page = first_valid_page;

                        // Add the links for paging through results
                        label_char = 'a';
                        counter = 1;
                        Output.WriteLine("<div class=\"sbkMebv_NavRow\">");
                        while (label_char <= 'z')
                        {
                            if (letters_appearing.Contains(label_char))
                            {
                                if (current_page == counter)
                                {
                                    Output.WriteLine("<span class=\"sbkMebv_NavRowCurrent\">" + Char.ToUpper(label_char) + "</span>&nbsp;");
                                }
                                else
                                {
                                    Output.WriteLine("<a href=\"" + page_url + "/" + counter + url_options + "\" >" + Char.ToUpper(label_char) + "</a>&nbsp;");

                                }

                            }
                            else
                            {
                                Output.WriteLine("<span class=\"sbkMebv_NavRowDisabled\" >" + Char.ToUpper(label_char) + "</span>&nbsp;");
                            }

                            counter++;
                            label_char = (char)((label_char) + 1);
                        }
                        Output.WriteLine("</div>");

                        Output.WriteLine("<br />");
                        Output.WriteLine("<br />");

                        // Find the start character and last character, per the page
                        char first_char = ' ';
                        char stop_char = 'b';
                        if (current_page > 1)
                        {
                            first_char = (char)(96 + current_page);
                            stop_char = (char)(97 + current_page);

                        }

                        // Add the pertinent rows
                        foreach (string thisValue in results)
                        {
                            if (thisValue.Length > 0)
                            {
                                char this_first_char = Char.ToLower(thisValue[0]);
                                if ((this_first_char >= first_char) && (this_first_char < stop_char))
                                {
                                    Output.WriteLine("<a href=\"" + search_url.Replace("%3c%25TERM%25%3e", thisValue.Trim().Replace(",", "%2C").Replace("&", "%26").Replace("\"", "%22")).Replace("&", "&amp;") + "\">" + thisValue.Replace("\"", "&quot;").Replace("&", "&amp;") + "</a><br />");
                                }
                            }
                        }
                    }
                }
                else
                {
                    Output.WriteLine("<br /><br /><br /><br />");
                    Output.WriteLine(RequestSpecificValues.Current_Mode.Info_Browse_Mode.Length == 0 ? "<center>Select a metadata field to browse by from the list on the left</center>" : "<center>NO MATCHING VALUES</center>");
                    Output.WriteLine("<br /><br />");
                }
            }

            // Set the current mode back
            RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
            RequestSpecificValues.Current_Mode.Aggregation_Type = Aggregation_Type_Enum.Browse_By;

            Output.WriteLine("</div>");
            Output.WriteLine("<br />");

            if ((public_browses.Count > 1) || (internal_browses.Count > 0))
            {
                Output.WriteLine("</td>");
                Output.WriteLine("</tr>");
                Output.WriteLine("</table>");
            }
            Output.WriteLine();
        }
        /// <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(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;
            Simple_Web_Content = null;

            // Get the web content object
            if ((( Current_Mode.WebContentID.HasValue ) && ( Current_Mode.WebContentID.Value > 0 )) && (( !Current_Mode.Missing.HasValue ) || ( !Current_Mode.Missing.Value )))
                Simple_Web_Content = SobekEngineClient.WebContent.Get_HTML_Based_Content(Current_Mode.WebContentID.Value, true, Tracer);

            // If somehow this is null and this was for DEFAULT, just add the page
            if (Simple_Web_Content == null)
            {
                Simple_Web_Content = SobekEngineClient.WebContent.Get_Special_Missing_Page(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 this is a redirect, just return
            if (!String.IsNullOrEmpty(Simple_Web_Content.Redirect))
                return true;

            if ( String.IsNullOrEmpty(Simple_Web_Content.Content))
            {
                Current_Mode.Error_Message = "Unable to read the file for display";
                return false;
            }

            // Look for a site map
            if (!String.IsNullOrEmpty(Simple_Web_Content.SiteMap))
            {
                // Look in the cache first
                Site_Map = CachedDataManager.Retrieve_Site_Map(Simple_Web_Content.SiteMap, Tracer);

                // If this was NULL, pull it
                if (Site_Map == null)
                {
                    string sitemap_file = Simple_Web_Content.SiteMap;
                    if (!sitemap_file.ToLower().Contains(".sitemap"))
                        sitemap_file = sitemap_file + ".sitemap";

                    // Only continue if the file exists
                    if (File.Exists(UI_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent\\sitemaps\\" + sitemap_file))
                    {
                        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(UI_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent\\sitemaps\\" + sitemap_file);

                        // If the sitemap file was succesfully read, cache it
                        if (Site_Map != null)
                        {
                            CachedDataManager.Store_Site_Map(Site_Map, Simple_Web_Content.SiteMap, Tracer);
                        }
                    }
                    else if (File.Exists(UI_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent\\" + sitemap_file))
                    {
                        // This is just for some legacy material
                        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(UI_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design\\webcontent\\" + sitemap_file);

                        // If the sitemap file was succesfully read, cache it
                        if (Site_Map != null)
                        {
                            CachedDataManager.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.Content = Simple_Web_Content.Apply_Settings_To_Static_Text(Simple_Web_Content.Content, null, Current_Mode.Skin, Current_Mode.Base_Skin, Current_Mode.Base_URL, UrlWriterHelper.URL_Options(Current_Mode), Tracer);

            return true;
        }
        /// <summary>  Constructor for a new instance of the Delete_Verify_WebContentViewer class  </summary>
        /// <param name="RequestSpecificValues">  All the necessary, non-global data specific to the current request  </param>
        /// <param name="StaticPage"> Static page info for this request </param>
        public Delete_Verify_WebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage)
            : base(RequestSpecificValues, StaticPage)
        {
            // Pull the web content page
            if (RequestSpecificValues.Current_Mode.WebContentID.HasValue)
                webContent = SobekEngineClient.WebContent.Get_HTML_Based_Content(RequestSpecificValues.Current_Mode.WebContentID.Value, true, RequestSpecificValues.Tracer);

            // This should never occur, but just a double check
            if ((webContent == null) || (!webContent.WebContentID.HasValue))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Ensure there IS a logged on user
            RequestSpecificValues.Tracer.Add_Trace("Delete_Item_MySobekViewer.Delete_Verify_WebContentViewer", "Validate user");
            if ((RequestSpecificValues.Current_User == null) || (!RequestSpecificValues.Current_User.LoggedOn))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // If the user was logged on, but did not have permissions, show an error message
            canDelete = true;
            deleted = false;
            if (!webContent.Can_Delete(RequestSpecificValues.Current_User))
            {
                errorMessage = "ERROR: You do not have permission to delete this page";
                canDelete = false;
            }
            else if ( HttpContext.Current.Request.RequestType == "POST" )
            {
                string save_value = HttpContext.Current.Request.Form["admin_delete_item"];

                // Better say "DELETE", or just send back to the item
                if (( save_value != null ) && ( String.Compare(save_value,"DELETE", StringComparison.OrdinalIgnoreCase) == 0))
                {
                    string entered_value = HttpContext.Current.Request.Form["admin_delete_confirm"];
                    if ((entered_value == null) || (entered_value.ToUpper() != "DELETE"))
                    {
                        errorMessage = "ERROR: To verify this deletion, type DELETE into the text box and press CONFIRM";
                    }
                    else
                    {
                        string deleteReason = "Requested via web application";

                        RestResponseMessage message = SobekEngineClient.WebContent.Delete_HTML_Based_Content(webContent.WebContentID.Value, RequestSpecificValues.Current_User.Full_Name, deleteReason, RequestSpecificValues.Tracer);

                        errorMessage = message.Message;
                        if ((message.ErrorTypeEnum != ErrorRestTypeEnum.Successful) && (String.IsNullOrEmpty(errorMessage)))
                        {
                            errorMessage = "Error encountered on SobekCM engine.";
                        }
                        else
                        {
                            errorMessage = "Successfully deleted this web content page.";

                            // Clear cached data here on the client
                            CachedDataManager.WebContent.Clear_All_Web_Content_Lists();
                            CachedDataManager.WebContent.Clear_All_Web_Content_Pages();
                            CachedDataManager.WebContent.Clear_Page_Details();
                            UI_ApplicationCache_Gateway.WebContent_Hierarchy_Clear();

                            deleted = true;
                        }
                    }
                }

            }
        }
        private void Save_Child_Page_Postback(NameValueCollection Form)
        {
            string code = RequestSpecificValues.Current_Mode.My_Sobek_SubMode.Substring(2);
            Complete_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
                        {
                            Content = "<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,
                            Author = RequestSpecificValues.Current_User.Full_Name,
                            Date = DateTime.Now.ToLongDateString(),
                            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));

            }
            else
            {
                childPageVisibility = Form["admin_aggr_visibility"];
                childPage.Parent_Code = Form["admin_aggr_parent"];

                switch (childPageVisibility)
                {
                    case "none":
                        childPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.None;
                        break;

                    case "browse":
                        childPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.Main_Menu;
                        break;

                    case "browseby":
                        childPage.Browse_Type = Item_Aggregation_Child_Visibility_Enum.Metadata_Browse_By;
                        break;
                }
            }
        }
        /// <summary> Gets the browse or info object and any other needed data for display ( 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="CachedDataManager" /> to store in the cache </remarks>
        protected static bool Get_Browse_Info(Navigation_Object Current_Mode,
                                    Item_Aggregation Aggregation_Object,
                                    string Base_Directory,
                                    Custom_Tracer Tracer,
                                    out Item_Aggregation_Child_Page 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("abstractHtmlSubwriter.Get_Browse_Info", String.Empty);
            }

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

            // First, make sure the browse submode is valid
            Browse_Object = Aggregation_Object.Child_Page_By_Code(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.Source_Data_Type)
            {
                case Item_Aggregation_Child_Source_Data_Enum.Database_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.HasValue ? Math.Max(Current_Mode.Sort.Value, ((ushort)1)) : 1;
                    if ((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;
                    }

                    // Get the page count in the results
                    int current_page_index = Current_Mode.Page.HasValue ? Math.Max(Current_Mode.Page.Value, ((ushort)1)) : 1;

                    // 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 = 1000000;
                        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 = CachedDataManager.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 = CachedDataManager.Retrieve_Browse_Results(Aggregation_Object.Code, browse_code, current_page_index, 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
                            Multiple_Paged_Results_Args returnArgs = Item_Aggregation_Utilities.Get_Browse_Results(Aggregation_Object, Browse_Object, current_page_index, 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))
                            {
                                CachedDataManager.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))
                            {
                                CachedDataManager.Store_Browse_Results(Aggregation_Object.Code, browse_code, current_page_index, sort, pagesOfResults, Tracer);
                            }
                        }
                    }
                    break;

                case Item_Aggregation_Child_Source_Data_Enum.Static_HTML:
                    Browse_Info_Display_Text = SobekEngineClient.Aggregations.Get_Aggregation_HTML_Child_Page(Aggregation_Object.Code, Aggregation_Object.Language, UI_ApplicationCache_Gateway.Settings.System.Default_UI_Language, Browse_Object.Code, Tracer);
                    break;
            }
            return true;
        }
 /// <summary>  Constructor for a new instance of the User_Permissions_WebContentViewer class  </summary>
 /// <param name="RequestSpecificValues">  All the necessary, non-global data specific to the current request  </param>
 /// <param name="StaticPage"> Static page info for this request </param>
 public User_Permissions_WebContentViewer(RequestCache RequestSpecificValues, HTML_Based_Content StaticPage)
     : base(RequestSpecificValues, StaticPage)
 {
 }