/// <summary> Add a new extension to this list of extensions </summary>
        /// <param name="NewExtension"> New extension to add </param>
        public void Add_Extension(ExtensionInfo NewExtension)
        {
            if (Extensions == null)
                Extensions = new List<ExtensionInfo>();

            Extensions.Add(NewExtension);
        }
        /// <summary> Takes a datatable from the database holding extension information
        /// and converts it into a list of <see cref="ExtensionInfo" /> objects. </summary>
        /// <param name="Source"> Source datatable from the database </param>
        /// <returns> Corresponding list of <see cref="ExtensionInfo" /> objects </returns>
        public static List<ExtensionInfo> DataTable_to_Extensions(DataTable Source)
        {
            List<ExtensionInfo> returnValue = new List<ExtensionInfo>();

            foreach (DataRow thisRow in Source.Rows)
            {
                ExtensionInfo newExtension = new ExtensionInfo
                {
                    Code = thisRow["Code"].ToString(),
                    Name = thisRow["Name"].ToString(),
                    Enabled = Boolean.Parse(thisRow["IsEnabled"].ToString()),
                    Version = thisRow["CurrentVersion"].ToString()
                };

                if (thisRow["EnabledDate"] != DBNull.Value)
                    newExtension.EnabledDate = DateTime.Parse(thisRow["EnabledDate"].ToString());

                returnValue.Add(newExtension);
            }

            return returnValue;
        }
        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;
        }