/// <summary> Constructor for a new instance of the InstanceWide_Configuration class </summary>
        public InstanceWide_Configuration()
        {
            // Create some of the configuration stuff
            Authentication = new Authentication_Configuration();
            BriefItemMapping = new BriefItemMapping_Configuration();
            ContactForm = new ContactForm_Configuration();
            Engine = new Engine_Server_Configuration();
            Extensions = new Extension_Configuration();
            QualityControlTool = new QualityControl_Configuration();
            Metadata = new Metadata_Configuration();
            OAI_PMH = new OAI_PMH_Configuration();
            UI = new InstanceWide_UI_Configuration();
            Source = new Configuration_Source_Info();

            // Set some defaults
            HasData = false;
        }
        private static void read_microservices_details_components(XmlReader ReaderXml, Engine_Server_Configuration Config )
        {
            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "component":
                            string Namespace = String.Empty;
                            Engine_Component component = new Engine_Component();
                            if (ReaderXml.MoveToAttribute("ID"))
                                component.ID = ReaderXml.Value.Trim();
                            if (ReaderXml.MoveToAttribute("Assembly"))
                                component.Assembly = ReaderXml.Value.Trim();
                            if (ReaderXml.MoveToAttribute("Namespace"))
                                Namespace = ReaderXml.Value.Trim() + ".";
                            if (ReaderXml.MoveToAttribute("Class"))
                                component.Class = Namespace + ReaderXml.Value.Trim();
                            if ((!String.IsNullOrEmpty(component.ID)) && (!String.IsNullOrEmpty(component.Class)))
                            {
                                // If the key already existed, remove the old one as it will be replaced
                                Config.Components.Add(component);

                            }
                            break;
                    }
                }
            }
        }
        private static void read_microservices_details_mapping(XmlReader ReaderXml, Engine_Server_Configuration Config, Engine_Path_Endpoint ParentSegment )
        {
            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "removeall":
                            if (ParentSegment != null)
                            {
                                if (ParentSegment.Children != null)
                                    ParentSegment.Children.Clear();
                            }
                            else
                            {
                                Config.RootPaths.Clear();
                            }
                            break;

                        case "path":
                            if (ReaderXml.MoveToAttribute("Segment"))
                            {
                                Engine_Path_Endpoint path;
                                string segment = ReaderXml.Value.Trim();

                                if (ParentSegment == null)
                                {
                                    if (Config.ContainsRootKey(segment.ToLower()))
                                        path = Config.GetRoot(segment.ToLower());
                                    else
                                    {
                                        path = new Engine_Path_Endpoint {Segment = segment};
                                        Config.AddRoot(segment.ToLower(), path);
                                    }
                                }
                                else
                                {
                                    if (ParentSegment.ContainsChildKey(segment.ToLower()))
                                    {
                                        path = ParentSegment.GetChild(segment.ToLower());
                                    }
                                    else
                                    {
                                        path = new Engine_Path_Endpoint { Segment = segment };
                                        ParentSegment.AddChild(path.Segment, path );
                                    }

                                }

                                ReaderXml.MoveToElement();
                                XmlReader subTreeReader = ReaderXml.ReadSubtree();
                                subTreeReader.Read();
                                read_microservices_details_mapping(subTreeReader, Config, path);
                            }
                            break;

                        case "complexendpoint":
                            // Read the top-endpoint information, before getting to each verb mapping
                            bool disabled_at_top = false;
                            Engine_Path_Endpoint endpoint = new Engine_Path_Endpoint { IsEndpoint = true };
                            if (ReaderXml.MoveToAttribute("Segment"))
                                endpoint.Segment = ReaderXml.Value.Trim();
                            if ((ReaderXml.MoveToAttribute("Enabled")) && (String.Compare(ReaderXml.Value.Trim(), "false", StringComparison.OrdinalIgnoreCase) == 0))
                                disabled_at_top = true;

                            // Now, read what remains
                            ReaderXml.MoveToElement();
                            XmlReader complexReader = ReaderXml.ReadSubtree();
                            complexReader.Read();
                            read_microservices_complex_endpoint_details(complexReader, endpoint, disabled_at_top);

                            // If a verb was mapped and there was a valid segment, add this
                            if ((!String.IsNullOrEmpty(endpoint.Segment)) && (endpoint.HasVerbMapping))
                            {
                                if (ParentSegment != null)
                                {
                                    // Add this endpoint
                                    ParentSegment.AddChild(endpoint.Segment, endpoint);
                                }
                            }
                            break;

                        case "endpoint":
                            read_microservices_simple_endpoint_details(ReaderXml, ParentSegment);
                            break;
                    }
                }
            }
        }
        private static void read_engine_details_restrictionranges(XmlReader ReaderXml, Engine_Server_Configuration Config )
        {
            Engine_RestrictionRange currentRange = null;

            while (ReaderXml.Read())
            {
                if (ReaderXml.NodeType == XmlNodeType.Element)
                {
                    switch (ReaderXml.Name.ToLower())
                    {
                        case "range":
                            string rangeId = null;
                            if (ReaderXml.MoveToAttribute("ID"))
                                rangeId = ReaderXml.Value.Trim();

                            // Must have an ID to be valid
                            if (!String.IsNullOrEmpty(rangeId))
                            {
                                currentRange = null;

                                // Look for a matching range
                                foreach (Engine_RestrictionRange range in Config.RestrictionRanges)
                                {
                                    if (range.ID == rangeId)
                                    {
                                        currentRange = range;
                                        break;
                                    }
                                }

                                // If no range, create the new one
                                if (currentRange == null)
                                {
                                    currentRange = new Engine_RestrictionRange { ID = rangeId };
                                }

                                if (ReaderXml.MoveToAttribute("Label"))
                                    currentRange.Label = ReaderXml.Value.Trim();
                            }
                            else
                            {
                                // Missing ID in this range
                                currentRange = null;
                            }
                            break;

                        case "removeall":
                            if (currentRange != null)
                                currentRange.IpRanges.Clear();
                            break;

                        case "iprange":
                            if (currentRange != null)
                            {
                                Engine_IpRange singleIpRange = new Engine_IpRange();
                                if (ReaderXml.MoveToAttribute("Label"))
                                    singleIpRange.Label = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("Start"))
                                    singleIpRange.StartIp = ReaderXml.Value.Trim();
                                if (ReaderXml.MoveToAttribute("End"))
                                    singleIpRange.EndIp = ReaderXml.Value.Trim();
                                if (singleIpRange.StartIp.Length > 0)
                                    currentRange.IpRanges.Add(singleIpRange);
                            }
                            break;
                    }

                }
                else if (ReaderXml.NodeType == XmlNodeType.EndElement)
                {
                    if (String.Compare(ReaderXml.Name, "range", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        if ((currentRange != null) && (!String.IsNullOrEmpty(currentRange.ID)))
                        {
                            if (!Config.RestrictionRanges.Contains(currentRange))
                                Config.RestrictionRanges.Add(currentRange);
                        }
                        currentRange = null;
                    }
                }
            }
        }