ClientSettingsStore
using System.Collections;
using System.Configuration.Internal;
using System.IO;
namespace System.Configuration
{
    internal sealed class ClientSettingsStore
    {
        private sealed class ClientSettingsConfigurationHost : DelegatingConfigHost
        {
            private const string ClientConfigurationHostTypeName = "System.Configuration.ClientConfigurationHost, System.Configuration.ConfigurationManager";
            private const string InternalConfigConfigurationFactoryTypeName = "System.Configuration.Internal.InternalConfigConfigurationFactory, System.Configuration.ConfigurationManager";
            private static volatile IInternalConfigConfigurationFactory s_configFactory;
            private IInternalConfigClientHost ClientHost => (IInternalConfigClientHost)base.Host;
            internal static IInternalConfigConfigurationFactory ConfigFactory => s_configFactory ?? (s_configFactory = TypeUtil.CreateInstance<IInternalConfigConfigurationFactory>("System.Configuration.Internal.InternalConfigConfigurationFactory, System.Configuration.ConfigurationManager"));
            private ClientSettingsConfigurationHost()
            {
            }
            public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams)
            {
            }
            public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot configRoot, params object[] hostInitConfigurationParams)
            {
                ConfigurationUserLevel configurationUserLevel = (ConfigurationUserLevel)hostInitConfigurationParams[0];
                base.Host = TypeUtil.CreateInstance<IInternalConfigHost>("System.Configuration.ClientConfigurationHost, System.Configuration.ConfigurationManager");
                string text;
                switch (configurationUserLevel) {
                case ConfigurationUserLevel.None:
                    text = ClientHost.GetExeConfigPath();
                    break;
                case ConfigurationUserLevel.PerUserRoaming:
                    text = ClientHost.GetRoamingUserConfigPath();
                    break;
                case ConfigurationUserLevel.PerUserRoamingAndLocal:
                    text = ClientHost.GetLocalUserConfigPath();
                    break;
                default:
                    throw new ArgumentException(System.SR.UnknownUserLevel);
                }
                string text2 = text;
                base.Host.InitForConfiguration(ref locationSubPath, out configPath, out locationConfigPath, configRoot, null, null, text2);
            }
            private static bool IsKnownConfigFile(string filename)
            {
                if (!string.Equals(filename, ConfigurationManagerInternalFactory.Instance.MachineConfigPath, StringComparison.OrdinalIgnoreCase) && !string.Equals(filename, ConfigurationManagerInternalFactory.Instance.ApplicationConfigUri, StringComparison.OrdinalIgnoreCase) && !string.Equals(filename, ConfigurationManagerInternalFactory.Instance.ExeLocalConfigPath, StringComparison.OrdinalIgnoreCase))
                    return string.Equals(filename, ConfigurationManagerInternalFactory.Instance.ExeRoamingConfigPath, StringComparison.OrdinalIgnoreCase);
                return true;
            }
            internal static Configuration OpenExeConfiguration(ConfigurationUserLevel userLevel)
            {
                return ConfigFactory.Create(typeof(ClientSettingsConfigurationHost), userLevel);
            }
            public override Stream OpenStreamForRead(string streamName)
            {
                if (IsKnownConfigFile(streamName))
                    return base.Host.OpenStreamForRead(streamName, true);
                return base.Host.OpenStreamForRead(streamName);
            }
            public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext)
            {
                return base.Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext);
            }
            public override void WriteCompleted(string streamName, bool success, object writeContext)
            {
                if (string.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeLocalConfigPath, StringComparison.OrdinalIgnoreCase) || string.Equals(streamName, ConfigurationManagerInternalFactory.Instance.ExeRoamingConfigPath, StringComparison.OrdinalIgnoreCase))
                    base.Host.WriteCompleted(streamName, success, writeContext, true);
                else
                    base.Host.WriteCompleted(streamName, success, writeContext);
            }
        }
        private const string ApplicationSettingsGroupName = "applicationSettings";
        private const string UserSettingsGroupName = "userSettings";
        private const string ApplicationSettingsGroupPrefix = "applicationSettings/";
        private const string UserSettingsGroupPrefix = "userSettings/";
        private static Configuration GetUserConfig(bool isRoaming)
        {
            return ClientSettingsConfigurationHost.OpenExeConfiguration(isRoaming ? ConfigurationUserLevel.PerUserRoaming : ConfigurationUserLevel.PerUserRoamingAndLocal);
        }
        private static ClientSettingsSection GetConfigSection(Configuration config, string sectionName, bool declare)
        {
            string sectionName2 = "userSettings/" + sectionName;
            ClientSettingsSection clientSettingsSection = null;
            if (config != null) {
                clientSettingsSection = (config.GetSection(sectionName2) as ClientSettingsSection);
                if ((clientSettingsSection == null) & declare) {
                    DeclareSection(config, sectionName);
                    clientSettingsSection = (config.GetSection(sectionName2) as ClientSettingsSection);
                }
            }
            return clientSettingsSection;
        }
        private static void DeclareSection(Configuration config, string sectionName)
        {
            ConfigurationSectionGroup sectionGroup = config.GetSectionGroup("userSettings");
            if (sectionGroup == null) {
                ConfigurationSectionGroup sectionGroup2 = new UserSettingsGroup();
                config.SectionGroups.Add("userSettings", sectionGroup2);
            }
            sectionGroup = config.GetSectionGroup("userSettings");
            if (sectionGroup != null) {
                ConfigurationSection configurationSection = sectionGroup.Sections[sectionName];
                if (configurationSection == null) {
                    configurationSection = new ClientSettingsSection();
                    configurationSection.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
                    configurationSection.SectionInformation.RequirePermission = false;
                    sectionGroup.Sections.Add(sectionName, configurationSection);
                }
            }
        }
        internal static IDictionary ReadSettings(string sectionName, bool isUserScoped)
        {
            Hashtable hashtable = new Hashtable();
            if (isUserScoped && !ConfigurationManagerInternalFactory.Instance.SupportsUserConfig)
                return hashtable;
            string str = isUserScoped ? "userSettings/" : "applicationSettings/";
            ConfigurationManager.RefreshSection(str + sectionName);
            ClientSettingsSection clientSettingsSection = ConfigurationManager.GetSection(str + sectionName) as ClientSettingsSection;
            if (clientSettingsSection != null) {
                foreach (SettingElement setting in clientSettingsSection.Settings) {
                    hashtable[setting.Name] = new StoredSetting(setting.SerializeAs, setting.Value.ValueXml);
                }
                return hashtable;
            }
            return hashtable;
        }
        internal static IDictionary ReadSettingsFromFile(string configFileName, string sectionName, bool isUserScoped)
        {
            Hashtable hashtable = new Hashtable();
            if (isUserScoped && !ConfigurationManagerInternalFactory.Instance.SupportsUserConfig)
                return hashtable;
            string str = isUserScoped ? "userSettings/" : "applicationSettings/";
            ExeConfigurationFileMap exeConfigurationFileMap = new ExeConfigurationFileMap();
            ConfigurationUserLevel userLevel = isUserScoped ? ConfigurationUserLevel.PerUserRoaming : ConfigurationUserLevel.None;
            if (isUserScoped) {
                exeConfigurationFileMap.ExeConfigFilename = ConfigurationManagerInternalFactory.Instance.ApplicationConfigUri;
                exeConfigurationFileMap.RoamingUserConfigFilename = configFileName;
            } else
                exeConfigurationFileMap.ExeConfigFilename = configFileName;
            ClientSettingsSection clientSettingsSection = ConfigurationManager.OpenMappedExeConfiguration(exeConfigurationFileMap, userLevel).GetSection(str + sectionName) as ClientSettingsSection;
            if (clientSettingsSection != null) {
                foreach (SettingElement setting in clientSettingsSection.Settings) {
                    hashtable[setting.Name] = new StoredSetting(setting.SerializeAs, setting.Value.ValueXml);
                }
                return hashtable;
            }
            return hashtable;
        }
        internal static ConnectionStringSettingsCollection ReadConnectionStrings()
        {
            return PrivilegedConfigurationManager.ConnectionStrings;
        }
        internal static void RevertToParent(string sectionName, bool isRoaming)
        {
            if (!ConfigurationManagerInternalFactory.Instance.SupportsUserConfig)
                throw new ConfigurationErrorsException(System.SR.UserSettingsNotSupported);
            Configuration userConfig = GetUserConfig(isRoaming);
            ClientSettingsSection configSection = GetConfigSection(userConfig, sectionName, false);
            if (configSection != null) {
                configSection.SectionInformation.RevertToParent();
                userConfig.Save();
            }
        }
        internal static void WriteSettings(string sectionName, bool isRoaming, IDictionary newSettings)
        {
            if (!ConfigurationManagerInternalFactory.Instance.SupportsUserConfig)
                throw new ConfigurationErrorsException(System.SR.UserSettingsNotSupported);
            Configuration userConfig = GetUserConfig(isRoaming);
            ClientSettingsSection configSection = GetConfigSection(userConfig, sectionName, true);
            if (configSection == null)
                throw new ConfigurationErrorsException(System.SR.SettingsSaveFailedNoSection);
            SettingElementCollection settings = configSection.Settings;
            IDictionaryEnumerator enumerator = newSettings.GetEnumerator();
            try {
                while (enumerator.MoveNext()) {
                    DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current;
                    SettingElement settingElement = settings.Get((string)dictionaryEntry.Key);
                    if (settingElement == null) {
                        settingElement = new SettingElement();
                        settingElement.Name = (string)dictionaryEntry.Key;
                        settings.Add(settingElement);
                    }
                    StoredSetting storedSetting = (StoredSetting)dictionaryEntry.Value;
                    settingElement.SerializeAs = storedSetting.SerializeAs;
                    settingElement.Value.ValueXml = storedSetting.Value;
                }
            } finally {
                (enumerator as IDisposable)?.Dispose();
            }
            try {
                userConfig.Save();
            } catch (ConfigurationErrorsException ex) {
                throw new ConfigurationErrorsException(System.SR.Format(System.SR.SettingsSaveFailed, ex.Message), ex);
            }
        }
    }
}