/// <summary> Constructor for a new instance of the Thematic_Headings_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling saving the new settings is handled here in the constructor </remarks>
        public Settings_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            // Determine the extension codes
            extensionCodes = new List<string>();
            if ((UI_ApplicationCache_Gateway.Configuration.Extensions != null) && (UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions != null) && (UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions.Count > 0))
            {
                SortedList<string, string> extensionSorter = new SortedList<string, string>();
                foreach (ExtensionInfo thisInfo in UI_ApplicationCache_Gateway.Configuration.Extensions.Extensions)
                    extensionSorter[thisInfo.Code] = thisInfo.Code;
                extensionCodes = extensionSorter.Values.ToList();
            }

            // If the RequestSpecificValues.Current_User cannot edit this, go back
            if (( RequestSpecificValues.Current_User == null ) || ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Portal_Admin)))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Determine if this user has limited rights
            if ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Host_Admin))
            {
                limitedRightsMode = true;
                readonlyMode = true;
            }
            else
            {
                limitedRightsMode = ((!RequestSpecificValues.Current_User.Is_Host_Admin) && (UI_ApplicationCache_Gateway.Settings.Servers.isHosted));
                readonlyMode = false;
            }

            // Load the settings either from the local session, or from the engine
            currSettings = HttpContext.Current.Session["Admin_Settings"] as Admin_Setting_Collection;
            if (currSettings == null)
            {
                currSettings = SobekEngineClient.Admin.Get_Admin_Settings(RequestSpecificValues.Tracer);
                if (currSettings != null)
                {
                    HttpContext.Current.Session["Admin_Settigs"] = currSettings;

                    // Build the setting values
                    build_setting_objects_for_display();
                }
                else
                {
                    actionMessage = "Error pulling the settings from the engine";
                }
            }

            #region Determine the mode and submode

            // Determine the current mode and submode
            if ((RequestSpecificValues.Current_Mode.Remaining_Url_Segments != null) && (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 0))
            {
                switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[0].ToLower())
                {
                    case "settings":
                        mainMode = Settings_Mode_Enum.Settings;
                        break;

                    case "config":
                        mainMode = Settings_Mode_Enum.Configuration;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "files":
                                    configSubMode = Settings_Configuration_SubMode_Enum.Files;
                                    break;

                                case "log":
                                    configSubMode = Settings_Configuration_SubMode_Enum.Reading_Log;
                                    break;
                            }
                        }
                        break;

                    case "builder":
                        mainMode = Settings_Mode_Enum.Builder;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "settings":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Settings;
                                    break;

                                case "folders":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Folders;
                                    break;

                                case "modules":
                                    builderSubEnum = Settings_Builder_SubMode_Enum.Builder_Modules;
                                    break;
                            }
                        }
                        break;

                    case "metadata":
                        mainMode = Settings_Mode_Enum.Metadata;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "fields":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Fields;
                                    break;

                                case "filereaders":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Metdata_Reader_Writers;
                                    break;

                                case "metsreaders":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.METS_Section_Reader_Writers;
                                    break;

                                case "metsprofiles":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.METS_Writing_Profiles;
                                    break;

                                case "modules":
                                    metadataSubEnum = Settings_Metadata_SubMode_Enum.Metadata_Modules_To_Include;
                                    break;
                            }
                        }
                        break;

                    case "engine":
                        mainMode = Settings_Mode_Enum.Engine;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "authentication":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Authentication;
                                    break;

                                case "briefitem":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Brief_Item_Mapping;
                                    break;

                                case "contact":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Contact_Form;
                                    break;

                                case "endpoints":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.Engine_Server_Endpoints;
                                    break;

                                case "oaipmh":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.OAI_PMH;
                                    break;

                                case "qctool":
                                    engineSubEnum = Settings_Engine_SubMode_Enum.QcTool;
                                    break;
                            }
                        }
                        break;

                    case "ui":
                        mainMode = Settings_Mode_Enum.UI;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "citation":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Citation_Viewer;
                                    break;

                                case "mapeditor":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Map_Editor;
                                    break;

                                case "microservices":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Microservice_Client_Endpoints;
                                    break;

                                case "template":
                                    uiSubEnum = Settings_UI_SubMode_Enum.Template_Elements;
                                    break;

                                case "viewers":
                                    uiSubEnum = Settings_UI_SubMode_Enum.HTML_Viewer_Subviewers;
                                    break;
                            }
                        }
                        break;

                    case "html":
                        mainMode = Settings_Mode_Enum.HTML;
                        if (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1)
                        {
                            switch (RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1].ToLower())
                            {
                                case "missing":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.Missing_Page;
                                    break;

                                case "noresults":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.No_Results;
                                    break;

                                case "usageemail":
                                    htmlSubEnum = Settings_HTML_SubMode_Enum.Usage_Email;
                                    break;
                            }
                        }
                        break;

                    case "extensions":
                        extensionSubMode = -1;
                        mainMode = Settings_Mode_Enum.Extensions;
                        if ((extensionCodes.Count > 0) && (RequestSpecificValues.Current_Mode.Remaining_Url_Segments.Length > 1))
                        {
                            int tryExtensionNum;
                            if (Int32.TryParse(RequestSpecificValues.Current_Mode.Remaining_Url_Segments[1], out tryExtensionNum))
                            {
                                if ((tryExtensionNum > 0) && (tryExtensionNum <= extensionCodes.Count))
                                    extensionSubMode = tryExtensionNum;
                            }
                        }
                        break;
                }
            }

            #endregion

            // Establish some default, starting values
            actionMessage = String.Empty;
            category_view = Convert.ToBoolean(RequestSpecificValues.Current_User.Get_Setting("Settings_AdminViewer:Category_View", "false"));

            // Determine the redirect URL now
            string[] origUrlSegments = RequestSpecificValues.Current_Mode.Remaining_Url_Segments;
            RequestSpecificValues.Current_Mode.Remaining_Url_Segments = new string[] { "%SETTINGSCODE%" };
            redirectUrl = UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode);
            RequestSpecificValues.Current_Mode.Remaining_Url_Segments = origUrlSegments;

            // Is this a post-back requesting to save all this data?
            if (RequestSpecificValues.Current_Mode.isPostBack)
            {
                NameValueCollection form = HttpContext.Current.Request.Form;

                if (form["admin_settings_order"] == "category")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "true");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "true");
                    category_view = true;
                }

                if (form["admin_settings_order"] == "alphabetical")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "false");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "false");
                    category_view = false;
                }

                string action_value = form["admin_settings_action"];
                if ((action_value == "save") && (RequestSpecificValues.Current_User.Is_System_Admin))
                {
                    save_setting_values(RequestSpecificValues, mainMode );
                }
                if ((mainMode == Settings_Mode_Enum.Extensions) && (extensionSubMode > 0))
                {
                    // Get the code
                    string plugin_code = extensionCodes[extensionSubMode - 1];
                    if (action_value == "enable_plugin")
                    {
                        EnableExtensionMessage response = SobekEngineClient.Admin.Plugin_Enable(plugin_code, RequestSpecificValues.Tracer);
                        actionMessage = response.Message;

                        // If not successful, and there are errors, copy those over
                        if ((!response.Success) && (response.Errors != null) && (response.Errors.Count > 0))
                        {
                            actionMessage = actionMessage + "<ul>";
                            foreach (string thisError in response.Errors)
                                actionMessage = actionMessage + "<li>" + thisError + "</li>";
                            actionMessage = actionMessage + "</ul>";
                        }
                    }

                    if (action_value == "disable_plugin")
                    {
                        EnableExtensionMessage response = SobekEngineClient.Admin.Plugin_Disable(plugin_code, RequestSpecificValues.Tracer);
                        actionMessage = response.Message;

                        // If not successful, and there are errors, copy those over
                        if ((!response.Success) && (response.Errors != null) && (response.Errors.Count > 0))
                        {
                            actionMessage = actionMessage + "<ul>";
                            foreach (string thisError in response.Errors)
                                actionMessage = actionMessage + "<li>" + thisError + "</li>";
                            actionMessage = actionMessage + "</ul>";
                        }
                    }
                }
                if (mainMode == Settings_Mode_Enum.HTML)
                {
                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.Missing_Page)
                    {
                        try
                        {
                            string missing_contents = form["missing_page_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "webcontent", "missing.html");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(missing_contents);
                            writer.Flush();
                            writer.Close();

                            SobekEngineClient.WebContent.Clear_Special_Missing_Page(RequestSpecificValues.Tracer);
                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the new missing page HTML to the file.";
                        }
                    }

                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.No_Results)
                    {
                        try
                        {
                            string no_results_content = form["no_results_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "webcontent", "noresults.html");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(no_results_content);
                            writer.Flush();
                            writer.Close();

                            HttpContext.Current.Application["NORESULTS"] = null;
                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the no results page HTML to the file.";
                        }
                    }

                    if (htmlSubEnum == Settings_HTML_SubMode_Enum.Usage_Email)
                    {
                        try
                        {
                            string usage_email_content = form["usage_email_content"].Trim();
                            string file_name = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "design", "extra", "stats", "stats_email_body.txt");
                            StreamWriter writer = new StreamWriter(file_name, false);
                            writer.Write(usage_email_content.Replace("[%", "<%").Replace("%]", "%>"));
                            writer.Flush();
                            writer.Close();

                            actionMessage = "Updated the statistics usage email body text.";

                        }
                        catch
                        {
                            actionMessage = "ERROR: Unable to write the usage email body to the file.";
                        }
                    }

                }

            }
        }
        /// <summary> Gets the administrative setting values, which includes display information
        /// along with the current value and key </summary>
        /// <param name="Response"></param>
        /// <param name="UrlSegments"></param>
        /// <param name="QueryString"></param>
        /// <param name="Protocol"></param>
        /// <param name="IsDebug"></param>
        public void GetAdminSettings(HttpResponse Response, List<string> UrlSegments, NameValueCollection QueryString, Microservice_Endpoint_Protocol_Enum Protocol, bool IsDebug)
        {
            Custom_Tracer tracer = new Custom_Tracer();

            try
            {
                tracer.Add_Trace("AdministrativeServices.GetAdminSettings", "Pulling dataset from the database");

                // Get the complete aggregation
                DataSet adminSet = Engine_Database.Get_Settings_Complete(true, tracer);

                // If the returned value from the database was NULL, there was an error
                if ((adminSet == null) || (adminSet.Tables.Count == 0) || ( adminSet.Tables[0].Rows.Count == 0))
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("Error completing request");

                    if (IsDebug)
                    {
                        Response.Output.WriteLine("DataSet returned from the database was either NULL or empty");
                        if (Engine_Database.Last_Exception != null)
                        {
                            Response.Output.WriteLine();
                            Response.Output.WriteLine(Engine_Database.Last_Exception.Message);
                            Response.Output.WriteLine();
                            Response.Output.WriteLine(Engine_Database.Last_Exception.StackTrace);
                        }

                        Response.Output.WriteLine();
                        Response.Output.WriteLine(tracer.Text_Trace);
                    }

                    Response.StatusCode = 500;
                    return;
                }

                tracer.Add_Trace("AdministrativeServices.GetAdminSettings", "Build the list of return objects");
                Admin_Setting_Collection returnValue = new Admin_Setting_Collection();

                try
                {
                    DataColumn keyColumn = adminSet.Tables[0].Columns["Setting_Key"];
                    DataColumn valueColumn = adminSet.Tables[0].Columns["Setting_Value"];
                    DataColumn tabPageColumn = adminSet.Tables[0].Columns["TabPage"];
                    DataColumn headingColumn = adminSet.Tables[0].Columns["Heading"];
                    DataColumn hiddenColumn = adminSet.Tables[0].Columns["Hidden"];
                    DataColumn reservedColumn = adminSet.Tables[0].Columns["Reserved"];
                    DataColumn helpColumn = adminSet.Tables[0].Columns["Help"];
                    DataColumn optionsColumn = adminSet.Tables[0].Columns["Options"];
                    DataColumn idColumn = adminSet.Tables[0].Columns["SettingID"];
                    DataColumn dimensionsColumn = adminSet.Tables[0].Columns["Dimensions"];

                    //Setting_Key, Setting_Value, TabPage, Heading, Hidden, Reserved, Help, Options

                    // Build the return values
                    foreach (DataRow thisRow in adminSet.Tables[0].Rows)
                    {
                        // Build the value object
                        Admin_Setting_Value thisValue = new Admin_Setting_Value
                        {
                            Key = thisRow[keyColumn].ToString(),
                            Value = thisRow[valueColumn] == DBNull.Value ? null : thisRow[valueColumn].ToString(),
                            TabPage = thisRow[tabPageColumn] == DBNull.Value ? null : thisRow[tabPageColumn].ToString(),
                            Heading = thisRow[headingColumn] == DBNull.Value ? null : thisRow[headingColumn].ToString(),
                            Hidden = bool.Parse(thisRow[hiddenColumn].ToString()),
                            Reserved = short.Parse(thisRow[reservedColumn].ToString()),
                            Help = thisRow[helpColumn] == DBNull.Value ? null : thisRow[helpColumn].ToString(),
                            SettingID = short.Parse(thisRow[idColumn].ToString())
                        };

                        // Get dimensions, if some were provided
                        if (thisRow[dimensionsColumn] != DBNull.Value)
                        {
                            string dimensions = thisRow[dimensionsColumn].ToString();
                            if (!String.IsNullOrWhiteSpace(dimensions))
                            {
                                short testWidth;
                                short testHeight;

                                // Does this include width AND height?
                                if (dimensions.IndexOf("|") >= 0)
                                {
                                    string[] splitter = dimensions.Split("|".ToCharArray());
                                    if ((splitter[0].Length > 0) && ( short.TryParse(splitter[0], out testWidth )))
                                    {
                                        thisValue.Width = testWidth;
                                        if ((splitter[1].Length > 0) && (short.TryParse(splitter[1], out testHeight)))
                                        {
                                            thisValue.Height = testHeight;

                                        }
                                    }
                                }
                                else
                                {
                                    if (short.TryParse(dimensions, out testWidth))
                                    {
                                        thisValue.Width = testWidth;
                                    }
                                }
                            }
                        }

                        // Get the options
                        if (thisRow[optionsColumn] != DBNull.Value)
                        {
                            string[] options = thisRow[optionsColumn].ToString().Split("|".ToCharArray());
                            foreach( string thisOption in options )
                                thisValue.Add_Option(thisOption.Trim());
                        }

                        // Add to the return value
                        returnValue.Settings.Add(thisValue);
                    }

                }
                catch (Exception ex)
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("Error completing request");

                    if (IsDebug)
                    {
                        Response.Output.WriteLine("Error creating the Builder_Settings object from the database tables");
                        Response.Output.WriteLine();
                        Response.Output.WriteLine(ex.Message);
                        Response.Output.WriteLine();
                        Response.Output.WriteLine(ex.StackTrace);
                        Response.Output.WriteLine();
                        Response.Output.WriteLine(tracer.Text_Trace);
                    }

                    Response.StatusCode = 500;
                    return;
                }

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

                    return;
                }

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

                // Use the base class to serialize the object according to request protocol
                Serialize(returnValue, Response, Protocol, json_callback);
            }
            catch (Exception ee)
            {
                if (IsDebug)
                {
                    Response.ContentType = "text/plain";
                    Response.Output.WriteLine("EXCEPTION CAUGHT!");
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(ee.Message);
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(ee.StackTrace);
                    Response.Output.WriteLine();
                    Response.Output.WriteLine(tracer.Text_Trace);
                    return;
                }

                Response.ContentType = "text/plain";
                Response.Output.WriteLine("Error completing request");
                Response.StatusCode = 500;
            }
        }
        /// <summary> Constructor for a new instance of the Thematic_Headings_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling saving the new settings is handled here in the constructor </remarks>
        public Settings_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            // If the RequestSpecificValues.Current_User cannot edit this, go back
            if (( RequestSpecificValues.Current_User == null ) || ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Portal_Admin)))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Determine if this user has limited rights
            if ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Host_Admin))
            {
                limitedRightsMode = true;
                readonlyMode = true;
            }
            else
            {
                limitedRightsMode = ((!RequestSpecificValues.Current_User.Is_Host_Admin) && (UI_ApplicationCache_Gateway.Settings.isHosted));
                readonlyMode = false;
            }

            // Load the settings either from the local session, or from the engine
            currSettings = HttpContext.Current.Session["Admin_Settings"] as Admin_Setting_Collection;
            if (currSettings == null)
            {
                currSettings = SobekEngineClient.Admin.Get_Admin_Settings(RequestSpecificValues.Tracer);
                if (currSettings != null)
                {
                    HttpContext.Current.Session["Admin_Settigs"] = currSettings;

                    // Build the setting values
                    build_setting_objects_for_display();
                }
                else
                {
                    actionMessage = "Error pulling the settings from the engine";
                }
            }

            // Establish some default, starting values
            actionMessage = String.Empty;
            category_view = Convert.ToBoolean(RequestSpecificValues.Current_User.Get_Setting("Settings_AdminViewer:Category_View", "false"));

            // Is this a post-back requesting to save all this data?
            if (RequestSpecificValues.Current_Mode.isPostBack)
            {
                NameValueCollection form = HttpContext.Current.Request.Form;

                if (form["admin_settings_order"] == "category")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "true");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "true");
                    category_view = true;
                }

                if (form["admin_settings_order"] == "alphabetical")
                {
                    RequestSpecificValues.Current_User.Add_Setting("Settings_AdminViewer:Category_View", "false");
                    SobekCM_Database.Set_User_Setting(RequestSpecificValues.Current_User.UserID, "Settings_AdminViewer:Category_View", "false");
                    category_view = false;
                }

                string action_value = form["admin_settings_action"];
                if ((action_value == "save") && (RequestSpecificValues.Current_User.Is_System_Admin))
                {
                    // If this was read-only, really shouldn't do anything here
                    if (readonlyMode)
                        return;

                    // First, create the setting lookup by ID, and the list of IDs to look for
                    List<short> settingIds = new List<short>();
                    Dictionary<short, Admin_Setting_Value> settingsObjsById = new Dictionary<short, Admin_Setting_Value>();
                    foreach (Admin_Setting_Value Value in currSettings.Settings)
                    {
                        // If this is readonly, will not prepare to update
                        if ((!Is_Value_ReadOnly(Value, readonlyMode, limitedRightsMode )) && ( !Value.Hidden ))
                        {
                            settingIds.Add(Value.SettingID);
                            settingsObjsById[Value.SettingID] = Value;
                        }
                    }

                    // Now, step through and get the values for each of these
                    List<Simple_Setting> newValues = new List<Simple_Setting>();
                    foreach (short id in settingIds)
                    {
                        // Get the setting information
                        Admin_Setting_Value thisValue = settingsObjsById[id];

                        if (form["setting" + id] != null)
                        {
                            newValues.Add(new Simple_Setting(thisValue.Key, form["setting" + id], thisValue.SettingID));
                        }
                        else
                        {
                            newValues.Add(new Simple_Setting(thisValue.Key, String.Empty, thisValue.SettingID));
                        }
                    }

                    // Now, validate all this
                    errorBuilder = new StringBuilder();
                    isValid = true;
                    validate_update_entered_data(newValues);

                    // Now, assign the values from the simple settings back to the main settings
                    // object.  This is to allow for the validation process to make small changes
                    // to the values the user entered, like different starts or endings
                    foreach (Simple_Setting thisSetting in newValues)
                    {
                        settingsObjsById[thisSetting.SettingID].Value = thisSetting.Value;
                    }

                    if ( isValid )
                    {
                        // Try to save each setting
                        //errors += newSettings.Keys.Count(ThisKey => !SobekCM_Database.Set_Setting(ThisKey, newSettings[ThisKey]));

                        // Prepare the action message
                       // if (errors > 0)
                       //     actionMessage = "Save completed, but with " + errors + " errors.";
                       // else
                            actionMessage = "Settings saved";

                        // Assign this to be used by the system
                        UI_ApplicationCache_Gateway.ResetSettings();

                        // Also, reset the source for static files, as thatmay have changed
                        Static_Resources.Config_Read_Attempted = false;

                        // Get all the settings again
                        build_setting_objects_for_display();
                    }
                    else
                    {
                        actionMessage = errorBuilder.ToString().Replace("\n", "<br />");
                    }
                }
            }
        }