DictionaryWrapper<TKey, TValue>
                    class DictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IWrappedDictionary, IDictionary, ICollection
                
                using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Newtonsoft.Json.Utilities
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal class DictionaryWrapper<[System.Runtime.CompilerServices.Nullable(2)] TKey, [System.Runtime.CompilerServices.Nullable(2)] TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IWrappedDictionary, IDictionary, ICollection
    {
        [System.Runtime.CompilerServices.Nullable(0)]
        private readonly struct DictionaryEnumerator<[System.Runtime.CompilerServices.Nullable(2)] TEnumeratorKey, [System.Runtime.CompilerServices.Nullable(2)] TEnumeratorValue> : IDictionaryEnumerator, IEnumerator
        {
            [System.Runtime.CompilerServices.Nullable(new byte[] {
                1,
                0,
                1,
                1
            })]
            private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
            public DictionaryEntry Entry => (DictionaryEntry)Current;
            public object Key => Entry.Key;
            [System.Runtime.CompilerServices.Nullable(2)]
            public object Value {
                [System.Runtime.CompilerServices.NullableContext(2)]
                get {
                    return Entry.Value;
                }
            }
            public object Current {
                get {
                    KeyValuePair<TEnumeratorKey, TEnumeratorValue> current = _e.Current;
                    object key = current.Key;
                    current = _e.Current;
                    return new DictionaryEntry(key, current.Value);
                }
            }
            public DictionaryEnumerator([System.Runtime.CompilerServices.Nullable(new byte[] {
                1,
                0,
                1,
                1
            })] IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
            {
                ValidationUtils.ArgumentNotNull(e, "e");
                _e = e;
            }
            public bool MoveNext()
            {
                return _e.MoveNext();
            }
            public void Reset()
            {
                _e.Reset();
            }
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        private readonly IDictionary _dictionary;
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            2,
            1,
            1
        })]
        private readonly IDictionary<TKey, TValue> _genericDictionary;
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            2,
            1,
            1
        })]
        private readonly IReadOnlyDictionary<TKey, TValue> _readOnlyDictionary;
        [System.Runtime.CompilerServices.Nullable(2)]
        private object _syncRoot;
        internal IDictionary<TKey, TValue> GenericDictionary => _genericDictionary;
        public ICollection<TKey> Keys {
            get {
                if (_dictionary != null)
                    return Enumerable.ToList<TKey>(Enumerable.Cast<TKey>((IEnumerable)_dictionary.Keys));
                if (_readOnlyDictionary != null)
                    return Enumerable.ToList<TKey>(_readOnlyDictionary.Keys);
                return GenericDictionary.Keys;
            }
        }
        public ICollection<TValue> Values {
            get {
                if (_dictionary != null)
                    return Enumerable.ToList<TValue>(Enumerable.Cast<TValue>((IEnumerable)_dictionary.Values));
                if (_readOnlyDictionary != null)
                    return Enumerable.ToList<TValue>(_readOnlyDictionary.Values);
                return GenericDictionary.Values;
            }
        }
        public TValue this[TKey key] {
            get {
                if (_dictionary != null)
                    return (TValue)_dictionary[key];
                if (_readOnlyDictionary != null)
                    return _readOnlyDictionary[key];
                return GenericDictionary[key];
            }
            set {
                if (_dictionary != null)
                    _dictionary[key] = value;
                else {
                    if (_readOnlyDictionary != null)
                        throw new NotSupportedException();
                    GenericDictionary[key] = value;
                }
            }
        }
        public int Count {
            get {
                if (_dictionary != null)
                    return _dictionary.Count;
                if (_readOnlyDictionary != null)
                    return _readOnlyDictionary.Count;
                return GenericDictionary.Count;
            }
        }
        public bool IsReadOnly {
            get {
                if (_dictionary != null)
                    return _dictionary.IsReadOnly;
                if (_readOnlyDictionary != null)
                    return true;
                return GenericDictionary.IsReadOnly;
            }
        }
        [System.Runtime.CompilerServices.Nullable(2)]
        object IDictionary.this[object key] {
            [return: System.Runtime.CompilerServices.Nullable(2)]
            get {
                if (_dictionary != null)
                    return _dictionary[key];
                if (_readOnlyDictionary != null)
                    return _readOnlyDictionary[(TKey)key];
                return GenericDictionary[(TKey)key];
            }
            [param: System.Runtime.CompilerServices.Nullable(2)]
            set {
                if (_dictionary != null)
                    _dictionary[key] = value;
                else {
                    if (_readOnlyDictionary != null)
                        throw new NotSupportedException();
                    GenericDictionary[(TKey)key] = (TValue)value;
                }
            }
        }
        bool IDictionary.IsFixedSize {
            get {
                if (_genericDictionary != null)
                    return false;
                if (_readOnlyDictionary != null)
                    return true;
                return _dictionary.IsFixedSize;
            }
        }
        ICollection IDictionary.Keys {
            get {
                if (_genericDictionary != null)
                    return Enumerable.ToList<TKey>((IEnumerable<TKey>)_genericDictionary.Keys);
                if (_readOnlyDictionary != null)
                    return Enumerable.ToList<TKey>(_readOnlyDictionary.Keys);
                return _dictionary.Keys;
            }
        }
        ICollection IDictionary.Values {
            get {
                if (_genericDictionary != null)
                    return Enumerable.ToList<TValue>((IEnumerable<TValue>)_genericDictionary.Values);
                if (_readOnlyDictionary != null)
                    return Enumerable.ToList<TValue>(_readOnlyDictionary.Values);
                return _dictionary.Values;
            }
        }
        bool ICollection.IsSynchronized {
            get {
                if (_dictionary != null)
                    return _dictionary.IsSynchronized;
                return false;
            }
        }
        object ICollection.SyncRoot {
            get {
                if (_syncRoot == null)
                    Interlocked.CompareExchange(ref _syncRoot, new object(), null);
                return _syncRoot;
            }
        }
        public object UnderlyingDictionary {
            get {
                if (_dictionary != null)
                    return _dictionary;
                if (_readOnlyDictionary != null)
                    return _readOnlyDictionary;
                return GenericDictionary;
            }
        }
        public DictionaryWrapper(IDictionary dictionary)
        {
            ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
            _dictionary = dictionary;
        }
        public DictionaryWrapper(IDictionary<TKey, TValue> dictionary)
        {
            ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
            _genericDictionary = dictionary;
        }
        public DictionaryWrapper(IReadOnlyDictionary<TKey, TValue> dictionary)
        {
            ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
            _readOnlyDictionary = dictionary;
        }
        public void Add(TKey key, TValue value)
        {
            if (_dictionary != null)
                _dictionary.Add(key, value);
            else {
                if (_genericDictionary == null)
                    throw new NotSupportedException();
                _genericDictionary.Add(key, value);
            }
        }
        public bool ContainsKey(TKey key)
        {
            if (_dictionary != null)
                return _dictionary.Contains(key);
            if (_readOnlyDictionary != null)
                return _readOnlyDictionary.ContainsKey(key);
            return GenericDictionary.ContainsKey(key);
        }
        public bool Remove(TKey key)
        {
            if (_dictionary != null) {
                if (_dictionary.Contains(key)) {
                    _dictionary.Remove(key);
                    return true;
                }
                return false;
            }
            if (_readOnlyDictionary != null)
                throw new NotSupportedException();
            return GenericDictionary.Remove(key);
        }
        public bool TryGetValue(TKey key, [System.Runtime.CompilerServices.Nullable(2)] out TValue value)
        {
            if (_dictionary != null) {
                if (!_dictionary.Contains(key)) {
                    value = default(TValue);
                    return false;
                }
                value = (TValue)_dictionary[key];
                return true;
            }
            if (_readOnlyDictionary != null)
                throw new NotSupportedException();
            return GenericDictionary.TryGetValue(key, out value);
        }
        public void Add([System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1
        })] KeyValuePair<TKey, TValue> item)
        {
            if (_dictionary != null)
                ((IList)_dictionary).Add(item);
            else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                _genericDictionary?.Add(item);
            }
        }
        public void Clear()
        {
            if (_dictionary != null)
                _dictionary.Clear();
            else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                GenericDictionary.Clear();
            }
        }
        public bool Contains([System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1
        })] KeyValuePair<TKey, TValue> item)
        {
            if (_dictionary != null)
                return ((IList)_dictionary).Contains(item);
            if (_readOnlyDictionary != null)
                return Enumerable.Contains<KeyValuePair<TKey, TValue>>((IEnumerable<KeyValuePair<TKey, TValue>>)_readOnlyDictionary, item);
            return GenericDictionary.Contains(item);
        }
        public void CopyTo([System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            0,
            1,
            1
        })] KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            if (_dictionary != null) {
                IDictionaryEnumerator enumerator = _dictionary.GetEnumerator();
                try {
                    while (enumerator.MoveNext()) {
                        DictionaryEntry entry = enumerator.Entry;
                        array[arrayIndex++] = new KeyValuePair<TKey, TValue>((TKey)entry.Key, (TValue)entry.Value);
                    }
                } finally {
                    (enumerator as IDisposable)?.Dispose();
                }
            } else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                GenericDictionary.CopyTo(array, arrayIndex);
            }
        }
        public bool Remove([System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1
        })] KeyValuePair<TKey, TValue> item)
        {
            if (_dictionary != null) {
                if (_dictionary.Contains(item.Key)) {
                    if (object.Equals(_dictionary[item.Key], item.Value)) {
                        _dictionary.Remove(item.Key);
                        return true;
                    }
                    return false;
                }
                return true;
            }
            if (_readOnlyDictionary != null)
                throw new NotSupportedException();
            return GenericDictionary.Remove(item);
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            0,
            1,
            1
        })]
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            if (_dictionary != null)
                return Enumerable.Select<DictionaryEntry, KeyValuePair<TKey, TValue>>(Enumerable.Cast<DictionaryEntry>((IEnumerable)_dictionary), (Func<DictionaryEntry, KeyValuePair<TKey, TValue>>)((DictionaryEntry de) => new KeyValuePair<TKey, TValue>((TKey)de.Key, (TValue)de.Value))).GetEnumerator();
            if (_readOnlyDictionary != null)
                return _readOnlyDictionary.GetEnumerator();
            return GenericDictionary.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        void IDictionary.Add(object key, [System.Runtime.CompilerServices.Nullable(2)] object value)
        {
            if (_dictionary != null)
                _dictionary.Add(key, value);
            else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                GenericDictionary.Add((TKey)key, (TValue)value);
            }
        }
        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            if (_dictionary != null)
                return _dictionary.GetEnumerator();
            if (_readOnlyDictionary != null)
                return new DictionaryEnumerator<TKey, TValue>(_readOnlyDictionary.GetEnumerator());
            return new DictionaryEnumerator<TKey, TValue>(GenericDictionary.GetEnumerator());
        }
        bool IDictionary.Contains(object key)
        {
            if (_genericDictionary != null)
                return _genericDictionary.ContainsKey((TKey)key);
            if (_readOnlyDictionary != null)
                return _readOnlyDictionary.ContainsKey((TKey)key);
            return _dictionary.Contains(key);
        }
        public void Remove(object key)
        {
            if (_dictionary != null)
                _dictionary.Remove(key);
            else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                GenericDictionary.Remove((TKey)key);
            }
        }
        void ICollection.CopyTo(Array array, int index)
        {
            if (_dictionary != null)
                _dictionary.CopyTo(array, index);
            else {
                if (_readOnlyDictionary != null)
                    throw new NotSupportedException();
                GenericDictionary.CopyTo((KeyValuePair<TKey, TValue>[])array, index);
            }
        }
    }
}