/// <summary> Builds a language-specific <see cref="Web_Skin_Object"/> when needed by a user's request </summary>
        /// <param name="CompleteSkin"> Complete web skin object </param>
        /// <param name="Language_Code"> Code for the language, which determines which HTML to use </param>
        /// <param name="Tracer"></param>
        /// <returns> Completely built HTML interface object </returns>
        /// <remarks> The datarow for this method is retrieved from the database by calling the <see cref="Database.Engine_Database.Get_All_Web_Skins"/> method during 
        /// application startup and is then stored in the <see cref="Web_Skin_Collection"/> class until needed. </remarks>
        public static Web_Skin_Object Build_Skin(Complete_Web_Skin_Object CompleteSkin, string Language_Code, Custom_Tracer Tracer )
        {
            // Look for the language
            Web_Language_Enum language = Web_Language_Enum_Converter.Code_To_Enum(Language_Code);
            Web_Language_Enum original_language = language;
            if (!CompleteSkin.SourceFiles.ContainsKey(language))
            {
                if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Language requested ( " + Web_Language_Enum_Converter.Enum_To_Name(language) + " ) not in language list");

                language = Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language;
                if (( original_language == language ) || ( !CompleteSkin.SourceFiles.ContainsKey(language)))
                {

                    if ((Tracer != null) && ( original_language != language ))
                        Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Default UI language ( " + Web_Language_Enum_Converter.Enum_To_Name(language) + " ) not in language list");

                    language = Web_Language_Enum.DEFAULT;
                    if (!CompleteSkin.SourceFiles.ContainsKey(language))
                    {
                        if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "DEFAULT language not in language list");

                        language = Web_Language_Enum.English;

                        if (!CompleteSkin.SourceFiles.ContainsKey(language))
                        {
                            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "English language also not in language list");

                            if (CompleteSkin.SourceFiles.Count > 0)
                            {
                                language = CompleteSkin.SourceFiles.Keys.First();
                            }
                            else
                            {
                                if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Apparently there are NO source files.. returning NULL");
                                language = Web_Language_Enum.UNDEFINED;
                            }
                        }
                    }
                }
            }

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Will build language-specific web skin for '" + Web_Language_Enum_Converter.Enum_To_Name(language)  + "'");

            // Now, look in the cache for this
            if (language != Web_Language_Enum.UNDEFINED)
            {
                Web_Skin_Object cacheObject = CachedDataManager.WebSkins.Retrieve_Skin(CompleteSkin.Skin_Code, Web_Language_Enum_Converter.Enum_To_Code(language), null);
                if (cacheObject != null)
                {
                    if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Web skin found in the memory cache");

                    return cacheObject;
                }
            }

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Web skin not found in the memory cache, so building it now");

            // Build this then
            Web_Skin_Object returnValue = new Web_Skin_Object(CompleteSkin.Skin_Code, CompleteSkin.Base_Skin_Code, "design/skins/" + CompleteSkin.Skin_Code + "/" + CompleteSkin.CSS_Style);

            // Set the language code
            if ( language == Web_Language_Enum.DEFAULT )
                returnValue.Language_Code = Web_Language_Enum_Converter.Enum_To_Code(Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);
            else if ( language == Web_Language_Enum.UNDEFINED )
                returnValue.Language_Code = Web_Language_Enum_Converter.Enum_To_Code(language);

            // Set some optional (nullable) flags
            if ( CompleteSkin.Override_Banner ) returnValue.Override_Banner = true;
            if ( CompleteSkin.Suppress_Top_Navigation ) returnValue.Suppress_Top_Navigation = true;

            // If no suitable language was found, probably an error (no source files at all)
            if (language == Web_Language_Enum.UNDEFINED)
            {
                if (!String.IsNullOrEmpty(CompleteSkin.Exception))
                    returnValue.Exception = CompleteSkin.Exception;
                else
                    returnValue.Exception = "No valid source files found";

                // Also set the headers and footers to the exception
                returnValue.Header_HTML = returnValue.Exception;
                returnValue.Footer_HTML = returnValue.Exception;
                returnValue.Header_Item_HTML = returnValue.Exception;
                returnValue.Footer_Item_HTML = returnValue.Exception;

                return returnValue;
            }

            // Get the source file
            Complete_Web_Skin_Source_Files sourceFiles = CompleteSkin.SourceFiles[language];

            // Build the banner
            if ((returnValue.Override_Banner.HasValue) && (returnValue.Override_Banner.Value))
            {
                if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Skin overrides the banner, so build the banner HTML");

                // Find the LANGUAGE-SPECIFIC high-bandwidth banner image
                if ( !String.IsNullOrEmpty(sourceFiles.Banner))
                {
                    if ( !String.IsNullOrEmpty(CompleteSkin.Banner_Link))
                    {
                        returnValue.Banner_HTML = "<a href=\"" + CompleteSkin.Banner_Link + "\"><img border=\"0\" src=\"<%BASEURL%>skins/" + CompleteSkin.Skin_Code + "/" + sourceFiles.Banner + "\" alt=\"MISSING BANNER\" /></a>";
                    }
                    else
                    {
                        returnValue.Banner_HTML = "<img border=\"0\" src=\"<%BASEURL%>skins/" + CompleteSkin.Skin_Code + "/" + sourceFiles.Banner + "\" alt=\"MISSING BANNER\" />";
                    }
                }
            }

            // Now, set the header and footer html
            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Determine the header footer source HTML files");
            string this_header = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", CompleteSkin.Skin_Code, sourceFiles.Header_Source_File);
            string this_footer = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", CompleteSkin.Skin_Code, sourceFiles.Footer_Source_File);
            string this_item_header = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", CompleteSkin.Skin_Code, sourceFiles.Header_Item_Source_File);
            string this_item_footer = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", CompleteSkin.Skin_Code, sourceFiles.Footer_Item_Source_File);

            // If the item specific stuff doesn't exist, use the regular
            if (!File.Exists(this_item_header))
                this_item_header = this_header;
            if (!File.Exists(this_item_footer))
                this_item_footer = this_footer;

            // Now, assign all of these
            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Get the HTML source for all the headers and footers");
            returnValue.Set_Header_Footer_Source(this_header, this_footer, this_item_header, this_item_footer);

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin", "Returning the fully built web skin");
            return returnValue;
        }
        /// <summary> Stores the complete html skin object to the cache  </summary>
        /// <param name="Skin_Code"> Code for this html display skin </param>
        /// <param name="StoreObject"> Complete HTML Skin object </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        public void Store_Complete_Skin(string Skin_Code, Complete_Web_Skin_Object StoreObject, Custom_Tracer Tracer)
        {
            // If the cache is disabled, just return before even tracing
            if ((settings.Disabled) || (StoreObject == null))
                return;

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

            // Log
            if (Tracer != null)
            {
                Tracer.Add_Trace("CachedDataManager.Store_Complete_Skin", "Adding object '" + key + "' to the local cache with expiration of 1 minute");
            }

            // Stote the value with five minute expiration
            HttpContext.Current.Cache.Insert(key, StoreObject, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
        }
        /// <summary> Builds the complete web skin object </summary>
        /// <param name="Skin_Row"> Row for this web skin, from the database query </param>
        /// <param name="Tracer"></param>
        /// <returns> Complete web skin </returns>
        public static Complete_Web_Skin_Object Build_Skin_Complete(DataRow Skin_Row, Custom_Tracer Tracer )
        {
            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Building the complete web skin from the row and design files");

            // Pull values out from this row
            string code = Skin_Row["WebSkinCode"].ToString();
            string base_interface = Skin_Row["BaseInterface"].ToString();
            bool override_banner = Convert.ToBoolean(Skin_Row["OverrideBanner"]);
            string banner_link = Skin_Row["BannerLink"].ToString();
            string notes = Skin_Row["Notes"].ToString();
            string this_style = code + ".css";

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Verifying existence of the CSS file");

            string style_file = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", code, this_style);
            if (!File.Exists(style_file))
                this_style = String.Empty;

            // Create the web skin object
            Complete_Web_Skin_Object completeSkin = new Complete_Web_Skin_Object(code, this_style)
            {
                Override_Banner = override_banner,
                Suppress_Top_Navigation = Convert.ToBoolean(Skin_Row["SuppressTopNavigation"]),
                Notes = notes
            };

            // Assign the optional values
            if (!String.IsNullOrEmpty(base_interface))
                completeSkin.Base_Skin_Code = base_interface;
            if (!String.IsNullOrEmpty(banner_link))
                completeSkin.Banner_Link = banner_link;

            // Look for source files
            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Look for all the source files in the design folder");

            string html_soure_directory = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", code, "html");

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Design folder = " + html_soure_directory  );

            try
            {
                if (Directory.Exists(html_soure_directory))
                {
                    if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Building the dictionary of language-specific headers and footers");

                    string[] possible_header_files = Directory.GetFiles(html_soure_directory, "*.htm*");
                    foreach (string thisHeaderFile in possible_header_files)
                    {
                        // Get the filename
                        string fileName = Path.GetFileName(thisHeaderFile);

                        // Should not ever really be null, but if so. just skip it
                        if (String.IsNullOrEmpty(fileName))
                            continue;

                        // Was this an item header file?
                        if (fileName.IndexOf("header_item", StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // If this is default (with no language specified) add as DEFAULT
                            if (fileName.ToLower().Contains("header_item.htm"))
                            {
                                if (completeSkin.SourceFiles.ContainsKey(Web_Language_Enum.DEFAULT))
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT].Header_Item_Source_File = Path.Combine("html", fileName);
                                else
                                {
                                    Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Header_Item_Source_File = Path.Combine("html", fileName) };
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT] = sourceFiles;
                                }
                            }
                            else
                            {
                                // Look for and parse the language code in the file
                                string[] parsed = fileName.Split("_-.".ToCharArray());
                                if (parsed.Length == 4)
                                {
                                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(parsed[2]);
                                    if (languageEnum != Web_Language_Enum.UNDEFINED)
                                    {
                                        if (completeSkin.SourceFiles.ContainsKey(languageEnum))
                                            completeSkin.SourceFiles[languageEnum].Header_Item_Source_File = Path.Combine("html", fileName);
                                        else
                                        {
                                            Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Header_Item_Source_File = Path.Combine("html", fileName) };
                                            completeSkin.SourceFiles[languageEnum] = sourceFiles;
                                        }
                                    }
                                }
                            }
                        }
                        // Was this a non-item header file?
                        else if (fileName.IndexOf("header", StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // If this is default (with no language specified) add as DEFAULT
                            if (fileName.ToLower().Contains("header.htm"))
                            {
                                if (completeSkin.SourceFiles.ContainsKey(Web_Language_Enum.DEFAULT))
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT].Header_Source_File = Path.Combine("html", fileName);
                                else
                                {
                                    Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Header_Source_File = Path.Combine("html", fileName) };
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT] = sourceFiles;
                                }
                            }
                            else
                            {
                                // Look for and parse the language code in the file
                                string[] parsed = fileName.Split("_-.".ToCharArray());
                                if (parsed.Length == 3)
                                {
                                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(parsed[1]);
                                    if (languageEnum != Web_Language_Enum.UNDEFINED)
                                    {
                                        if (completeSkin.SourceFiles.ContainsKey(languageEnum))
                                            completeSkin.SourceFiles[languageEnum].Header_Source_File = Path.Combine("html", fileName);
                                        else
                                        {
                                            Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Header_Source_File = Path.Combine("html", fileName) };
                                            completeSkin.SourceFiles[languageEnum] = sourceFiles;
                                        }
                                    }
                                }
                            }
                        }
                        // Was this a item footer file?
                        else if (fileName.IndexOf("footer_item", StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // If this is default (with no language specified) add as DEFAULT
                            if (fileName.ToLower().Contains("footer_item.htm"))
                            {
                                if (completeSkin.SourceFiles.ContainsKey(Web_Language_Enum.DEFAULT))
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT].Footer_Item_Source_File = Path.Combine("html", fileName);
                                else
                                {
                                    Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Footer_Item_Source_File = Path.Combine("html", fileName) };
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT] = sourceFiles;
                                }
                            }
                            else
                            {
                                // Look for and parse the language code in the file
                                string[] parsed = fileName.Split("_-.".ToCharArray());
                                if (parsed.Length == 4)
                                {
                                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(parsed[2]);
                                    if (languageEnum != Web_Language_Enum.UNDEFINED)
                                    {
                                        if (completeSkin.SourceFiles.ContainsKey(languageEnum))
                                            completeSkin.SourceFiles[languageEnum].Footer_Item_Source_File = Path.Combine("html", fileName);
                                        else
                                        {
                                            Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Footer_Item_Source_File = Path.Combine("html", fileName) };
                                            completeSkin.SourceFiles[languageEnum] = sourceFiles;
                                        }
                                    }
                                }
                            }
                        }
                        // Was this a non-item footer file?
                        else if (fileName.IndexOf("footer", StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // If this is default (with no language specified) add as DEFAULT
                            if (fileName.ToLower().Contains("footer.htm"))
                            {
                                if (completeSkin.SourceFiles.ContainsKey(Web_Language_Enum.DEFAULT))
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT].Footer_Item_Source_File = Path.Combine("html", fileName);
                                else
                                {
                                    Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Footer_Source_File = Path.Combine("html", fileName) };
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT] = sourceFiles;
                                }
                            }
                            else
                            {
                                // Look for and parse the language code in the file
                                string[] parsed = fileName.Split("_-.".ToCharArray());
                                if (parsed.Length == 3)
                                {
                                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(parsed[1]);
                                    if (languageEnum != Web_Language_Enum.UNDEFINED)
                                    {
                                        if (completeSkin.SourceFiles.ContainsKey(languageEnum))
                                            completeSkin.SourceFiles[languageEnum].Footer_Source_File = Path.Combine("html", fileName);
                                        else
                                        {
                                            Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files { Footer_Source_File = Path.Combine("html", fileName) };
                                            completeSkin.SourceFiles[languageEnum] = sourceFiles;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Unable to find the design folder ( '" + html_soure_directory + "')");
                    completeSkin.Exception = "Unable to find the design folder ( '" + html_soure_directory + "')";
                }
            }
            catch (Exception ee)
            {
                if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Exception encountered while checking for web skin source files: " + ee.Message);
                completeSkin.Exception = "Exception encountered while checking for web skin source files: " + ee.Message;
            }

            // Look for banners as well
            if (override_banner)
            {
                try
                {
                    string banner_source_directory = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location, "skins", code);
                    if (Directory.Exists(banner_source_directory))
                    {
                        string[] possible_banner_files = Directory.GetFiles(banner_source_directory, "banner*.*");
                        foreach (string thisBannerFile in possible_banner_files)
                        {
                            // Get the filename
                            string fileName = Path.GetFileName(thisBannerFile);

                            // If this is default (with no language specified) add as DEFAULT
                            if (fileName.ToLower().Contains("banner."))
                            {
                                if (completeSkin.SourceFiles.ContainsKey(Web_Language_Enum.DEFAULT))
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT].Banner = fileName;
                                else
                                {
                                    Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files {Banner = fileName};
                                    completeSkin.SourceFiles[Web_Language_Enum.DEFAULT] = sourceFiles;
                                }
                            }
                            else
                            {
                                // Look for and parse the language code in the file
                                string[] parsed = fileName.Split("_-.".ToCharArray());
                                if (parsed.Length == 3)
                                {
                                    Web_Language_Enum languageEnum = Web_Language_Enum_Converter.Code_To_Enum(parsed[1]);
                                    if (languageEnum != Web_Language_Enum.UNDEFINED)
                                    {
                                        if (completeSkin.SourceFiles.ContainsKey(languageEnum))
                                            completeSkin.SourceFiles[languageEnum].Banner = fileName;
                                        else
                                        {
                                            Complete_Web_Skin_Source_Files sourceFiles = new Complete_Web_Skin_Source_Files {Banner = fileName};
                                            completeSkin.SourceFiles[languageEnum] = sourceFiles;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ee)
                {
                    if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Exception encountered while checking for web skin banner: " + ee.Message);
                    completeSkin.Exception = "Exception encountered while checking for web skin banner: " + ee.Message;
                }
            }

            if (Tracer != null) Tracer.Add_Trace("Web_Skin_Utilities.Build_Skin_Complete", "Return the built complete web skin");

            return completeSkin;
        }
        /// <summary> Constructor for a new instance of the Skin_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 Skin_Single_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            RequestSpecificValues.Tracer.Add_Trace("Skin_Single_AdminViewer.Constructor", String.Empty);

            // Set some defaults
            actionMessage = String.Empty;
            string code = RequestSpecificValues.Current_Mode.My_Sobek_SubMode;

            string page_code = "a";
            if (code.Contains("/"))
            {
                string[] parser = code.Split("/".ToCharArray());
                code = parser[0];
                page_code = parser[1];
            }

            // Determine the page
            page = 1;
            if (page_code == "b")
                page = 2;
            else if (page_code == "c")
                page = 3;
            else if (page_code == "d")
                page = 4;
            else if (page_code == "e")
                page = 5;

            // If the user cannot edit this, go back
            if ((!RequestSpecificValues.Current_User.Is_Portal_Admin ) && ( !RequestSpecificValues.Current_User.Is_System_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;
            }

            // Load the web skin, either currenlty from the session (if already editing this skin )
            // or by building the complete web skin object
            Complete_Web_Skin_Object cachedInstance = HttpContext.Current.Session["Edit_Skin_" + code + "|object"] as Complete_Web_Skin_Object;
            webSkin = cachedInstance ?? SobekEngineClient.WebSkins.Get_Complete_Web_Skin(code, RequestSpecificValues.Tracer);

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

            // Get the dictionary for updated source files
            updatedSourceFiles = HttpContext.Current.Session["Edit_Skin_" + code + "|files"] as Dictionary<string, string> ?? new Dictionary<string, string>();

            // Get the skin directory and ensure it exists
            skinDirectory = HttpContext.Current.Server.MapPath("design/skins/" + webSkin.Skin_Code);
            if (!Directory.Exists(skinDirectory))
                Directory.CreateDirectory(skinDirectory);

            // 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_skin_save"];

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

                    // 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 aggregedit web skin info from the sessions
                        HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|object"] = null;
                        HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|files"] = null;

                        // Redirect the user to the skins mgmt screen
                        RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Skins_Mgmt;
                        UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                        return;
                    }

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

                        case 2:
                            Save_Page_2_Postback(form);
                            break;

                        case 3:
                            Save_Page_3_Postback(form);
                            break;

                        case 4:
                            Save_Page_4_Postback(form);
                            break;

                        case 5:
                            Save_Page_Uploads_Postback(form);
                            break;
                    }

                    // Should this be saved to the database?
                    if ((action == "save") || (action == "save_exit"))
                    {
                        // Save this existing interface
                        bool successful_save = SobekCM_Database.Save_Web_Skin(webSkin.Skin_Code, webSkin.Base_Skin_Code, webSkin.Override_Banner, true, webSkin.Banner_Link, webSkin.Notes, webSkin.Suppress_Top_Navigation, RequestSpecificValues.Tracer);

                        // Prepare the backup folders
                        string backup_folder = skinDirectory + "\\backup\\html";
                        if (!Directory.Exists(backup_folder))
                            Directory.CreateDirectory(backup_folder);
                        string css_backup_folder = skinDirectory + "\\backup\\css";
                        if (!Directory.Exists(css_backup_folder))
                            Directory.CreateDirectory(css_backup_folder);

                        // Also, save all the updated files
                        foreach (KeyValuePair<string, string> pairs in updatedSourceFiles)
                        {
                            try
                            {
                                if (pairs.Key != "CSS")
                                {
                                    string filename = Path.Combine(skinDirectory, pairs.Key);
                                    if (String.IsNullOrEmpty(pairs.Value))
                                    {
                                        if (File.Exists(filename))
                                        {
                                            // Use the last modified date as the name of the backup
                                            DateTime lastModifiedDate = (new FileInfo(filename)).LastWriteTime;
                                            string backup_name = Path.GetFileName(filename).Replace(Path.GetExtension(filename), "") + lastModifiedDate.Year + lastModifiedDate.Month.ToString().PadLeft(2, '0') + lastModifiedDate.Day.ToString().PadLeft(2, '0') + lastModifiedDate.Hour.ToString().PadLeft(2, '0') + lastModifiedDate.Minute.ToString().PadLeft(2, '0') + Path.GetExtension(filename);
                                            if (!File.Exists(backup_folder + "\\" + backup_name))
                                                File.Copy(filename, backup_folder + "\\" + backup_name, false);

                                            // Now, delete the file
                                            File.Delete(filename);
                                        }
                                    }
                                    else
                                    {
                                        string fullName = Path.Combine(skinDirectory, filename);
                                        if (File.Exists(fullName))
                                        {
                                            StreamReader reader = new StreamReader(fullName);
                                            string current_contents = reader.ReadToEnd();
                                            reader.Close();

                                            if (String.CompareOrdinal(pairs.Value.Replace("[%", "<%").Replace("%]", "%>"), current_contents) != 0)
                                            {
                                                // Use the last modified date as the name of the backup
                                                DateTime lastModifiedDate = (new FileInfo(filename)).LastWriteTime;
                                                string backup_name = Path.GetFileName(filename).Replace(Path.GetExtension(filename), "") + lastModifiedDate.Year + lastModifiedDate.Month.ToString().PadLeft(2, '0') + lastModifiedDate.Day.ToString().PadLeft(2, '0') + lastModifiedDate.Hour.ToString().PadLeft(2, '0') + lastModifiedDate.Minute.ToString().PadLeft(2, '0') + Path.GetExtension(filename);
                                                if (!File.Exists(backup_folder + "\\" + backup_name))
                                                    File.Copy(fullName, backup_folder + "\\" + backup_name, false);

                                                StreamWriter writer = new StreamWriter(fullName, false);
                                                writer.Write(pairs.Value.Replace("[%", "<%").Replace("%]", "%>"));
                                                writer.Flush();
                                                writer.Close();
                                            }
                                        }
                                        else
                                        {
                                            StreamWriter writer = new StreamWriter(fullName, false);
                                            writer.Write(pairs.Value.Replace("[%", "<%").Replace("%]", "%>"));
                                            writer.Flush();
                                            writer.Close();
                                        }
                                    }
                                }
                                else
                                {
                                    string new_skin_file = Path.Combine(skinDirectory, webSkin.CSS_Style);
                                    if (File.Exists(new_skin_file))
                                    {
                                        StreamReader reader = new StreamReader(new_skin_file);
                                        string current_contents = reader.ReadToEnd();
                                        reader.Close();

                                        if (String.CompareOrdinal(pairs.Value, current_contents) != 0)
                                        {
                                            // Use the last modified date as the name of the backup
                                            DateTime lastModifiedDate = (new FileInfo(new_skin_file)).LastWriteTime;
                                            string backup_name = Path.GetFileName(new_skin_file).Replace(Path.GetExtension(new_skin_file), "") + lastModifiedDate.Year + lastModifiedDate.Month.ToString().PadLeft(2, '0') + lastModifiedDate.Day.ToString().PadLeft(2, '0') + lastModifiedDate.Hour.ToString().PadLeft(2, '0') + lastModifiedDate.Minute.ToString().PadLeft(2, '0') + Path.GetExtension(new_skin_file);
                                            if (!File.Exists(css_backup_folder + "\\" + backup_name))
                                                File.Copy(new_skin_file, css_backup_folder + "\\" + backup_name, false);

                                            StreamWriter writer = new StreamWriter(new_skin_file, false);
                                            writer.Write(pairs.Value);
                                            writer.Flush();
                                            writer.Close();
                                        }
                                    }
                                    else
                                    {
                                        StreamWriter writer = new StreamWriter(new_skin_file, false);
                                        writer.Write(pairs.Value.Replace("[%", "<%").Replace("%]", "%>"));
                                        writer.Flush();
                                        writer.Close();
                                    }
                                }
                            }
                            catch
                            {

                            }
                        }

                        lock (UI_ApplicationCache_Gateway.Web_Skin_Collection)
                        {
                            Web_Skin_Utilities.Populate_Default_Skins(UI_ApplicationCache_Gateway.Web_Skin_Collection, RequestSpecificValues.Tracer);
                        }
                        CachedDataManager.WebSkins.Remove_Skin(webSkin.Skin_Code, RequestSpecificValues.Tracer);

                        if (successful_save)
                        {
                            if (action == "save_exit")
                            {
                                // Clear the aggregedit web skin info from the sessions
                                HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|object"] = null;
                                HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|files"] = null;

                                // Redirect the user to the skins mgmt screen
                                RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Skins_Mgmt;
                                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                            }
                        }
                        else
                        {
                            actionMessage = "Unable to edit existing html skin <i>" + webSkin.Skin_Code + "</i>";
                        }
                    }
                    else
                    {
                        string new_lang = String.Empty;
                        if (action == "new_lang")
                        {
                            action = "c";
                            string new_language = form["webskin_new_lang"];
                            string copy_language = form["webskin_new_lang_copy"];

                            Web_Language_Enum new_language_enum = Web_Language_Enum_Converter.Code_To_Enum(new_language);
                            new_lang = new_language;

                            if (!webSkin.SourceFiles.ContainsKey(new_language_enum))
                            {
                                string language_code = "_" + new_language;

                                Complete_Web_Skin_Source_Files sources = new Complete_Web_Skin_Source_Files();
                                sources.Header_Source_File = "html\\header" + language_code + ".html";
                                sources.Footer_Source_File = "html\\footer" + language_code + ".html";
                                sources.Header_Item_Source_File = "html\\header_item" + language_code + ".html";
                                sources.Footer_Item_Source_File = "html\\footer_item" + language_code + ".html";
                                webSkin.SourceFiles[new_language_enum] = sources;

                                updatedSourceFiles[sources.Header_Source_File] = String.Empty;
                                updatedSourceFiles[sources.Footer_Source_File] = String.Empty;
                                updatedSourceFiles[sources.Header_Item_Source_File] = String.Empty;
                                updatedSourceFiles[sources.Footer_Item_Source_File] = String.Empty;

                                if (!String.IsNullOrEmpty(copy_language))
                                {
                                    Web_Language_Enum copy_language_enum = Web_Language_Enum_Converter.Code_To_Enum(copy_language);
                                    if (copy_language == "def")
                                        copy_language_enum = Web_Language_Enum.DEFAULT;

                                    if (webSkin.SourceFiles.ContainsKey(copy_language_enum))
                                    {
                                        Complete_Web_Skin_Source_Files copy_sources = webSkin.SourceFiles[copy_language_enum];
                                        updatedSourceFiles[sources.Header_Source_File] = get_file_source(copy_sources.Header_Source_File);
                                        updatedSourceFiles[sources.Footer_Source_File] = get_file_source(copy_sources.Footer_Source_File);
                                        updatedSourceFiles[sources.Header_Item_Source_File] = get_file_source(copy_sources.Header_Item_Source_File);
                                        updatedSourceFiles[sources.Footer_Item_Source_File] = get_file_source(copy_sources.Footer_Item_Source_File);
                                    }
                                }

                            }
                        }

                        // Determine the base URL to redirect to
                        RequestSpecificValues.Current_Mode.My_Sobek_SubMode = code + "/" + action;

                        // Delete language support for a single language?
                        if (action == "delete_skin")
                        {
                            string lang = form["admin_skin_language"];
                            if (lang.IndexOf("-") == 0)
                            {
                                Web_Language_Enum langEnum = Web_Language_Enum_Converter.Code_To_Enum(lang.Substring(1));
                                if (webSkin.SourceFiles.ContainsKey(langEnum))
                                {
                                    Complete_Web_Skin_Source_Files sources = webSkin.SourceFiles[langEnum];
                                    webSkin.SourceFiles.Remove(langEnum);
                                    updatedSourceFiles[sources.Header_Source_File] = String.Empty;
                                    updatedSourceFiles[sources.Footer_Source_File] = String.Empty;
                                    updatedSourceFiles[sources.Header_Item_Source_File] = String.Empty;
                                    updatedSourceFiles[sources.Footer_Item_Source_File] = String.Empty;
                                }
                            }

                            RequestSpecificValues.Current_Mode.My_Sobek_SubMode = code + "/c";
                        }

                        // Save the updated info
                        HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|object"] = webSkin;
                        HttpContext.Current.Session["Edit_Skin_" + webSkin.Skin_Code + "|files"] = updatedSourceFiles;

                        string url = UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode);

                        if (action == "c")
                        {
                            string lang = form["admin_skin_language"];
                            if (new_lang.Length > 0)
                                lang = new_lang;

                            if (!String.IsNullOrEmpty(lang))
                            {
                                if (url.Contains("?"))
                                    url = url + "&lang=" + lang;
                                else
                                    url = url + "?lang=" + lang;
                            }
                        }

                        HttpContext.Current.Response.Redirect(url, false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        RequestSpecificValues.Current_Mode.Request_Completed = true;
                    }
                }
                catch
                {
                    actionMessage = "Unable to correctly parse postback data.";
                }
            }
        }