private static bool read_citation_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            bool errorEncountered = false;

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "clearall":
                                Config.UI.CitationViewer.Clear();
                                break;

                            case "citationset":
                                string setName = "UNNAMED";
                                if (ReaderXml.MoveToAttribute("Name"))
                                    setName = ReaderXml.Value.Trim();
                                // Ensure a setname exists
                                if (String.IsNullOrEmpty(setName))
                                    setName = "AUTOSETNAME" + (Config.UI.CitationViewer.CitationSets.Count + 1);

                                // Is this the (new) default
                                if (ReaderXml.MoveToAttribute("Default"))
                                {
                                    if (String.Compare(ReaderXml.Value.Trim(), "true", StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        Config.UI.CitationViewer.DefaultCitationSet = setName;
                                    }
                                }

                                // Create the citation set and add it, or get the existing
                                CitationSet citationSet = Config.UI.CitationViewer.Add_CitationSet(setName);

                                // Read all the details for this citation set
                                ReaderXml.MoveToElement();
                                read_citation_set_details(ReaderXml.ReadSubtree(), citationSet);

                                break;
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_citation_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
                errorEncountered = true;
            }

            // If there was an error while reading, use the system defaults
            if (errorEncountered)
            {
                Config.Metadata.Clear();
                Config.Metadata.Set_Default_Values();
            }

            return !errorEncountered;
        }
        private static void read_authentication_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            // Ensure the config object exists
            if (Config.UI.MapEditor == null)
                Config.UI.MapEditor = new MapEditor_Configuration();

            while (ReaderXml.Read())
            {
                // Only detect start elements.
                if (ReaderXml.IsStartElement())
                {
                    // Get element name and switch on it.
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "shibboleth":
                            // Ensure the object is there then
                            if (Config.Authentication.Shibboleth == null)
                                Config.Authentication.Shibboleth = new Shibboleth_Configuration();

                            // Read the attributes
                            if (ReaderXml.MoveToAttribute("UserIdentityAttribute"))
                                Config.Authentication.Shibboleth.UserIdentityAttribute = ReaderXml.Value.Trim();

                            if (ReaderXml.MoveToAttribute("URL"))
                                Config.Authentication.Shibboleth.ShibbolethURL = ReaderXml.Value.Trim();

                            if (ReaderXml.MoveToAttribute("Label"))
                                Config.Authentication.Shibboleth.Label = ReaderXml.Value.Trim();

                            if (ReaderXml.MoveToAttribute("Debug"))
                            {
                                if (String.Compare(ReaderXml.Value.Trim(), "true", StringComparison.OrdinalIgnoreCase) == 0)
                                    Config.Authentication.Shibboleth.Debug = true;
                            }

                            if (ReaderXml.MoveToAttribute("Enabled"))
                            {
                                if (String.Compare(ReaderXml.Value.Trim(), "false", StringComparison.OrdinalIgnoreCase) == 0)
                                    Config.Authentication.Shibboleth.Enabled = false;
                            }
                            ReaderXml.MoveToElement();
                            read_shibb_details(ReaderXml.ReadSubtree(), Config);

                            break;
                    }
                }
            }
        }
        /// <summary> Read the configuration file for the brief item mapping sets </summary>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        private static bool read_briefitem_mapping_details(XmlReader ReaderXml, InstanceWide_Configuration Config )
        {
            // Ensure the brief item mapping exists
            if (Config.BriefItemMapping == null)
                Config.BriefItemMapping = new BriefItemMapping_Configuration();

            // During this process, small objects ( IBriefItemMappers ) which contain no data
            // but implement the mapping method will be created.  This dictionary helps to ensure
            // each one is created only once.
            Dictionary<string, IBriefItemMapper> mappingObjDictionary = new Dictionary<string, IBriefItemMapper>();

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "mappingset":
                                // Get the ID for this mapping set
                                string id = String.Empty;
                                if (ReaderXml.MoveToAttribute("ID"))
                                    id = ReaderXml.Value.Trim();

                                // Was this indicated as the default set?
                                if (ReaderXml.MoveToAttribute("Default"))
                                {
                                    if (String.Compare(ReaderXml.Value, "true", StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        if (id.Length > 0)
                                            Config.BriefItemMapping.DefaultSetName = id;
                                        else
                                        {
                                            Config.BriefItemMapping.DefaultSetName = "DEFAULT";
                                            id = "DEFAULT";
                                        }
                                    }
                                }

                                BriefItemMapping_Set thisSet = Config.BriefItemMapping.GetMappingSet(id);
                                if (thisSet == null)
                                {
                                    thisSet = new BriefItemMapping_Set {SetName = id};
                                    Config.BriefItemMapping.Add_MappingSet(thisSet);
                                }

                                // Read the set here
                                ReaderXml.MoveToElement();
                                read_mappingset_details(ReaderXml.ReadSubtree(), thisSet, mappingObjDictionary);
                                break;
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_briefitem_mapping_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
                return false;
            }

            return true;
        }
        private static bool read_template_elements_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            bool errorEncountered = false;

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "clearall":
                                Config.UI.TemplateElements.Clear();
                                break;

                            case "templateelement":

                                // Build the new template element info
                                TemplateElementConfig newElement = new TemplateElementConfig();
                                if (ReaderXml.MoveToAttribute("type"))
                                    newElement.Type = ReaderXml.Value.Trim().ToLower();
                                if (ReaderXml.MoveToAttribute("subtype"))
                                    newElement.Subtype = ReaderXml.Value.Trim().ToLower();
                                if (ReaderXml.MoveToAttribute("assembly"))
                                    newElement.Assembly = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("class"))
                                    newElement.Class = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("image"))
                                    newElement.Image = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("adminUri"))
                                    newElement.AdminUri = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("helpUri"))
                                    newElement.HelpUri = ReaderXml.Value.Trim();

                                // add if the minimum requirements are met
                                if ((!String.IsNullOrEmpty(newElement.Type)) && (!String.IsNullOrEmpty(newElement.Class)))
                                    Config.UI.TemplateElements.Add_Element(newElement);

                                break;

                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_template_elements_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
                errorEncountered = true;
            }

            // If there was an error while reading, use the system defaults
            if (errorEncountered)
            {
                Config.Metadata.Clear();
                Config.Metadata.Set_Default_Values();
            }

            return !errorEncountered;
        }
        private static bool read_writer_viewer_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            bool errorEncountered = false;

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "clearall":
                                Config.UI.WriterViewers.Clear();
                                break;

                            case "itemwriter":
                                if (ReaderXml.MoveToAttribute("class"))
                                    Config.UI.WriterViewers.Items.Class = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("assembly"))
                                    Config.UI.WriterViewers.Items.Assembly = ReaderXml.Value.Trim();
                                ReaderXml.MoveToElement();
                                read_item_writer_viewer_configs(ReaderXml.ReadSubtree(), Config.UI.WriterViewers);
                                break;
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_writer_viewer_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
                errorEncountered = true;
            }

            // If there was an error while reading, use the system defaults
            if (errorEncountered)
            {
                Config.Metadata.Clear();
                Config.Metadata.Set_Default_Values();
            }

            return !errorEncountered;
        }
        private static void read_engine_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            // Ensure the config object exists
            if (Config.Engine == null)
                Config.Engine = new Engine_Server_Configuration();

            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "mapping":
                            read_microservices_details_mapping(ReaderXml.ReadSubtree(), Config.Engine, null );
                            break;

                        case "components":
                            read_microservices_details_components(ReaderXml.ReadSubtree(), Config.Engine );
                            break;

                        case "restrictionranges":
                            read_engine_details_restrictionranges(ReaderXml.ReadSubtree(), Config.Engine );
                            break;
                    }
                }
            }
        }
        /// <summary> Read the indicated configuration file for these default static resources </summary>
        private static void read_static_resource_details(XmlReader ReaderXml, InstanceWide_Configuration Config, string Base_URL)
        {
            // Get the configuration object
            StaticResources_Configuration config = Config.UI.StaticResources;

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "file":
                                string key = (ReaderXml.MoveToAttribute("key")) ? ReaderXml.Value.Trim() : null;
                                string source = (ReaderXml.MoveToAttribute("source")) ? ReaderXml.Value.Trim() : null;
                                if ((!String.IsNullOrEmpty(key)) && (!String.IsNullOrEmpty(source))) config.Add_File(key.ToLower(), source.Replace("[%BASEURL%]", Base_URL));
                                break;
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_static_resource_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
            }

            // Some override values for testing
            //config.Sobekcm_Css = "http://cdn.sobekdigital.com/css/sobekcm/4.10.0/sobekcm.css";
            //config.Sobekcm_Admin_Css = "http://cdn.sobekdigital.com/css/sobekcm-admin/4.10.0/sobekcm_admin.css";
            //config.Sobekcm_Admin_Js = "http://cdn.sobekdigital.com/js/sobekcm-admin/4.10.0/sobekcm_admin.js";
            //config.Sobekcm_Full_Js = "http://localhost:52468/default/js/sobekcm-full/4.10.1/sobekcm_full.js";
            //config.Sobekcm_Item_Css = "http://cdn.sobekdigital.com/css/sobekcm-item/4.10.0/sobekcm_item.css";
            //config.Sobekcm_Qc_Css = "http://cdn.sobekdigital.com/css/sobekcm-qc/4.10.0/sobekcm_qc.css";
            //config.Sobekcm_Metadata_Js = "http://cdn.sobekdigital.com/js/sobekcm-metadata/4.10.0/sobekcm_metadata.js";
            //config.Sobekcm_Metadata_Css = "http://cdn.sobekdigital.com/css/sobekcm-metadata/4.10.0/sobekcm_metadata.css";
        }
        private static void read_oai_details(XmlReader readerXml, InstanceWide_Configuration config)
        {
            bool baseSpecified = false;

            // Ensure the OAI-PMH object exists
            if (config.OAI_PMH == null)
                config.OAI_PMH = new OAI_PMH_Configuration();

            // Just step through the subtree of this
            while (readerXml.Read())
            {
                if (readerXml.NodeType == XmlNodeType.Element)
                {
                    switch (readerXml.Name.ToLower())
                    {
                        case "oai-pmh":
                            if (readerXml.Value.Trim().ToLower() == "false")
                                config.OAI_PMH.Enabled = false;
                            break;

                        case "repository":
                            if (readerXml.MoveToAttribute("IdentifierBase"))
                            {
                                baseSpecified = true;
                                config.OAI_PMH.Identifier_Base = readerXml.Value.Trim();
                            }
                            break;

                        case "identify":
                            read_oai_details_identify(readerXml.ReadSubtree(), config.OAI_PMH, baseSpecified);
                            break;

                        case "metadataprefixes":
                            read_oai_details_metadataPrefixes(readerXml.ReadSubtree(), config.OAI_PMH);
                            break;
                    }
                }
            }
        }
        private static void read_quality_control_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            // Ensure the config object exists
            if (Config.QualityControlTool == null)
                Config.QualityControlTool = new QualityControl_Configuration();

            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "profiles":
                            read_qc_profiles(ReaderXml.ReadSubtree(), Config.QualityControlTool);
                            break;
                    }
                }
            }
        }
        private static bool read_metadata_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            bool errorEncountered = false;

            // Ensure the config object exists
            if (Config.Metadata == null)
                Config.Metadata = new Metadata_Configuration();

            // Clear al the current (probably default) settings
            if ( Config.Metadata.isDefault )
                Config.Metadata.Clear();

            // Some collections to read into
            Dictionary<string, METS_Section_ReaderWriter_Config> readerWriters = new Dictionary<string, METS_Section_ReaderWriter_Config>();
            if ((Config.Metadata.METS_Section_File_ReaderWriter_Configs != null) && (Config.Metadata.METS_Section_File_ReaderWriter_Configs.Count > 0))
            {
                foreach (METS_Section_ReaderWriter_Config currentConfig in Config.Metadata.METS_Section_File_ReaderWriter_Configs)
                {
                    readerWriters[currentConfig.ID] = currentConfig;
                }
            }

            try
            {
                while (ReaderXml.Read())
                {
                    if (ReaderXml.NodeType == XmlNodeType.Element)
                    {
                        switch (ReaderXml.Name.ToLower())
                        {
                            case "clearall":
                                Config.Metadata.Clear();
                                break;

                            case "metadata_file_readerwriters":
                                read_metadata_file_readerwriter_configs(ReaderXml.ReadSubtree(), Config.Metadata);
                                break;

                            case "mets_sec_readerwriters":
                                read_mets_readerwriter_configs(ReaderXml.ReadSubtree(), readerWriters, Config.Metadata);
                                break;

                            case "mets_writing":
                                read_mets_writing_config(ReaderXml.ReadSubtree(), readerWriters, Config.Metadata);
                                break;

                            case "additional_metadata_modules":
                                read_metadata_modules_config(ReaderXml.ReadSubtree(), Config.Metadata);
                                break;

                            case "metadata_mappers":
                                read_metadata_mappers_config(ReaderXml.ReadSubtree(), Config.Metadata);
                                break;
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Config.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_metadata_details");
                Config.Source.Add_Log(ee.Message);
                Config.Source.Add_Log(ee.StackTrace);

                Config.Source.ErrorEncountered = true;
                errorEncountered = true;
            }

            // If there was an error while reading, use the system defaults
            if (errorEncountered)
            {
                Config.Metadata.Clear();
                Config.Metadata.Set_Default_Values();
            }

            return !errorEncountered;
        }
        private static void engine_config_finalize(InstanceWide_Configuration Configuration)
        {
            // If there was an error or nothing was read, do nothing
            if ((Configuration.Engine == null) || (Configuration.Engine.RootPaths == null) || (Configuration.Engine.RootPaths.Count == 0))
                return;

            // Build the dictionaries for all the components
            Dictionary<string, Engine_Component> components = new Dictionary<string, Engine_Component>(StringComparer.OrdinalIgnoreCase);
            foreach (Engine_Component thisComponent in Configuration.Engine.Components)
            {
                components[thisComponent.ID] = thisComponent;
            }

            // Ensure the current IP address for this server is added to any
            // restriction range.. should always be able to get to the range from the
            // local machine
            List<string> local_ips = get_local_ip_addresses();
            foreach (string localIp in local_ips)
            {
                foreach (Engine_RestrictionRange thisRange in Configuration.Engine.RestrictionRanges)
                {
                    thisRange.Add_IP_Range("Web server IP (added automatically)", localIp);
                }
            }

            // Build the dictionaries for all the restriction ranges
            Dictionary<string, Engine_RestrictionRange> restrictionRanges = new Dictionary<string, Engine_RestrictionRange>(StringComparer.OrdinalIgnoreCase);
            foreach (Engine_RestrictionRange thisRange in Configuration.Engine.RestrictionRanges)
            {
                restrictionRanges[thisRange.ID] = thisRange;
            }

            // Now, iterate through the tree of child pages
            foreach (Engine_Path_Endpoint pathEndpoint in Configuration.Engine.RootPaths)
            {
                engine_config_finalize_recurse_through_endpoints(pathEndpoint, components, restrictionRanges);
            }
        }
        private static void read_mapeditor_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            // Ensure the config object exists
            if ( Config.UI.MapEditor == null )
                Config.UI.MapEditor = new MapEditor_Configuration();

            while (ReaderXml.Read())
            {
                // Only detect start elements.
                if (ReaderXml.IsStartElement())
                {
                    // Get element name and switch on it.
                    switch (ReaderXml.Name)
                    {
                        case "collection":
                            string collectionName = ReaderXml["id"];
                            MapEditor_Configuration_Collection collection = new MapEditor_Configuration_Collection
                            {
                                Name = collectionName
                            };

                            while (ReaderXml.Read())
                            {
                                if (ReaderXml.NodeType == XmlNodeType.Whitespace) continue;

                                if (ReaderXml.Name == "collection")
                                {
                                    if (ReaderXml.NodeType == XmlNodeType.EndElement)
                                        break;
                                }

                                if (!ReaderXml.IsStartElement()) continue;

                                string key = ReaderXml.Name;
                                if (ReaderXml.Read())
                                {
                                    string value = String.IsNullOrEmpty(ReaderXml.Value) ? "\"\"" : ReaderXml.Value;
                                    collection.Settings.Add(new Simple_Setting(key, value, -1));
                                }
                            }
                            Config.UI.MapEditor.Collections.Add(collection);
                            break;
                    }
                }
            }
        }
        private static ExtensionInfo read_extension_details(XmlReader readerXml, InstanceWide_Configuration config, string SourceDirectoryName, string SourceDirectory )
        {
            // Create the new extension information object
            ExtensionInfo thisExtension = new ExtensionInfo
            {
                Code = SourceDirectoryName,
                Name = SourceDirectoryName,
                Version = "0.0"
            };

            // Read the attributes
            if (readerXml.MoveToAttribute("name"))
                thisExtension.Name = readerXml.Value.Trim();
            if (readerXml.MoveToAttribute("version"))
                thisExtension.Version = readerXml.Value.Trim();
            if (readerXml.MoveToAttribute("code"))
            {
                string code = readerXml.Value.Trim();
                if (String.Compare(SourceDirectoryName, code, StringComparison.OrdinalIgnoreCase) == 0)
                    thisExtension.Code = code;
                else
                {
                    thisExtension.Add_Error("WARNING: Code in the extension config ( " + code + " ) does not match directory name ( " + SourceDirectoryName + " )");
                    if (config != null)
                        config.Source.Add_Log("           WARNING: Code in the extension config ( " + code + " ) does not match directory name ( " + SourceDirectoryName + " )");
                }
            }

            // Check to see if a user with the HIGHEST rights is only that can disable ( i.e., the HOST ADMIN if hosted )
            if (readerXml.MoveToAttribute("canDisable"))
            {
                string whoDisable = readerXml.Value.Trim();
                if (String.Compare(whoDisable, "host", StringComparison.InvariantCultureIgnoreCase) == 0)
                    thisExtension.HighestRightsRequired = true;
            }

            // Just step through the subtree of this
            readerXml.MoveToElement();
            XmlReader childReader = readerXml.ReadSubtree();
            while (childReader.Read())
            {
                if (childReader.NodeType == XmlNodeType.Element)
                {
                    switch (childReader.Name.ToLower())
                    {
                        case "description":
                            childReader.Read();
                            string description = childReader.Value;
                            if (!String.IsNullOrWhiteSpace(description))
                            {
                                if (thisExtension.AdminInfo == null) thisExtension.AdminInfo = new ExtensionAdminInfo();
                                thisExtension.AdminInfo.Description = description;
                            }
                            break;

                        case "author":
                            if (readerXml.MoveToAttribute("name"))
                            {
                                string author_name = readerXml.Value.Trim();
                                string author_email = (readerXml.MoveToAttribute("email")) ? readerXml.Value.Trim() : String.Empty;
                                if (thisExtension.AdminInfo == null) thisExtension.AdminInfo = new ExtensionAdminInfo();
                                thisExtension.AdminInfo.Add_Author(author_name, author_email);
                            }
                            break;

                        case "permissions":
                            childReader.Read();
                            string permissions = childReader.Value;
                            if (!String.IsNullOrWhiteSpace(permissions))
                            {
                                if (thisExtension.AdminInfo == null) thisExtension.AdminInfo = new ExtensionAdminInfo();
                                thisExtension.AdminInfo.Permissions = permissions;
                            }
                            break;
                            break;

                        case "assembly":
                            if (childReader.MoveToAttribute("name"))
                            {
                                string assembly_name = childReader.Value.Trim();
                                string full_assembly_name = Path.Combine(SourceDirectory, assembly_name);

                                string id = String.Empty;
                                if (childReader.MoveToAttribute("id"))
                                    id = childReader.Value.Trim();

                                if (File.Exists(full_assembly_name))
                                {
                                    // Was there an ID?
                                    if (String.IsNullOrEmpty(id))
                                        id = Path.GetFileNameWithoutExtension(full_assembly_name);

                                    thisExtension.Add_Assembly(id, full_assembly_name);
                                }
                                else
                                {
                                    thisExtension.Add_Error("ERROR: Referenced assembly ( " + full_assembly_name + " ) does not exist");
                                    if (config != null)
                                        config.Source.Add_Log("           ERROR: Referenced assembly ( " + full_assembly_name + " ) does not exist");
                                }
                            }
                            break;

                        case "css":
                            string css_url = String.Empty;
                            string css_condition = String.Empty;
                            if (childReader.MoveToAttribute("url"))
                                css_url = childReader.Value.Trim();
                            if (childReader.MoveToAttribute("condition"))
                                css_condition = childReader.Value.Trim();
                            if ((!String.IsNullOrWhiteSpace(css_url)) && (!String.IsNullOrWhiteSpace(css_condition)))
                            {
                                ExtensionCssInfoConditionEnum condition = ExtensionCssInfoConditionEnum.ERROR;
                                switch (css_condition.ToLower())
                                {
                                    case "admin":
                                        condition = ExtensionCssInfoConditionEnum.Admin;
                                        break;

                                    case "aggregation":
                                        condition = ExtensionCssInfoConditionEnum.Aggregation;
                                        break;

                                    case "always":
                                        condition = ExtensionCssInfoConditionEnum.Always;
                                        break;

                                    case "item":
                                        condition = ExtensionCssInfoConditionEnum.Item;
                                        break;

                                    case "metadata":
                                        condition = ExtensionCssInfoConditionEnum.Metadata;
                                        break;

                                    case "mysobek":
                                        condition = ExtensionCssInfoConditionEnum.MySobek;
                                        break;

                                    case "results":
                                        condition = ExtensionCssInfoConditionEnum.Results;
                                        break;

                                }

                                if (condition != ExtensionCssInfoConditionEnum.ERROR)
                                    thisExtension.Add_CssFile(css_url, condition);
                            }
                            break;

                    }
                }
            }

            // Return the built extension information
            return thisExtension;
        }
        /// <summary> Refreshes the values from the database settings </summary>
        /// <returns> A fully built instance-wide setting object </returns>
        public static InstanceWide_Configuration Read_Config_Files(List<string> ConfigurationDirectories, InstanceWide_Settings Settings)
        {
            // Start to build the instance wide configuration
            InstanceWide_Configuration returnValue = new InstanceWide_Configuration();

            // Add an initial log, with the data
            returnValue.Source.Add_Log("Beginning to read configuration files (" + DateTime.Now.ToShortDateString() + ")");

            // Log the directories to look within
            returnValue.Source.Add_Log();
            returnValue.Source.Add_Log("Looking in the following directories for config/xml files");
            foreach (string configDir in ConfigurationDirectories)
            {
                returnValue.Source.Add_Log("     " + configDir.ToLower().Replace(Settings.Servers.Application_Server_Network.ToLower(), ""));
            }

            // Step through and get the configuration files to be read (in folder and alphabetical order)
            List<string> configFiles = new List<string>();
            SortedList<string, string> filesSorted = new SortedList<string, string>();
            foreach (string thisConfigDir in ConfigurationDirectories)
            {
                if (Directory.Exists(thisConfigDir))
                {
                    // Get the list of XML and CONFIG files, and read them in alphabetical order
                    string[] files = Tools.SobekCM_File_Utilities.GetFiles(thisConfigDir, "*.xml|*.config");
                    if (files.Length > 0)
                    {
                        // Get all the files and sort by name
                        filesSorted.Clear();
                        foreach (string thisFile in files)
                        {
                            string filename = Path.GetFileName(thisFile);
                            if (filename != null)
                            {
                                filesSorted.Add(filename, thisFile);
                            }
                        }

                        // Add the files to the complete list
                        configFiles.AddRange(filesSorted.Values);
                    }
                }
            }

            // Add the source list to the source
            foreach (string fileFound in configFiles)
            {
                returnValue.Source.Files.Add(fileFound.ToLower().Replace(Settings.Servers.Application_Server_Network.ToLower(), ""));
            }

            // Log this
            returnValue.Source.Add_Log();
            returnValue.Source.Add_Log("Found the following config files to attempt to read:");
            foreach (string configFile in configFiles)
            {
                returnValue.Source.Add_Log("     " + configFile.ToLower().Replace(Settings.Servers.Application_Server_Network.ToLower(), ""));
            }

            // With all the files to read collected and sorted, read each one
            foreach (string thisConfigFile in configFiles)
            {
                if (read_config_file(thisConfigFile, returnValue, Settings))
                    returnValue.HasData = true;
            }

            // Now, perform some final clean-up functions here now that all the files have been read
            engine_config_finalize(returnValue);

            // Copy over all the extension information
            if (returnValue.Extensions.Extensions != null)
            {
                foreach (ExtensionInfo thisExtension in returnValue.Extensions.Extensions)
                {
                    if ((thisExtension.Enabled) && (thisExtension.Assemblies != null))
                    {
                        foreach (ExtensionAssembly thisAssembly in thisExtension.Assemblies)
                        {
                            ResourceObjectSettings.Add_Assembly(thisAssembly.ID, thisAssembly.FilePath);
                        }
                    }
                }
            }

            // Finalize the metadata config
            returnValue.Metadata.Finalize_Metadata_Configuration();

            // Save the metadata configuration to the resource object library
            ResourceObjectSettings.MetadataConfig = returnValue.Metadata;

            returnValue.HasData = true;

            return returnValue;
        }
        private static bool read_config_file(string ConfigFile, InstanceWide_Configuration ConfigObj, InstanceWide_Settings Settings)
        {
            // If the file doesn't exist, that is strange.. but not an error per se
            if (!File.Exists(ConfigFile))
            {
                return true;
            }

            // Add to the log
            ConfigObj.Source.Add_Log();
            string directoryName = "Unknown";
            string directory = Path.GetDirectoryName(ConfigFile);
            try
            {
                string file = Path.GetFileName(ConfigFile);
                DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(ConfigFile));
                directoryName = dirInfo.Name;
                string directory2 = dirInfo.Parent.Name;

                ConfigObj.Source.Add_Log("Reading " + directory2 + "\\" + directoryName + "\\" + file);
            }
            catch
            {
                ConfigObj.Source.Add_Log("Reading " + ConfigFile + " (Error parsing for logging)");
            }

            // Streams used for reading
            Stream readerStream = null;
            XmlTextReader readerXml = null;

            try
            {
                // Check the file for the last modified date
                DateTime lastModifiedDate = (new FileInfo(ConfigFile)).LastWriteTime;
                if (DateTime.Compare(ConfigObj.Source.LatestDateTimeStamp, lastModifiedDate) < 0)
                    ConfigObj.Source.LatestDateTimeStamp = lastModifiedDate;

                // Open a link to the file
                readerStream = new FileStream(ConfigFile, FileMode.Open, FileAccess.Read);

                // Try to read the XML
                readerXml = new XmlTextReader(readerStream);

                // Step through this configuration file
                while (readerXml.Read())
                {
                    if (readerXml.NodeType == XmlNodeType.Element)
                    {
                        switch (readerXml.Name.ToLower())
                        {
                            case "authentication":
                                ConfigObj.Source.Add_Log("        Parsing AUTHENTICATION subtree");
                                read_authentication_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "oai-pmh":
                                ConfigObj.Source.Add_Log("        Parsing OAI-PMH subtree");
                                read_oai_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "contactform":
                                ConfigObj.Source.Add_Log("        Parsing CONTACTFORM subtree");
                                read_contactform_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "briefitem_mapping":
                                ConfigObj.Source.Add_Log("        Parsing BRIEFITEM_MAPPING subtree");
                                read_briefitem_mapping_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "mapeditor":
                                ConfigObj.Source.Add_Log("        Parsing MAPEDITOR subtree");
                                read_mapeditor_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "engine":
                                ConfigObj.Source.Add_Log("        Parsing ENGINE subtree");
                                if (readerXml.MoveToAttribute("ClearAll"))
                                {
                                    if ((readerXml.Value.Trim().ToLower() == "true") && ( ConfigObj.Engine != null ))
                                    {
                                        ConfigObj.Engine.ClearAll();
                                    }
                                    readerXml.MoveToElement();
                                }
                                read_engine_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "qualitycontrol":
                                ConfigObj.Source.Add_Log("        Parsing QUALITYCONTROL subtree");
                                read_quality_control_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "metadata":
                                ConfigObj.Source.Add_Log("        Parsing METADATA subtree");
                                read_metadata_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "writerviewers":
                                ConfigObj.Source.Add_Log("        Parsing WRITER/VIEWER subtree");
                                read_writer_viewer_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "citation":
                                ConfigObj.Source.Add_Log("        Parsing CITATION subtree");
                                read_citation_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "templateelements":
                            case "templateconfig":
                                ConfigObj.Source.Add_Log("        Parsing TEMPLATE ELEMENTS subtree");
                                read_template_elements_details(readerXml.ReadSubtree(), ConfigObj);
                                break;

                            case "extension":
                                // Ensure the extension configuration exists
                                if (ConfigObj.Extensions == null)
                                    ConfigObj.Extensions = new Extension_Configuration();

                                ConfigObj.Source.Add_Log("        Parsing EXTENSION subtree");
                                ExtensionInfo extensionInfo = read_extension_details(readerXml, ConfigObj, directoryName, directory);

                                // Since this was read here, it must be enabled, but determine enabled date
                                extensionInfo.Enabled = true;
                                ExtensionInfo dbInfo = Settings.ExtensionByCode(extensionInfo.Code);
                                if (dbInfo != null)
                                    extensionInfo.EnabledDate = dbInfo.EnabledDate;

                                // Add this to the list of extensions
                                ConfigObj.Extensions.Add_Extension(extensionInfo);
                                break;

                            case "static_resources":
                                string base_url = Settings.Servers.Base_URL;
                                bool read_section = false;
                                if (readerXml.MoveToAttribute("code"))
                                {
                                    string code = readerXml.Value;
                                    if ((code == "*") || (String.Compare(Settings.Servers.Static_Resources_Config_File, code, StringComparison.OrdinalIgnoreCase) == 0))
                                        read_section = true;
                                    readerXml.MoveToElement();

                                    // Savethe code though, if it wasn't an asterisk
                                    if (( code != "*") && ( !ConfigObj.UI.StaticResources.Static_Resource_Codes.Contains(code.ToLower())))
                                        ConfigObj.UI.StaticResources.Static_Resource_Codes.Add(code.ToLower());
                                }
                                if (readerXml.MoveToAttribute("baseUrl"))
                                {
                                    base_url = readerXml.Value;
                                    readerXml.MoveToElement();
                                }
                                if (read_section)
                                {
                                    ConfigObj.Source.Add_Log("        Parsing active STATIC RESOURCES subtree");
                                    read_static_resource_details(readerXml.ReadSubtree(), ConfigObj, base_url);
                                }
                                else
                                {
                                    ConfigObj.Source.Add_Log("        Skipping inactive STATIC RESOURCES subtree");
                                }
                                break;

                        }
                    }
                }
            }
            catch (Exception ee)
            {
                ConfigObj.Source.Add_Log("EXCEPTION CAUGHT in Configuration_Files_Reader.read_config_files");
                ConfigObj.Source.Add_Log(ee.Message);
                ConfigObj.Source.Add_Log(ee.StackTrace);

                ConfigObj.Source.ErrorEncountered = true;
            }
            finally
            {
                if (readerXml != null)
                {
                    readerXml.Close();
                }
                if (readerStream != null)
                {
                    readerStream.Close();
                }
            }

            return true;
        }
        private static void read_shibb_details(XmlReader ReaderXml, InstanceWide_Configuration Config)
        {
            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "mapping":
                            string serverVariable = null;
                            string userAttribute = null;
                            if (ReaderXml.MoveToAttribute("ServerVariable"))
                                serverVariable = ReaderXml.Value.Trim();
                            if (ReaderXml.MoveToAttribute("UserAttribute"))
                                userAttribute = ReaderXml.Value.Trim();
                            if ((!String.IsNullOrEmpty(serverVariable)) && (!String.IsNullOrEmpty(userAttribute)))
                            {
                                User_Object_Attribute_Mapping_Enum userAttrEnum = User_Object_Attribute_Mapping_Enum_Converter.ToEnum(userAttribute.ToUpper());
                                if (userAttrEnum != User_Object_Attribute_Mapping_Enum.NONE)
                                {
                                    Config.Authentication.Shibboleth.Add_Attribute_Mapping(serverVariable, userAttrEnum);
                                }
                            }
                            break;

                        case "constant":
                            string userAttribute2 = null;
                            string constantValue = null;
                            if (ReaderXml.MoveToAttribute("UserAttribute"))
                                userAttribute2 = ReaderXml.Value.Trim();
                            if (!ReaderXml.IsEmptyElement)
                            {
                                ReaderXml.Read();
                                constantValue = ReaderXml.Value.Trim();
                            }
                            if ((!String.IsNullOrEmpty(userAttribute2)) && (!String.IsNullOrEmpty(constantValue)))
                            {
                                User_Object_Attribute_Mapping_Enum userAttrEnum = User_Object_Attribute_Mapping_Enum_Converter.ToEnum(userAttribute2.ToUpper());
                                if (userAttrEnum != User_Object_Attribute_Mapping_Enum.NONE)
                                {
                                    Config.Authentication.Shibboleth.Add_Constant(userAttrEnum, constantValue);
                                }
                            }
                            break;

                        case "cansubmit":
                            string serverVariable2 = null;
                            string requiredValue = null;
                            if (ReaderXml.MoveToAttribute("ServerVariable"))
                                serverVariable2 = ReaderXml.Value.Trim();
                            if (ReaderXml.MoveToAttribute("Value"))
                                requiredValue = ReaderXml.Value.Trim();
                            if ((!String.IsNullOrEmpty(serverVariable2)) && (!String.IsNullOrEmpty(requiredValue)))
                            {
                                Config.Authentication.Shibboleth.Add_CanSubmit_Indicator(serverVariable2, requiredValue);
                            }
                            break;
                    }
                }
            }
        }
        /// <summary> Refresh the settings object by pulling the data back from the database </summary>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        public static bool RefreshConfiguration()
        {
            try
            {
                lock (configurationLock)
                {
                    if (configuration == null)
                        configuration = Configuration_Files_Reader.Read_Config_Files( Settings);
                    else
                    {
                        InstanceWide_Configuration newConfig = Configuration_Files_Reader.Read_Config_Files( Settings);
                        configuration = newConfig;
                    }
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
        private static void read_contactform_details(XmlReader readerXml, InstanceWide_Configuration config)
        {
            // Ensure the contact form configuration exists
            if (config.ContactForm == null)
                config.ContactForm = new ContactForm_Configuration();

            // Read the attributes
            if (readerXml.MoveToAttribute("Name"))
                config.ContactForm.Name = readerXml.Value.Trim();

            // Just step through the subtree of this
            while (readerXml.Read())
            {
                if (readerXml.NodeType == XmlNodeType.Element)
                {
                    switch (readerXml.Name.ToLower())
                    {
                        case "elements":
                            read_contactform_elements(readerXml.ReadSubtree(), config.ContactForm);
                            break;
                    }
                }
            }
        }