Traces execution of a SobekCM query through construction of the various classes and rendering of HTML and controls
This class allows a trace route to be written at the bottom of the server HTML page
        /// <summary> Get the language-specific web skin, by skin code and language </summary>
        /// <param name="SkinCode"> Code for the web skin </param>
        /// <param name="RequestedLanguage"> Requested language for the web skin code </param>
        /// <param name="DefaultLanguage"> Default UI language for the instance </param>
        /// <param name="Cache_On_Build"> Flag indicates whether to use the cache </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <returns> Language-specific web skin object </returns>
        public Web_Skin_Object Get_LanguageSpecific_Web_Skin(string SkinCode, Web_Language_Enum RequestedLanguage, Web_Language_Enum DefaultLanguage, bool Cache_On_Build, Custom_Tracer Tracer)
        {
            // If no interface yet, look in the cache
            if ((SkinCode != "new") && (Cache_On_Build))
            {
                Web_Skin_Object htmlSkin = CachedDataManager.WebSkins.Retrieve_Skin(SkinCode, Web_Language_Enum_Converter.Enum_To_Code(RequestedLanguage), Tracer);
                if (htmlSkin != null)
                {
                    if (Tracer != null)
                    {
                        Tracer.Add_Trace("SobekEngineClient_WebSkinEndpoints.Get_LanguageSpecific_Web_Skin", "Web skin '" + SkinCode + "' found in cache");
                    }
                    return htmlSkin;
                }
            }

            // If still not interface, build one
            Web_Skin_Object new_skin = WebSkinServices.get_web_skin(SkinCode, RequestedLanguage, DefaultLanguage, Tracer);

            // Look in the web skin row and see if it should be kept around, rather than momentarily cached
            if ((new_skin != null) && ( String.IsNullOrEmpty(new_skin.Exception)))
            {
                if (Cache_On_Build)
                {
                    // Momentarily cache this web skin object
                    CachedDataManager.WebSkins.Store_Skin(SkinCode, Web_Language_Enum_Converter.Enum_To_Code(RequestedLanguage), new_skin, Tracer);
                }
            }

            return new_skin;
        }
        /// <summary> Stream to which to write the HTML for this subwriter  </summary>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public override void Write_Main_Viewer_Section(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("Feature_ItemViewer.Write_Main_Viewer_Section", "");
            }

            // Save the current viewer code
            string current_view_code = CurrentMode.ViewerCode;

            // Start the citation table
            Output.WriteLine("\t\t<!-- FEATURE VIEWER OUTPUT -->" );
            Output.WriteLine("\t\t<td align=\"left\" height=\"40px\" ><span class=\"SobekViewerTitle\"><b>Index of Features</b></span></td></tr>" );
            Output.WriteLine("\t\t<tr><td class=\"SobekDocumentDisplay\">");
            Output.WriteLine("\t\t\t<div class=\"SobekCitation\">");

            // Get the list of streets from the database
            //Map_Features_DataSet features = SobekCM_Database.Get_All_Features_By_Item( CurrentItem.Web.ItemID, Tracer );
            //Create_Feature_Index( Output, features );

            // Finish the citation table
            Output.WriteLine( "\t\t\t</div>"  );
            Output.WriteLine("\t\t</td>" );
            Output.WriteLine("\t\t<!-- END FEATURE VIEWER OUTPUT -->" );

            // Restore the mode
            CurrentMode.ViewerCode = current_view_code;
        }
        /// <summary> Aggregate all the item-level and item group-level hits up the hierarchy to the aggregations </summary>
        /// <param name="Year"> Year of this usage </param>
        /// <param name="Month"> Month of this usage </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <returns> TRUE if successfully aggregated, otherwise FALSE </returns>
        /// <remarks> This calls the 'SobekCM_Statistics_Aggregate' stored procedure </remarks> 
        public static string Aggregate_Statistics(int Year, int Month, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("Engine_Database.Aggregate_Statistics", "");
            }

            try
            {
                EalDbParameter[] parameters = new EalDbParameter[3];
                parameters[0] = new EalDbParameter("@statyear", Year);
                parameters[1] = new EalDbParameter("@statmonth", Month);
                EalDbParameter returnMsg = parameters[2] = new EalDbParameter("@message", Month);
                returnMsg.Direction = ParameterDirection.InputOutput;

                // Define a temporary dataset
                EalDbAccess.ExecuteNonQuery( DatabaseType, Connection_String, CommandType.StoredProcedure, "SobekCM_Statistics_Aggregate", parameters);

                return returnMsg.Value.ToString();
            }
            catch (Exception ee)
            {
                Last_Exception = ee;
                if (Tracer != null)
                {
                    Tracer.Add_Trace("Engine_Database.Aggregate_Statistics", "Exception caught during database work", Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Engine_Database.Aggregate_Statistics", ee.Message, Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Engine_Database.Aggregate_Statistics", ee.StackTrace, Custom_Trace_Type_Enum.Error);
                }
                return "Exception caught";
            }
        }
        /// <summary> Stream to which to write the HTML for this subwriter  </summary>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public override void Write_Main_Viewer_Section(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("EAD_Description_ItemViewer.Write_Main_Viewer_Section", "");
            }

            // Try to get the ead information
            EAD_Transfer_Object eadInfo = SobekEngineClient.Items.Get_Item_EAD(BriefItem.BibID, BriefItem.VID, true, Tracer);

            // Build the value
            Output.WriteLine("          <td>");
            Output.WriteLine("            <div id=\"sbkEad_MainArea\">");

            if ( !String.IsNullOrWhiteSpace(CurrentMode.Text_Search))
            {
                // Get any search terms
                List<string> terms = new List<string>();
                if (CurrentMode.Text_Search.Trim().Length > 0)
                {
                    string[] splitter = CurrentMode.Text_Search.Replace("\"", "").Split(" ".ToCharArray());
                    terms.AddRange(from thisSplit in splitter where thisSplit.Trim().Length > 0 select thisSplit.Trim());
                }

                Output.Write(Text_Search_Term_Highlighter.Hightlight_Term_In_HTML(eadInfo.Full_Description, terms));
            }
            else
            {
                Output.Write(eadInfo.Full_Description);
            }

            Output.WriteLine("            </div>");
            Output.WriteLine("          </td>");
        }
        /// <summary> This provides an opportunity for the viewer to perform any pre-display work
        /// which is necessary before entering any of the rendering portions </summary>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <remarks> This methods pulls the text to display and determines the width </remarks>
        public override void Perform_PreDisplay_Work(Custom_Tracer Tracer)
        {
            // Set some defaults
            text_from_file = String.Empty;
            file_does_not_exist = false;
            error_occurred = false;
            width = -1;

            if (FileName.Length > 0)
            {
                string filesource = CurrentItem.Web.Source_URL + "/" + FileName;
                text_from_file = Get_Html_Page(filesource, Tracer);

                // Did this work?
                if (text_from_file.Length > 0)
                {
                    string[] splitter = text_from_file.Split("\n".ToCharArray());
                    foreach (string thisString in splitter)
                    {
                        width = Math.Max(width, thisString.Length*9);
                    }
                   // width = Math.Min(width, 800);
                }
            }
            else
            {
                file_does_not_exist = true;
            }
        }
        /// <summary> Constructor for a new instance of the Text_Search_ItemViewer class, which allows the full text of an 
        /// individual resource to be searched and individual matching pages are displayed with page thumbnails </summary>
        /// <param name="BriefItem"> Digital resource object </param>
        /// <param name="CurrentUser"> Current user, who may or may not be logged on </param>
        /// <param name="CurrentRequest"> Information about the current request </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public Text_Search_ItemViewer(BriefItemInfo BriefItem, User_Object CurrentUser, Navigation_Object CurrentRequest, Custom_Tracer Tracer )
        {
            Tracer.Add_Trace("Text_Search_ItemViewer.Constructor");

            // Save the arguments for use later
            this.BriefItem = BriefItem;
            this.CurrentUser = CurrentUser;
            this.CurrentRequest = CurrentRequest;

            // Set the behavior properties to the empy behaviors ( in the base class )
            Behaviors = EmptyBehaviors;

            if (!String.IsNullOrWhiteSpace(CurrentRequest.Text_Search))
            {
                List<string> terms = new List<string>();
                List<string> web_fields = new List<string>();

                // Split the terms correctly
                SobekCM_Assistant.Split_Clean_Search_Terms_Fields(CurrentRequest.Text_Search, "ZZ", Search_Type_Enum.Basic, terms, web_fields, null, Search_Precision_Type_Enum.Contains, '|');

                Tracer.Add_Trace("Text_Search_ItemViewer.Constructor", "Performing Solr/Lucene search");

                int page = CurrentRequest.SubPage.HasValue ? Math.Max(CurrentRequest.SubPage.Value, ((ushort)1)) : 1;
                results = Solr_Page_Results.Search(BriefItem.BibID, BriefItem.VID, terms, 20, page, false);

                Tracer.Add_Trace("Text_Search_ItemViewer.Constructor", "Completed Solr/Lucene search in " + results.QueryTime + "ms");
            }
        }
        /// <summary> Create the BriefItemInfo from a full METS-based SobekCM_Item object,
        /// using the default mapping set </summary>
        /// <param name="Original"> Original METS-based object to use </param>
        /// <param name="MappingSetId"> Name of the mapping set to use (if there are more than one)</param>
        /// <param name="Tracer"> Custom tracer to record general process flow </param>
        /// <returns> Completely built BriefItemInfo object from the METS-based SobekCM_Item object </returns>
        public static BriefItemInfo Create(SobekCM_Item Original, string MappingSetId, Custom_Tracer Tracer )
        {
            // Try to get the brief mapping set
            List<IBriefItemMapper> mappingSet = get_mapping_set(MappingSetId);

            // Create the mostly empty new brief item
            Tracer.Add_Trace("BriefItem_Factory.Create", "Create the mostly empty new brief item");
            BriefItemInfo newItem = new BriefItemInfo
            {
                BibID = Original.BibID,
                VID = Original.VID,
                Title = Original.Bib_Info.Main_Title.Title
            };

            // Build the new item using the selected mapping set
            Tracer.Add_Trace("BriefItem_Factory.Create", "Use the set of mappers to map data to the brief item");
            foreach (IBriefItemMapper thisMapper in mappingSet)
            {
                Tracer.Add_Trace("BriefItem_Factory.Create", "...." + thisMapper.GetType().ToString().Replace("SobekCM.Engine_Library.Items.BriefItems.Mappers.",""));
                thisMapper.MapToBriefItem(Original, newItem);
            }
            Tracer.Add_Trace("BriefItem_Factory.Create", "Finished using all instatiated and configued mappers");

            return newItem;
        }
        /// <summary> Stream to which to write the HTML for this subwriter  </summary>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public override void Write_Main_Viewer_Section(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("YouTube_Embedded_Video_ItemViewer.Write_Main_Viewer_Section", "");
            }

            //Determine the name of the FLASH file
            string youtube_url = CurrentItem.Bib_Info.Location.Other_URL;
             if ( youtube_url.IndexOf("watch") > 0 )
                 youtube_url = youtube_url.Replace("watch?v=","v/") + "?fs=1&amp;hl=en_US";
            const int width = 600;
            const int height = 480;

            // Add the HTML for the image
            StringBuilder result = new StringBuilder(500);
            Output.WriteLine("          <td><div id=\"sbkEmv_ViewerTitle\">Streaming Video</div></td>");
            Output.WriteLine("        </tr>");
            Output.WriteLine("        <tr>");
            Output.WriteLine("          <td id=\"sbkEmv_MainArea\">");
            Output.WriteLine("            <object style=\"width:" + width + ";height:" + height + "\">");
            Output.WriteLine("              <param name=\"allowscriptaccess\" value=\"always\" />");
            Output.WriteLine("              <param name=\"movie\" value=\"" + youtube_url + "\" />");
            Output.WriteLine("              <param name=\"allowFullScreen\" value=\"true\"></param>");
            Output.WriteLine("              <embed src=\"" + youtube_url + "\" type=\"application/x-shockwave-flash\" AllowScriptAccess=\"always\" allowfullscreen=\"true\" width=\"" + width + "\" height=\"" + height + "\"></embed>");
            Output.WriteLine("            </object>");
            Output.WriteLine("          </td>" );
        }
        /// <summary> Method returns the table of results for the browse indicated </summary>
        /// <param name="ItemAggr"> Item Aggregation from which to return the browse </param>
        /// <param name = "ChildPageObject">Object with all the information about the browse</param>
        /// <param name = "Page"> Page of results requested for the indicated browse </param>
        /// <param name = "Sort"> Sort applied to the results before being returned </param>
        /// <param name="Potentially_Include_Facets"> Flag indicates if facets could be included in this browse results </param>
        /// <param name = "Need_Browse_Statistics"> Flag indicates if the browse statistics (facets and total counts) are required for this browse as well </param>
        /// <param name = "Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <param name="Results_Per_Page"> Number of results to retrieve per page</param>
        /// <returns> Resutls for the browse or info in table form </returns>
        public static Multiple_Paged_Results_Args Get_Browse_Results(Item_Aggregation ItemAggr, Item_Aggregation_Child_Page ChildPageObject,
                                                                      int Page, int Sort, int Results_Per_Page, bool Potentially_Include_Facets, bool Need_Browse_Statistics,
                                                                      Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("Item_Aggregation_Utilities.Get_Browse_Results", String.Empty);
            }

            // Get the list of facets first
            List<short> facetsList = ItemAggr.Facets;
            if (!Potentially_Include_Facets)
                facetsList = null;

            // Pull data from the database if necessary
            if ((ChildPageObject.Code == "all") || (ChildPageObject.Code == "new"))
            {
                // Get this browse from the database
                if ((ItemAggr.ID < 0) || (ItemAggr.Code.ToUpper() == "ALL"))
                {
                    if (ChildPageObject.Code == "new")
                        return Engine_Database.Get_All_Browse_Paged(true, false, Results_Per_Page, Page, Sort, Need_Browse_Statistics, facetsList, Need_Browse_Statistics, Tracer);
                    return Engine_Database.Get_All_Browse_Paged(false, false, Results_Per_Page, Page, Sort, Need_Browse_Statistics, facetsList, Need_Browse_Statistics, Tracer);
                }

                if (ChildPageObject.Code == "new")
                {
                    return Engine_Database.Get_Item_Aggregation_Browse_Paged(ItemAggr.Code, true, false, Results_Per_Page, Page, Sort, Need_Browse_Statistics, facetsList, Need_Browse_Statistics, Tracer);
                }
                return Engine_Database.Get_Item_Aggregation_Browse_Paged(ItemAggr.Code, false, false, Results_Per_Page, Page, Sort, Need_Browse_Statistics, facetsList, Need_Browse_Statistics, Tracer);
            }

            // Default return NULL
            return null;
        }
        /// <summary> Retrieves the complete html skin object from the cache  </summary>
        /// <param name="Skin_Code"> Code for this html display skin </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <returns> Either NULL or the complete html skin object </returns>
        public Complete_Web_Skin_Object Retrieve_Complete_Skin(string Skin_Code, Custom_Tracer Tracer)
        {
            // If the cache is disabled, just return before even tracing
            if (settings.Disabled)
                return null;

            // Determine the key
            string key = "SKIN|" + Skin_Code.ToLower() + "|COMPLETE";

            // See if this is in the local cache first
            object returnValue = HttpContext.Current.Cache.Get(key);
            if (returnValue != null)
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("CachedDataManager.Retrieve_Complete_Skin", "Found complete html skin on local cache");
                }

                return (Complete_Web_Skin_Object)returnValue;
            }

            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager.Retrieve_Complete_Skin", "Complete skin not found in either the local cache");
            }

            // Since everything failed, just return null
            return null;
        }
        /// <summary> [HELPER] Gets the language-specific web skin, by web skin code and language code </summary>
        /// <param name="SkinCode"> Web skin code </param>
        /// <param name="RequestedLanguage"> Web language </param>
        /// <param name="DefaultLanguage"> Default language, in case the requested web language does nto exist </param>
        /// <param name="Tracer"></param>
        /// <returns> A build language-specific web skin </returns>
        /// <remarks> This may be public now, but this will be converted into a private helped class with 
        /// the release of SobekCM 5.0 </remarks>
        public static Web_Skin_Object get_web_skin(string SkinCode, Web_Language_Enum RequestedLanguage, Web_Language_Enum DefaultLanguage, Custom_Tracer Tracer)
        {
            Complete_Web_Skin_Object completeSkin = get_complete_web_skin(SkinCode, Tracer);

            if (completeSkin == null)
            {
                Tracer.Add_Trace("WebSkinServices.get_web_skin", "Complete skin retrieved was NULL, so returning NULL");
                return null;
            }

            // Look in the cache for this first
            Web_Skin_Object cacheObject = CachedDataManager.WebSkins.Retrieve_Skin(SkinCode, Web_Language_Enum_Converter.Enum_To_Code(RequestedLanguage), Tracer);
            if (cacheObject != null)
            {
                if (Tracer != null) Tracer.Add_Trace("WebSkinServices.get_web_skin", "Web skin found in the memory cache");
                return cacheObject;
            }

            // Try to get this language-specifi web skin
            Web_Skin_Object returnValue = Web_Skin_Utilities.Build_Skin(completeSkin, Web_Language_Enum_Converter.Enum_To_Code(RequestedLanguage), Tracer);

            // If this web skin has a value (an no exception) store in the cache
            if ((returnValue != null) && (String.IsNullOrEmpty(returnValue.Exception)))
            {
                if (Tracer != null) Tracer.Add_Trace("WebSkinServices.get_web_skin", "Store the web skin in the memory cache");
                CachedDataManager.WebSkins.Store_Skin(SkinCode, Web_Language_Enum_Converter.Enum_To_Code(RequestedLanguage), returnValue, Tracer );
            }

            // Return the object
            return returnValue;
        }
        /// <summary> Add the main HTML for the main viewer, which is the bulk of the share fragment </summary>
        /// <param name="MainPlaceHolder">Main place holder ( "mainPlaceHolder" ) in the itemNavForm form into which the bulk of the item viewer's output is displayed</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public override void Add_Main_Viewer_Section(PlaceHolder MainPlaceHolder, Custom_Tracer Tracer)
        {
            StringBuilder responseBuilder = new StringBuilder();

            // Calculate the title and url
            string title = HttpUtility.HtmlEncode(CurrentItem.Bib_Info.Main_Title.Title);
            string share_url = CurrentMode.Base_URL + "/" + CurrentItem.BibID + "/" + CurrentItem.VID;
            if (HttpContext.Current != null)
                share_url = HttpContext.Current.Items["Original_URL"].ToString().Replace("&", "%26").Replace("?", "%3F").Replace("http://", "").Replace("=", "%3D").Replace("\"", "&quot;");

            responseBuilder.AppendLine("<!-- Share form -->");
            responseBuilder.AppendLine("<div id=\"shareform_content\">");

            responseBuilder.AppendLine("<a href=\"http://www.facebook.com/share.php?u=" + share_url + "&amp;t=" + title + "\" target=\"FACEBOOK_WINDOW\" onmouseover=\"facebook_share.src='" + Static_Resources.Facebook_Share_H_Gif + "'\" onfocus=\"facebook_share.src='" + Static_Resources.Facebook_Share_H_Gif + "'\" onmouseout=\"facebook_share.src='" + Static_Resources.Facebook_Share_Gif + "'\" onblur=\"facebook_share.src='" + Static_Resources.Facebook_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"facebook_share\" name=\"facebook_share\" src=\"" + Static_Resources.Facebook_Share_Gif + "\" alt=\"FACEBOOK\" /></a>");
            responseBuilder.AppendLine("<a href=\"http://buzz.yahoo.com/buzz?targetUrl=" + share_url + "&amp;headline=" + title + "\" target=\"YAHOOBUZZ_WINDOW\" onmouseover=\"yahoobuzz_share.src='" + Static_Resources.Yahoobuzz_Share_H_Gif + "'\" onfocus=\"yahoobuzz_share.src='" + Static_Resources.Yahoobuzz_Share_H_Gif + "'\" onmouseout=\"yahoobuzz_share.src='" + Static_Resources.Yahoobuzz_Share_Gif + "'\" onblur=\"yahoobuzz_share.src='" + Static_Resources.Yahoobuzz_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"yahoobuzz_share\" name=\"yahoobuzz_share\" src=\"" + Static_Resources.Yahoobuzz_Share_Gif + "\" alt=\"YAHOO BUZZ\" /></a>");
            responseBuilder.AppendLine("<br />");

            responseBuilder.AppendLine("<a href=\"http://twitter.com/home?status=Currently reading " + share_url + "\" target=\"TWITTER_WINDOW\" onmouseover=\"twitter_share.src='" + Static_Resources.Twitter_Share_H_Gif + "'\" onfocus=\"twitter_share.src='" + Static_Resources.Twitter_Share_H_Gif + "'\" onmouseout=\"twitter_share.src='" + Static_Resources.Twitter_Share_Gif + "'\" onblur=\"twitter_share.src='" + Static_Resources.Twitter_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"twitter_share\" name=\"twitter_share\" src=\"" + Static_Resources.Twitter_Share_Gif + "\" alt=\"TWITTER\" /></a>");
            responseBuilder.AppendLine("<a href=\"http://www.google.com/bookmarks/mark?op=add&amp;bkmk=" + share_url + "&amp;title=" + title + "\" target=\"GOOGLE_WINDOW\" onmouseover=\"google_share.src='" + Static_Resources.Google_Share_H_Gif + "'\" onfocus=\"google_share.src='" + Static_Resources.Google_Share_H_Gif + "'\" onmouseout=\"google_share.src='" + Static_Resources.Google_Share_Gif + "'\" onblur=\"google_share.src='" + Static_Resources.Google_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"google_share\" name=\"google_share\" src=\"" + Static_Resources.Google_Share_Gif + "\" alt=\"GOOGLE SHARE\" /></a>");
            responseBuilder.AppendLine("<br />");

            responseBuilder.AppendLine("<a href=\"http://www.stumbleupon.com/submit?url=" + share_url + "&amp;title=" + title + "\" target=\"STUMBLEUPON_WINDOW\" onmouseover=\"stumbleupon_share.src='" + Static_Resources.Stumbleupon_Share_H_Gif + "'\" onfocus=\"stumbleupon_share.src='" + Static_Resources.Stumbleupon_Share_H_Gif + "'\" onmouseout=\"stumbleupon_share.src='" + Static_Resources.Stumbleupon_Share_Gif + "'\" onblur=\"stumbleupon_share.src='" + Static_Resources.Stumbleupon_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"stumbleupon_share\" name=\"stumbleupon_share\" src=\"" + Static_Resources.Stumbleupon_Share_Gif + "\" alt=\"STUMBLEUPON\" /></a>");
            responseBuilder.AppendLine("<a href=\"http://myweb.yahoo.com/myresults/bookmarklet?t=" + title + "&amp;u=" + share_url + "\" target=\"YAHOO_WINDOW\" onmouseover=\"yahoo_share.src='" + Static_Resources.Yahoo_Share_H_Gif + "'\" onfocus=\"yahoo_share.src='" + Static_Resources.Yahoo_Share_H_Gif + "'\" onmouseout=\"yahoo_share.src='" + Static_Resources.Yahoo_Share_Gif + "'\" onblur=\"yahoo_share.src='" + Static_Resources.Yahoo_Share_Gif + "'\" onclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"yahoo_share\" name=\"yahoo_share\" src=\"" + Static_Resources.Yahoo_Share_Gif + "\" alt=\"YAHOO SHARE\" /></a>");
            responseBuilder.AppendLine("<br />");

            responseBuilder.AppendLine("<a href=\"http://digg.com/submit?phase=2&amp;url=" + share_url + "&amp;title=" + title + "\" target=\"DIGG_WINDOW\" onmouseover=\"digg_share.src='" + Static_Resources.Digg_Share_H_Gif + "'\" onfocus=\"digg_share.src='" + Static_Resources.Digg_Share_H_Gif + "'\" onmouseout=\"digg_share.src='" + Static_Resources.Digg_Share_Gif + "'\" onblur=\"digg_share.src='" + Static_Resources.Digg_Share_Gif + "'\"  nclick=\"\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"digg_share\" name=\"digg_share\" src=\"" + Static_Resources.Digg_Share_Gif + "\" alt=\"DIGG\" /></a>");
            responseBuilder.AppendLine("<a onmouseover=\"favorites_share.src='" + Static_Resources.Facebook_Share_H_Gif + "'\" onfocus=\"favorites_share.src='" + Static_Resources.Facebook_Share_H_Gif + "'\" onmouseout=\"favorites_share.src='" + Static_Resources.Facebook_Share_Gif + "'\" onblur=\"favorites_share.src='" + Static_Resources.Facebook_Share_Gif + "'\" onclick=\"javascript:add_to_favorites();\"><img class=\"ResultSavePrintButtons\" border=\"0px\" id=\"favorites_share\" name=\"favorites_share\" src=\"" + Static_Resources.Facebook_Share_Gif + "\" alt=\"MY FAVORITES\" /></a>");
            responseBuilder.AppendLine("<br />");

            responseBuilder.AppendLine("</div>");
            responseBuilder.AppendLine();

            MainPlaceHolder.Controls.Add(new Literal() { Text = responseBuilder.ToString() });
        }
        /// <summary> Gets the brief digital resource object, by BibID_VID </summary>
        /// <param name="BibID"> Bibliographic identifier (BibID) for the digital resource to retrieve </param>
        /// <param name="VID"> Volume identifier (VID) for the digital resource to retrieve </param>
        /// <param name="UseCache"> Flag indicates if the cache should be used to check for a built copy or store the final product </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <returns> Fully built brief digital item object </returns>
        public BriefItemInfo Get_Item_Brief(string BibID, string VID, bool UseCache, Custom_Tracer Tracer)
        {
            // Add a beginning trace
            Tracer.Add_Trace("SobekEngineClient_ItemEndpoints.Get_Item_Brief", "Get brief item information by bibid/vid");

            // Look in the cache
            if ((Config.UseCache) && (UseCache))
            {
                BriefItemInfo fromCache = CachedDataManager.Items.Retrieve_Brief_Digital_Resource_Object(BibID, VID, Tracer);
                if (fromCache != null)
                {
                    Tracer.Add_Trace("SobekEngineClient_WebContentServices.Get_Item_Brief", "Found brief item in the local cache");
                    return fromCache;
                }
            }
            // Get the endpoint
            MicroservicesClient_Endpoint endpoint = GetEndpointConfig("Items.GetItemBrief", Tracer);

            // Format the URL
            string url = String.Format(endpoint.URL, BibID, VID);

            // Call out to the endpoint and deserialize the object
            BriefItemInfo returnValue = Deserialize<BriefItemInfo>(url, endpoint.Protocol, Tracer);

            // Add to the local cache
            if ((Config.UseCache) && (UseCache) && (returnValue != null))
            {
                Tracer.Add_Trace("SobekEngineClient_WebContentServices.Get_Item_Brief", "Store brief item in the local cache");
                CachedDataManager.Items.Store_Brief_Digital_Resource_Object(BibID, VID, returnValue, Tracer);
            }

            // Return the object
            return returnValue;
        }
        /// <summary> Read the source browse and info static html files and create the
        /// appropriate <see cref="HTML_Based_Content"/> object with all the bibliographic information
        /// (author, keywords, description, title, code) loaded from the header in the HTML file</summary>
        /// <param name="Source_File"> Source file to read directly from the local network (not via the web)</param>
        /// <param name="Retain_Entire_Display_Text"> Flag indicates whether the entire display text should be retained (as it is about to be displayed) or just the basic information from the HEAD of the file </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <returns> Fully built browse info object with all the bibliographic information</returns>
        public static HTML_Based_Content Read_HTML_File(string Source_File,  bool Retain_Entire_Display_Text, Custom_Tracer Tracer)
        {
            try
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Read_HTML_File", "Reading source file");
                }

                // Read this info file
                StreamReader reader = new StreamReader(Source_File);
                string displayText = reader.ReadToEnd();
                reader.Close();

                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Read_HTML_File", "Succesfully read the source file");
                }

                // Convert this to the object
                return Text_To_HTML_Based_Content(displayText, Retain_Entire_Display_Text, Source_File, Tracer);
            }
            catch ( Exception ee )
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("HTML_Based_Content_Reader.Read_HTML_File", "EXCEPTION caught reading source file " + ee.Message );
                }

                return null;
            }
        }
        /// <summary> Removes a user-specific digital resource object from the cache , it it exists </summary>
        /// <param name="UserID"> Primary key of the user, if this should be removed from the user-specific cache</param>
        /// <param name="BibID"> Bibliographic Identifier for the digital resource to remove </param>
        /// <param name="VID"> Volume Identifier for the digital resource to remove </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        public void Remove_Digital_Resource_Object(int UserID, string BibID, string VID, Custom_Tracer Tracer)
        {
            // If the cache is disabled, just return before even tracing
            if (settings.Disabled)
                return;

            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager_ItemServices.Remove_Digital_Resource_Object", "");
            }

            string key_start = "ITEM_" + BibID.ToUpper() + "_" + VID + "_";

            // Build the sorted list of locally cached stuff
            List<Cached_Object_Info> locallyCached = (from DictionaryEntry thisItem in HttpContext.Current.Cache select new Cached_Object_Info(thisItem.Key.ToString(), thisItem.Value.GetType())).ToList();

            // Determine which keys to expire
            List<string> keys_to_expire = (from cachedObject in locallyCached where cachedObject.Object_Key.IndexOf(key_start) == 0 select cachedObject.Object_Key).ToList();

            // Clear these from the local cache
            foreach (string expireKey in keys_to_expire)
            {
                HttpContext.Current.Cache.Remove(expireKey);
            }

            // Now, remove the actual item
            HttpContext.Current.Cache.Remove("ITEM_" + BibID.ToUpper() + "_" + VID);
            if (UserID > 0)
            {
                HttpContext.Current.Cache.Remove("USERITEM" + UserID + "_ITEM_" + BibID.ToUpper() + "_" + VID);
            }
        }
        /// <summary> Stream to which to write the HTML for this subwriter  </summary>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public override void Write_Main_Viewer_Section(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("EAD_Description_ItemViewer.Write_Main_Viewer_Section", "");
            }

            // Get the metadata module for EADs
            EAD_Info eadInfo = (EAD_Info)CurrentItem.Get_Metadata_Module(GlobalVar.EAD_METADATA_MODULE_KEY);

            // Build the value
            Output.WriteLine("          <td>");
            Output.WriteLine("            <div id=\"sbkEad_MainArea\">");

            if ( !String.IsNullOrWhiteSpace(CurrentMode.Text_Search))
            {
                // Get any search terms
                List<string> terms = new List<string>();
                if (CurrentMode.Text_Search.Trim().Length > 0)
                {
                    string[] splitter = CurrentMode.Text_Search.Replace("\"", "").Split(" ".ToCharArray());
                    terms.AddRange(from thisSplit in splitter where thisSplit.Trim().Length > 0 select thisSplit.Trim());
                }

                Output.Write(Text_Search_Term_Highlighter.Hightlight_Term_In_HTML(eadInfo.Full_Description, terms));
            }
            else
            {
                Output.Write(eadInfo.Full_Description);
            }

            Output.WriteLine("            </div>");
            Output.WriteLine("          </td>");
        }
        /// <summary> Gets a page from an existing digital resource, by page sequence </summary>
        /// <param name="Current_Item"> Digital resource from which to pull the current page, by sequence </param>
        /// <param name="Sequence"> Sequence for the page to retrieve from this item </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <returns> Page tree node object for the requested page </returns>
        public static Page_TreeNode Get_Current_Page(SobekCM_Item Current_Item, int Sequence, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_Item_Factory.Get_Current_Page", "Requesting the page (by sequence) from the item");
            }

            Page_TreeNode returnValue = null;

            try
            {
                // Set the current page
                if (Sequence >= 1)
                {
                    int requested_page = Sequence - 1;
                    if ((requested_page < 0) || (requested_page > Current_Item.Web.Static_PageCount - 1))
                        requested_page = 0;

                    if (requested_page <= Current_Item.Web.Static_PageCount - 1)
                    {
                        returnValue = Current_Item.Web.Pages_By_Sequence[requested_page];
                    }
                }
            }
            catch (Exception ee)
            {
                throw new ApplicationException("Error assigning the current page sequence", ee);
            }

            return returnValue;
        }
        /// <summary> Adds the main view section to the page turner </summary>
        /// <param name="MainPlaceHolder">Main place holder ( "mainPlaceHolder" ) in the itemNavForm form into which the bulk of the item viewer's output is displayed</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public override void Add_Main_Viewer_Section(PlaceHolder MainPlaceHolder, Custom_Tracer Tracer)
        {
            if ((CurrentItem.Behaviors.Can_Be_Described) && (CurrentUser != null))
            {
                // Determine the number of columns for text areas, depending on browser
                int actual_cols = 50;
                if (( !String.IsNullOrEmpty(CurrentMode.Browser_Type)) && (CurrentMode.Browser_Type.ToUpper().IndexOf("FIREFOX") >= 0))
                    actual_cols = 45;

                StringBuilder responseBuilder = new StringBuilder();
                responseBuilder.AppendLine("<!-- Add descriptive tage form  -->");
                responseBuilder.AppendLine("<div class=\"describe_popup_div\" id=\"describe_item_form\" style=\"display:none;\">");
                responseBuilder.AppendLine("  <div class=\"popup_title\"><table width=\"100%\"><tr><td align=\"left\">A<span class=\"smaller\">DD </span> I<span class=\"smaller\">TEM </span> D<span class=\"smaller\">ESCRIPTION</span></td><td align=\"right\"> <a href=\"#template\" alt=\"CLOSE\" onclick=\"describe_item_form_close()\">X</a> &nbsp; </td></tr></table></div>");
                responseBuilder.AppendLine("  <br />");
                responseBuilder.AppendLine("  <fieldset><legend>Enter a description or notes to add to this item &nbsp; </legend>");
                responseBuilder.AppendLine("    <br />");
                responseBuilder.AppendLine("    <table class=\"popup_table\">");

                // Add comments area
                responseBuilder.Append("      <tr align=\"left\" valign=\"top\"><td><br /><label for=\"add_notes\">Notes:</label></td>");
                responseBuilder.AppendLine("<td><textarea rows=\"10\" cols=\"" + actual_cols + "\" name=\"add_tag\" id=\"add_tag\" class=\"add_notes_textarea\" onfocus=\"javascript:textbox_enter('add_tag','add_notes_textarea_focused')\" onblur=\"javascript:textbox_leave('add_tag','add_notes_textarea')\"></textarea></td></tr>");
                responseBuilder.AppendLine("    </table>");
                responseBuilder.AppendLine("    <br />");
                responseBuilder.AppendLine("  </fieldset><br />");
                responseBuilder.AppendLine("  <center><a href=\"\" onclick=\"return describe_item_form_close();\"><img border=\"0\" src=\"" + CurrentMode.Base_URL + "design/skins/" + CurrentMode.Base_Skin_Or_Skin + "/buttons/cancel_button_g.gif\" alt=\"CLOSE\" /></a> &nbsp; &nbsp; <input type=\"image\" src=\"" + CurrentMode.Base_URL + "design/skins/" + CurrentMode.Base_Skin_Or_Skin + "/buttons/save_button_g.gif\" value=\"Submit\" alt=\"Submit\" ></center><br />");
                responseBuilder.AppendLine("</div>");
                responseBuilder.AppendLine();

                MainPlaceHolder.Controls.Add(new Literal { Text = responseBuilder.ToString() });
            }
        }
        /// <summary> Builds a brief version of a digital resource, used when displaying the 'FULL VIEW' in 
        /// a search result or browse list </summary>
        /// <param name="METS_Location"> Location (URL) of the METS file to read via HTTP </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <returns> Briefly built version of a digital resource </returns>
        public SobekCM_Item Build_Brief_Item(string METS_Location, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_METS_Based_ItemBuilder.Build_Brief_Item", "Create the requested item");
            }

            try
            {
                // Get the response object for this METS file
                string mets_file = METS_Location.Replace("\\", "/") + "/citation_mets.xml";

                SobekCM_Item thisPackage = Build_Item_From_METS(mets_file, "citation_mets.xml", Tracer);

                if (thisPackage == null)
                {
                    if (Tracer != null)
                        Tracer.Add_Trace("SobekCM_METS_Based_ItemBuilder.Build_Brief_Item", "Unable to find/read either METS file", Custom_Trace_Type_Enum.Error);
                }

                if (Tracer != null)
                {
                    Tracer.Add_Trace("SobekCM_METS_Based_ItemBuilder.Build_Brief_Item", "Finished building this item");
                }

                return thisPackage;
            }
            catch (Exception ee)
            {
                if (Tracer != null)
                    Tracer.Add_Trace("SobekCM_METS_Based_ItemBuilder.Build_Brief_Item", ee.ToString().Replace("\n", "<br />"), Custom_Trace_Type_Enum.Error);
                return null;
            }
        }
        /// <summary> Writes the HTML generated by this error html subwriter directly to the response stream </summary>
        /// <param name="Output"> Stream to which to write the HTML for this subwriter </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <returns> TRUE -- Value indicating if html writer should finish the page immediately after this, or if there are other controls or routines which need to be called first </returns>
        public override bool Write_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            Tracer.Add_Trace("Error_HtmlSubwriter.Write_HTML", "Rendering HTML");

            // Start the page container
            Output.WriteLine("<div id=\"pagecontainer\">");
            Output.WriteLine("<br />");

            string errorMessage = RequestSpecificValues.Current_Mode.Error_Message;
            if (String.IsNullOrEmpty(errorMessage))
                errorMessage = "Error";

                Output.WriteLine("<center>");

                Output.WriteLine("  <br /><br />");
                Output.WriteLine("<span style=\"font-size:large; color:red\">");
                Output.WriteLine("    <b>Deprecated URL detected</b>");
                Output.WriteLine("</span>");
                Output.WriteLine("<span style=\"font-size:1.2em\">");
                Output.WriteLine("  <br /><br />");
                Output.WriteLine("The URL you entered is a legacy URL.  Support for this URL will end shortly.<br /><br />Please update your records to the new URL below:<br /><br />");
                Output.WriteLine("<a href=\"" + errorMessage + "\">" + errorMessage + "</a>");
                Output.WriteLine("  <br /><br /><br /><br />");
                Output.WriteLine("</span>");
                Output.WriteLine("</center>");
                Output.WriteLine();

                Output.WriteLine("<!-- Close the pagecontainer div -->");
                Output.WriteLine("</div>");
                Output.WriteLine();

            return true;
        }
        /// <summary> Constructor for a new instance of the JPEG_ItemViewer class, used to display JPEGs linked to
        /// pages in a digital resource </summary>
        /// <param name="BriefItem"> Digital resource object </param>
        /// <param name="CurrentUser"> Current user, who may or may not be logged on </param>
        /// <param name="CurrentRequest"> Information about the current request </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="JPEG_ViewerCode"> JPEG viewer code, as determined by configuration files </param>
        /// <param name="FileExtensions"> File extensions that this viewer allows, as determined by configuration files </param>
        public JPEG_ItemViewer(BriefItemInfo BriefItem, User_Object CurrentUser, Navigation_Object CurrentRequest, Custom_Tracer Tracer, string JPEG_ViewerCode, string[] FileExtensions)
        {
            // Add the trace
            if ( Tracer != null )
                Tracer.Add_Trace("JPEG_ItemViewer.Constructor");

            // Save the arguments for use later
            this.BriefItem = BriefItem;
            this.CurrentUser = CurrentUser;
            this.CurrentRequest = CurrentRequest;

            // Set the behavior properties
            Behaviors = EmptyBehaviors;

            // Is the JPEG2000 viewer included in this item?
            bool zoomableViewerIncluded = BriefItem.UI.Includes_Viewer_Type("JPEG2000");
            string[] jpeg2000_extensions = null;
            if (zoomableViewerIncluded)
            {
                iItemViewerPrototyper jp2Prototyper = ItemViewer_Factory.Get_Viewer_By_ViewType("JPEG2000");
                if (jp2Prototyper == null)
                    zoomableViewerIncluded = false;
                else
                {
                    zoomableViewerCode = jp2Prototyper.ViewerCode;
                    jpeg2000_extensions = jp2Prototyper.FileExtensions;
                }
            }

            // Set some default values
            width = 500;
            height = -1;
            includeLinkToZoomable = false;

            // Determine the page
            page = 1;
            if (!String.IsNullOrEmpty(CurrentRequest.ViewerCode))
            {
                int tempPageParse;
                if (Int32.TryParse(CurrentRequest.ViewerCode.Replace(JPEG_ViewerCode.Replace("#",""), ""), out tempPageParse))
                    page = tempPageParse;
            }

            // Just a quick range check
            if (page > BriefItem.Images.Count)
                page = 1;

            // Try to set the file information here
            if ((!set_file_information(FileExtensions, zoomableViewerIncluded, jpeg2000_extensions)) && (page != 1))
            {
                // If there was an error, just set to the first page
                page = 1;
                set_file_information(FileExtensions, zoomableViewerIncluded, jpeg2000_extensions);
            }

            // Since this is a paging viewer, set the viewer code
            if (String.IsNullOrEmpty(CurrentRequest.ViewerCode))
                CurrentRequest.ViewerCode = JPEG_ViewerCode.Replace("#", page.ToString());
        }
        /// <summary> Add the HTML to be displayed in the main SobekCM viewer area (outside of the forms)</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 class does nothing, since the interface list is added as controls, not HTML </remarks>
        public override void Write_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            Tracer.Add_Trace("Edit_Serial_Hierarchy_MySobekViewer.Write_HTML", "Do nothing");

            Output.WriteLine("<br /><br />");
            Output.WriteLine("<strong>EDIT SERIAL HIERARCHY</strong><br /><br />");
            Output.WriteLine("Implementation for this feature is currently pending.<br /><br /><br />");
        }
        /// <summary> Stream to which to write the HTML for this subwriter  </summary>
        /// <param name="Output"> Response stream for the item viewer to write directly to </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public override void Write_Main_Viewer_Section(TextWriter Output, Custom_Tracer Tracer)
        {
            // Replace item URL in the restricted message
            CurrentMode.ViewerCode = string.Empty;
            string msg = restrictedMessage.Replace("<%ITEMURL%>", UrlWriterHelper.Redirect_URL(CurrentMode));

            Output.WriteLine("<td style=\"text-align:left;\" id=\"sbkRes_MainArea\">" + msg + "</td>");
        }
        /// <summary> Add the HTML to be displayed in the main SobekCM viewer area (outside of the forms)</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 class does nothing, since the interface list is added as controls, not HTML </remarks>
        public override void Write_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            Tracer.Add_Trace("Group_AutoFill_Volume_MySobekViewer.Write_HTML", "Do nothing");

            Output.WriteLine("<br /><br />");
            Output.WriteLine("<strong>AUTO-FILL NEW VOLUMES</strong><br /><br />");
            Output.WriteLine("Implementation for this feature is currently pending.<br /><br /><br />");
        }
 /// <summary> Constructor for a new instance of the SobekCM_Traced_Exception class </summary>
 /// <param name="Message"> The error message that explains the reason for the exception </param>
 /// <param name="Inner_Exception"> The exception which is the cause of the current exception </param>
 /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
 public SobekCM_Traced_Exception(string Message, Exception Inner_Exception, Custom_Tracer Tracer )
     : base(Message, Inner_Exception)
 {
     tracer = Tracer;
     if (tracer != null)
     {
         tracer.Add_Trace("SobekCM_Traced_Exception.Constructor", "Exception caught and bundled in the custom traced exception");
     }
 }
        /// <summary> Writes the final output to close this public folder browse, including the results page navigation buttons </summary>
        /// <param name="Output"> Stream to which to write the HTML for this subwriter </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <remarks> This calls the <see cref="PagedResults_HtmlSubwriter.Write_Final_HTML"/> method in the <see cref="PagedResults_HtmlSubwriter"/> object. </remarks>
        public override void Write_Final_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            Tracer.Add_Trace("Public_Folder_HtmlSubwriter.Write_Final_Html", "Rendering HTML ( finish the main viewer section )");

            if (writeResult != null)
            {
                writeResult.Write_Final_HTML(Output, Tracer);
            }
        }
        /// <summary> Add the HTML to be displayed in 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>
        public override void Add_Search_Box_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("No_Search_AggregationViewer.Add_Search_Box_HTML", "Adding html for search box");
            }

            Output.WriteLine("<h1>" + RequestSpecificValues.Hierarchy_Object.Name + " Home</h1>");
        }
        /// <summary> Add the HTML to be displayed </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> No html is added here, although children classes should override this virtual method to add HTML </remarks>
        public virtual void Add_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("abstractWebContentViewer.Add_HTML", "No html added");
            }

            // No html to be added here
        }
        /// <summary> Constructor for a new instance of the Google_Coordinate_Entry_ItemViewer class, used to edit the 
        /// coordinate information associated with this digital resource within an online google maps interface </summary>
        /// <param name="BriefItem"> Digital resource object </param>
        /// <param name="CurrentUser"> Current user, who may or may not be logged on </param>
        /// <param name="CurrentRequest"> Information about the current request </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public Google_Coordinate_Entry_ItemViewer(BriefItemInfo BriefItem, User_Object CurrentUser, Navigation_Object CurrentRequest, Custom_Tracer Tracer )
        {
            // Save the arguments for use later
            this.BriefItem = BriefItem;
            this.CurrentUser = CurrentUser;
            this.CurrentRequest = CurrentRequest;

            try
            {

                // Get the full SobekCM item
                Tracer.Add_Trace("Google_Coordinate_Entry_ItemViewer.Constructor", "Try to pull this sobek complete item");
                currentItem = SobekEngineClient.Items.Get_Sobek_Item(CurrentRequest.BibID, CurrentRequest.VID, Tracer);
                if (currentItem == null)
                {
                    Tracer.Add_Trace("Google_Coordinate_Entry_ItemViewer.Constructor", "Unable to build complete item");
                    CurrentRequest.Mode = Display_Mode_Enum.Error;
                    CurrentRequest.Error_Message = "Invalid Request : Unable to build complete item";
                    return;
                }

                //string resource_directory = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + CurrentItem.Web.AssocFilePath;
                //string current_mets = resource_directory + CurrentItem.METS_Header.ObjectID + ".mets.xml";

                // If there is no user, send to the login
                if (CurrentUser == null)
                {
                    CurrentRequest.Mode = Display_Mode_Enum.My_Sobek;
                    CurrentRequest.My_Sobek_Type = My_Sobek_Type_Enum.Logon;
                    CurrentRequest.Return_URL = BriefItem.BibID + "/" + BriefItem.VID + "/mapedit";
                    UrlWriterHelper.Redirect(CurrentRequest);
                    return;
                }

                //holds actions from page
                string action = HttpContext.Current.Request.Form["action"] ?? String.Empty;
                string payload = HttpContext.Current.Request.Form["payload"] ?? String.Empty;

                // See if there were hidden requests
                if (!String.IsNullOrEmpty(action))
                {
                    if (action == "save")
                        SaveContent(payload);
                }

                ////create a backup of the mets
                //string backup_directory = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + Current_Item.Web.AssocFilePath + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name;
                //string backup_mets_name = backup_directory + "\\" + CurrentItem.METS_Header.ObjectID + "_" + DateTime.Now.Year + "_" + DateTime.Now.Month + "_" + DateTime.Now.Day + ".mets.bak";
                //File.Copy(current_mets, backup_mets_name);

            }
            catch (Exception ee)
            {
                //Custom_Tracer.Add_Trace("MapEdit Start Failure");
                throw new ApplicationException("MapEdit Start Failure\r\n" + ee.Message);
            }
        }
        /// <summary> Add the HTML to be displayed </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>
        public override void Add_HTML(TextWriter Output, Custom_Tracer Tracer)
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("Work_History_WebContentViewer.Add_HTML", "No html added");
            }

            Output.WriteLine("<div class=\"Wchs_Text\">");
            Output.WriteLine("  <p>The list of changes, including the user that performed the change, appear below.</p>");
            Output.WriteLine("</div>");

            // Get the stats
            int webcontentid = -1;
            if (RequestSpecificValues.Current_Mode.WebContentID.HasValue)
                webcontentid = RequestSpecificValues.Current_Mode.WebContentID.Value;

            Single_WebContent_Change_Report stats;
            try
            {
                stats = SobekEngineClient.WebContent.Get_Single_Milestones(webcontentid, Tracer);
            }
            catch (Exception ee)
            {
                Output.WriteLine("<div id=\"apiExceptionMsg\">Exception caught: " + ee.Message + "</div>");
                return;
            }

            // If no stats, show a message for that
            if ((stats == null) || (stats.Changes == null) || (stats.Changes.Count == 0))
            {
                Output.WriteLine("<div id=\"sbkWchs_NoDataMsg\">No change history</div>");
                return;
            }

            Output.WriteLine("  <br />");
            Output.WriteLine("  <table class=\"sbkStatsTbl\" style=\"width: 500px; margin-left:auto; margin-right: auto;\">");
            Output.WriteLine("    <tr>");
            Output.WriteLine("      <th style=\"text-align:left;\">DATE</th>");
            Output.WriteLine("      <th>USER</th>");
            Output.WriteLine("      <th>CHANGE</th>");
            Output.WriteLine("    </tr>");

            // Add the usage data rows
            foreach (Milestone_Entry change in stats.Changes)
            {
                // Add the data row
                Output.WriteLine("    <tr>");
                Output.WriteLine("      <td style=\"text-align:left;\">" + change.MilestoneDate + "</td>");
                Output.WriteLine("      <td>" + change.User + "</td>");
                Output.WriteLine("      <td>" + change.Notes + "</td>");
                Output.WriteLine("    </tr>");
            }
            Output.WriteLine("  </table>");

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