ConfigurationValues
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.CompilerServices;
namespace System.Configuration
{
    internal sealed class ConfigurationValues : NameObjectCollectionBase
    {
        private sealed class EmptyCollection : IEnumerable
        {
            private sealed class EmptyCollectionEnumerator : IEnumerator
            {
                object IEnumerator.Current {
                    get {
                        return null;
                    }
                }
                bool IEnumerator.MoveNext()
                {
                    return false;
                }
                void IEnumerator.Reset()
                {
                }
            }
            private readonly IEnumerator _emptyEnumerator;
            internal EmptyCollection()
            {
                _emptyEnumerator = new EmptyCollectionEnumerator();
            }
            IEnumerator IEnumerable.GetEnumerator()
            {
                return _emptyEnumerator;
            }
        }
        private sealed class ConfigurationElementsCollection : IEnumerable
        {
            private readonly ConfigurationValues _values;
            internal ConfigurationElementsCollection(ConfigurationValues values)
            {
                _values = values;
            }
            [IteratorStateMachine(typeof(<System-Collections-IEnumerable-GetEnumerator>d__2))]
            IEnumerator IEnumerable.GetEnumerator()
            {
                <System-Collections-IEnumerable-GetEnumerator>d__2 <System-Collections-IEnumerable-GetEnumerator>d__ = new <System-Collections-IEnumerable-GetEnumerator>d__2(0);
                <System-Collections-IEnumerable-GetEnumerator>d__.<>4__this = this;
                return <System-Collections-IEnumerable-GetEnumerator>d__;
            }
        }
        private sealed class InvalidValuesCollection : IEnumerable
        {
            private readonly ConfigurationValues _values;
            internal InvalidValuesCollection(ConfigurationValues values)
            {
                _values = values;
            }
            [IteratorStateMachine(typeof(<System-Collections-IEnumerable-GetEnumerator>d__2))]
            IEnumerator IEnumerable.GetEnumerator()
            {
                <System-Collections-IEnumerable-GetEnumerator>d__2 <System-Collections-IEnumerable-GetEnumerator>d__ = new <System-Collections-IEnumerable-GetEnumerator>d__2(0);
                <System-Collections-IEnumerable-GetEnumerator>d__.<>4__this = this;
                return <System-Collections-IEnumerable-GetEnumerator>d__;
            }
        }
        private static volatile IEnumerable s_emptyCollection;
        private BaseConfigurationRecord _configRecord;
        private volatile bool _containsElement;
        private volatile bool _containsInvalidValue;
        internal object this[string key] {
            get {
                return GetConfigValue(key)?.Value;
            }
            set {
                SetValue(key, value, ConfigurationValueFlags.Modified, null);
            }
        }
        internal object this[int index] {
            get {
                return GetConfigValue(index)?.Value;
            }
        }
        internal object SyncRoot => this;
        internal IEnumerable ConfigurationElements {
            get {
                if (!_containsElement)
                    return EmptyCollectionInstance;
                return new ConfigurationElementsCollection(this);
            }
        }
        internal IEnumerable InvalidValues {
            get {
                if (!_containsInvalidValue)
                    return EmptyCollectionInstance;
                return new InvalidValuesCollection(this);
            }
        }
        private static IEnumerable EmptyCollectionInstance => s_emptyCollection ?? (s_emptyCollection = new EmptyCollection());
        internal ConfigurationValues()
            : base(StringComparer.Ordinal)
        {
        }
        internal void AssociateContext(BaseConfigurationRecord configRecord)
        {
            _configRecord = configRecord;
            foreach (ConfigurationElement configurationElement in ConfigurationElements) {
                configurationElement.AssociateContext(_configRecord);
            }
        }
        internal bool Contains(string key)
        {
            return BaseGet(key) != null;
        }
        internal string GetKey(int index)
        {
            return BaseGetKey(index);
        }
        internal ConfigurationValue GetConfigValue(string key)
        {
            return (ConfigurationValue)BaseGet(key);
        }
        internal ConfigurationValue GetConfigValue(int index)
        {
            return (ConfigurationValue)BaseGet(index);
        }
        internal PropertySourceInfo GetSourceInfo(string key)
        {
            return GetConfigValue(key)?.SourceInfo;
        }
        internal void ChangeSourceInfo(string key, PropertySourceInfo sourceInfo)
        {
            ConfigurationValue configValue = GetConfigValue(key);
            if (configValue != null)
                configValue.SourceInfo = sourceInfo;
        }
        private ConfigurationValue CreateConfigValue(object value, ConfigurationValueFlags valueFlags, PropertySourceInfo sourceInfo)
        {
            if (value != null) {
                if (value is ConfigurationElement) {
                    _containsElement = true;
                    ((ConfigurationElement)value).AssociateContext(_configRecord);
                } else if (value is InvalidPropValue) {
                    _containsInvalidValue = true;
                }
            }
            return new ConfigurationValue(value, valueFlags, sourceInfo);
        }
        internal void SetValue(string key, object value, ConfigurationValueFlags valueFlags, PropertySourceInfo sourceInfo)
        {
            ConfigurationValue value2 = CreateConfigValue(value, valueFlags, sourceInfo);
            BaseSet(key, value2);
        }
        internal void Clear()
        {
            BaseClear();
        }
        internal ConfigurationValueFlags RetrieveFlags(string key)
        {
            return ((ConfigurationValue)BaseGet(key))?.ValueFlags ?? ConfigurationValueFlags.Default;
        }
        internal bool IsModified(string key)
        {
            ConfigurationValue configurationValue = (ConfigurationValue)BaseGet(key);
            if (configurationValue != null)
                return (configurationValue.ValueFlags & ConfigurationValueFlags.Modified) != ConfigurationValueFlags.Default;
            return false;
        }
        internal bool IsInherited(string key)
        {
            ConfigurationValue configurationValue = (ConfigurationValue)BaseGet(key);
            if (configurationValue != null)
                return (configurationValue.ValueFlags & ConfigurationValueFlags.Inherited) != ConfigurationValueFlags.Default;
            return false;
        }
    }
}