少年修仙传客户端基础资源
lwb
2020-11-11 ba24a4a15c0317ac2fd954f4173b4b79cbdf191e
Assets/Plugins/PocoSDK/ConcurrentDictionary.cs
@@ -11,1669 +11,1825 @@
namespace TcpServer
{
   /// <summary>
   /// Represents a thread-safe collection of keys and values.
   /// </summary>
   /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
   /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
   /// <remarks>
   /// All public and protected members of <see cref="ConcurrentDictionary{TKey,TValue}"/> are thread-safe and may be used
   /// concurrently from multiple threads.
   /// </remarks>
   [Serializable]
   [ComVisible (false)]
   [DebuggerDisplay ("Count = {Count}")]
   //    [HostProtection(Synchronization = true, ExternalThreading = true)]
    /// <summary>
    /// Represents a thread-safe collection of keys and values.
    /// </summary>
    /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
    /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
    /// <remarks>
    /// All public and protected members of <see cref="ConcurrentDictionary{TKey,TValue}"/> are thread-safe and may be used
    /// concurrently from multiple threads.
    /// </remarks>
    [Serializable]
    [ComVisible(false)]
    [DebuggerDisplay("Count = {Count}")]
    //    [HostProtection(Synchronization = true, ExternalThreading = true)]
    public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
   {
      [NonSerialized]
      private volatile Node[] m_buckets;
      // A singly-linked list for each bucket.
      [NonSerialized]
      private object[] m_locks;
      // A set of locks, each guarding a section of the table.
      [NonSerialized]
      private volatile int[] m_countPerLock;
      // The number of elements guarded by each lock.
      private IEqualityComparer<TKey> m_comparer;
      // Key equality comparer
    {
        [NonSerialized]
        private volatile Node[] m_buckets;
        // A singly-linked list for each bucket.
        [NonSerialized]
        private object[] m_locks;
        // A set of locks, each guarding a section of the table.
        [NonSerialized]
        private volatile int[] m_countPerLock;
        // The number of elements guarded by each lock.
        private IEqualityComparer<TKey> m_comparer;
        // Key equality comparer
      private KeyValuePair<TKey, TValue>[] m_serializationArray;
      // Used for custom serialization
        private KeyValuePair<TKey, TValue>[] m_serializationArray;
        // Used for custom serialization
      private int m_serializationConcurrencyLevel;
      // used to save the concurrency level in serialization
        private int m_serializationConcurrencyLevel;
        // used to save the concurrency level in serialization
      private int m_serializationCapacity;
      // used to save the capacity in serialization
        private int m_serializationCapacity;
        // used to save the capacity in serialization
      // The default concurrency level is DEFAULT_CONCURRENCY_MULTIPLIER * #CPUs. The higher the
      // DEFAULT_CONCURRENCY_MULTIPLIER, the more concurrent writes can take place without interference
      // and blocking, but also the more expensive operations that require all locks become (e.g. table
      // resizing, ToArray, Count, etc). According to brief benchmarks that we ran, 4 seems like a good
      // compromise.
      private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4;
        // The default concurrency level is DEFAULT_CONCURRENCY_MULTIPLIER * #CPUs. The higher the
        // DEFAULT_CONCURRENCY_MULTIPLIER, the more concurrent writes can take place without interference
        // and blocking, but also the more expensive operations that require all locks become (e.g. table
        // resizing, ToArray, Count, etc). According to brief benchmarks that we ran, 4 seems like a good
        // compromise.
        private const int DEFAULT_CONCURRENCY_MULTIPLIER = 4;
      // The default capacity, i.e. the initial # of buckets. When choosing this value, we are making
      // a trade-off between the size of a very small dictionary, and the number of resizes when
      // constructing a large dictionary. Also, the capacity should not be divisible by a small prime.
      private const int DEFAULT_CAPACITY = 31;
        // The default capacity, i.e. the initial # of buckets. When choosing this value, we are making
        // a trade-off between the size of a very small dictionary, and the number of resizes when
        // constructing a large dictionary. Also, the capacity should not be divisible by a small prime.
        private const int DEFAULT_CAPACITY = 31;
      /// <summary>
      /// Initializes a new instance of the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that is empty, has the default concurrency level, has the default initial capacity, and
      /// uses the default comparer for the key type.
      /// </summary>
      public ConcurrentDictionary () : this (DefaultConcurrencyLevel, DEFAULT_CAPACITY)
      {
      }
        /// <summary>
        /// Initializes a new instance of the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that is empty, has the default concurrency level, has the default initial capacity, and
        /// uses the default comparer for the key type.
        /// </summary>
        public ConcurrentDictionary() : this(DefaultConcurrencyLevel, DEFAULT_CAPACITY)
        {
        }
      /// <summary>
      /// Initializes a new instance of the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that is empty, has the specified concurrency level and capacity, and uses the default
      /// comparer for the key type.
      /// </summary>
      /// <param name="concurrencyLevel">The estimated number of threads that will update the
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
      /// <param name="capacity">The initial number of elements that the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>
      /// can contain.</param>
      /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="concurrencyLevel"/> is
      /// less than 1.</exception>
      /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="capacity"/> is less than
      /// 0.</exception>
      public ConcurrentDictionary (int concurrencyLevel, int capacity) : this (concurrencyLevel, capacity, EqualityComparer<TKey>.Default)
      {
      }
        /// <summary>
        /// Initializes a new instance of the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that is empty, has the specified concurrency level and capacity, and uses the default
        /// comparer for the key type.
        /// </summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
        /// <param name="capacity">The initial number of elements that the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>
        /// can contain.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="concurrencyLevel"/> is
        /// less than 1.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="capacity"/> is less than
        /// 0.</exception>
        public ConcurrentDictionary(int concurrencyLevel, int capacity) : this(concurrencyLevel, capacity, EqualityComparer<TKey>.Default)
        {
        }
      /// <summary>
      /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that contains elements copied from the specified <see
      /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/>, has the default concurrency
      /// level, has the default initial capacity, and uses the default comparer for the key type.
      /// </summary>
      /// <param name="collection">The <see
      /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to
      /// the new
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentException"><paramref name="collection"/> contains one or more
      /// duplicate keys.</exception>
      public ConcurrentDictionary (IEnumerable<KeyValuePair<TKey, TValue>> collection) : this (collection, EqualityComparer<TKey>.Default)
      {
      }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that contains elements copied from the specified <see
        /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/>, has the default concurrency
        /// level, has the default initial capacity, and uses the default comparer for the key type.
        /// </summary>
        /// <param name="collection">The <see
        /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to
        /// the new
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="collection"/> contains one or more
        /// duplicate keys.</exception>
        public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) : this(collection, EqualityComparer<TKey>.Default)
        {
        }
      /// <summary>
      /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that is empty, has the specified concurrency level and capacity, and uses the specified
      /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
      /// </summary>
      /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
      /// implementation to use when comparing keys.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      public ConcurrentDictionary (IEqualityComparer<TKey> comparer) : this (DefaultConcurrencyLevel, DEFAULT_CAPACITY, comparer)
      {
      }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that is empty, has the specified concurrency level and capacity, and uses the specified
        /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
        /// </summary>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
        /// implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        public ConcurrentDictionary(IEqualityComparer<TKey> comparer) : this(DefaultConcurrencyLevel, DEFAULT_CAPACITY, comparer)
        {
        }
      /// <summary>
      /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that contains elements copied from the specified <see
      /// cref="T:System.Collections.IEnumerable"/>, has the default concurrency level, has the default
      /// initial capacity, and uses the specified
      /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
      /// </summary>
      /// <param name="collection">The <see
      /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to
      /// the new
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
      /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
      /// implementation to use when comparing keys.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference
      /// (Nothing in Visual Basic). -or-
      /// <paramref name="comparer"/> is a null reference (Nothing in Visual Basic).
      /// </exception>
      public ConcurrentDictionary (IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
         : this (DefaultConcurrencyLevel, collection, comparer)
      {
      }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that contains elements copied from the specified <see
        /// cref="T:System.Collections.IEnumerable"/>, has the default concurrency level, has the default
        /// initial capacity, and uses the specified
        /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
        /// </summary>
        /// <param name="collection">The <see
        /// cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to
        /// the new
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
        /// implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is a null reference
        /// (Nothing in Visual Basic). -or-
        /// <paramref name="comparer"/> is a null reference (Nothing in Visual Basic).
        /// </exception>
        public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
            : this(DefaultConcurrencyLevel, collection, comparer)
        {
        }
      /// <summary>
      /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable"/>,
      /// has the specified concurrency level, has the specified initial capacity, and uses the specified
      /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
      /// </summary>
      /// <param name="concurrencyLevel">The estimated number of threads that will update the
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
      /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to the new
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
      /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/> implementation to use
      /// when comparing keys.</param>
      /// <exception cref="T:System.ArgumentNullException">
      /// <paramref name="collection"/> is a null reference (Nothing in Visual Basic).
      /// -or-
      /// <paramref name="comparer"/> is a null reference (Nothing in Visual Basic).
      /// </exception>
      /// <exception cref="T:System.ArgumentOutOfRangeException">
      /// <paramref name="concurrencyLevel"/> is less than 1.
      /// </exception>
      /// <exception cref="T:System.ArgumentException"><paramref name="collection"/> contains one or more duplicate keys.</exception>
      public ConcurrentDictionary (
         int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
         : this (concurrencyLevel, DEFAULT_CAPACITY, comparer)
      {
         if (collection == null)
            throw new ArgumentNullException ("collection");
         if (comparer == null)
            throw new ArgumentNullException ("comparer");
        /// <summary>
        /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that contains elements copied from the specified <see cref="T:System.Collections.IEnumerable"/>,
        /// has the specified concurrency level, has the specified initial capacity, and uses the specified
        /// <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
        /// </summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
        /// <param name="collection">The <see cref="T:System.Collections.IEnumerable{KeyValuePair{TKey,TValue}}"/> whose elements are copied to the new
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/>.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/> implementation to use
        /// when comparing keys.</param>
        /// <exception cref="T:System.ArgumentNullException">
        /// <paramref name="collection"/> is a null reference (Nothing in Visual Basic).
        /// -or-
        /// <paramref name="comparer"/> is a null reference (Nothing in Visual Basic).
        /// </exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        /// <paramref name="concurrencyLevel"/> is less than 1.
        /// </exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="collection"/> contains one or more duplicate keys.</exception>
        public ConcurrentDictionary(
            int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
            : this(concurrencyLevel, DEFAULT_CAPACITY, comparer)
        {
            if (collection == null)
                throw new ArgumentNullException("collection");
            if (comparer == null)
                throw new ArgumentNullException("comparer");
         InitializeFromCollection (collection);
      }
            InitializeFromCollection(collection);
        }
      private void InitializeFromCollection (IEnumerable<KeyValuePair<TKey, TValue>> collection)
      {
         TValue dummy;
         foreach (KeyValuePair<TKey, TValue> pair in collection) {
            if (pair.Key == null)
               throw new ArgumentNullException ("key");
        private void InitializeFromCollection(IEnumerable<KeyValuePair<TKey, TValue>> collection)
        {
            TValue dummy;
            foreach (KeyValuePair<TKey, TValue> pair in collection)
            {
                if (pair.Key == null)
                    throw new ArgumentNullException("key");
            if (!TryAddInternal (pair.Key, pair.Value, false, false, out dummy)) {
               throw new ArgumentException (GetResource ("ConcurrentDictionary_SourceContainsDuplicateKeys"));
            }
         }
      }
                if (!TryAddInternal(pair.Key, pair.Value, false, false, out dummy))
                {
                    throw new ArgumentException(GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys"));
                }
            }
        }
      /// <summary>
      /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// class that is empty, has the specified concurrency level, has the specified initial capacity, and
      /// uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
      /// </summary>
      /// <param name="concurrencyLevel">The estimated number of threads that will update the
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
      /// <param name="capacity">The initial number of elements that the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>
      /// can contain.</param>
      /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
      /// implementation to use when comparing keys.</param>
      /// <exception cref="T:System.ArgumentOutOfRangeException">
      /// <paramref name="concurrencyLevel"/> is less than 1. -or-
      /// <paramref name="capacity"/> is less than 0.
      /// </exception>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      public ConcurrentDictionary (int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
      {
         if (concurrencyLevel < 1) {
            throw new ArgumentOutOfRangeException ("concurrencyLevel", GetResource ("ConcurrentDictionary_ConcurrencyLevelMustBePositive"));
         }
         if (capacity < 0) {
            throw new ArgumentOutOfRangeException ("capacity", GetResource ("ConcurrentDictionary_CapacityMustNotBeNegative"));
         }
         if (comparer == null)
            throw new ArgumentNullException ("comparer");
        /// <summary>
        /// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// class that is empty, has the specified concurrency level, has the specified initial capacity, and
        /// uses the specified <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>.
        /// </summary>
        /// <param name="concurrencyLevel">The estimated number of threads that will update the
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/> concurrently.</param>
        /// <param name="capacity">The initial number of elements that the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>
        /// can contain.</param>
        /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer{TKey}"/>
        /// implementation to use when comparing keys.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        /// <paramref name="concurrencyLevel"/> is less than 1. -or-
        /// <paramref name="capacity"/> is less than 0.
        /// </exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        public ConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer)
        {
            if (concurrencyLevel < 1)
            {
                throw new ArgumentOutOfRangeException("concurrencyLevel", GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive"));
            }
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException("capacity", GetResource("ConcurrentDictionary_CapacityMustNotBeNegative"));
            }
            if (comparer == null)
                throw new ArgumentNullException("comparer");
         // The capacity should be at least as large as the concurrency level. Otherwise, we would have locks that don't guard
         // any buckets.
         if (capacity < concurrencyLevel) {
            capacity = concurrencyLevel;
         }
            // The capacity should be at least as large as the concurrency level. Otherwise, we would have locks that don't guard
            // any buckets.
            if (capacity < concurrencyLevel)
            {
                capacity = concurrencyLevel;
            }
         m_locks = new object[concurrencyLevel];
         for (int i = 0; i < m_locks.Length; i++) {
            m_locks [i] = new object ();
         }
            m_locks = new object[concurrencyLevel];
            for (int i = 0; i < m_locks.Length; i++)
            {
                m_locks[i] = new object();
            }
         m_countPerLock = new int[m_locks.Length];
         m_buckets = new Node[capacity];
         m_comparer = comparer;
      }
            m_countPerLock = new int[m_locks.Length];
            m_buckets = new Node[capacity];
            m_comparer = comparer;
        }
      /// <summary>
      /// Attempts to add the specified key and value to the <see cref="ConcurrentDictionary{TKey,
      /// TValue}"/>.
      /// </summary>
      /// <param name="key">The key of the element to add.</param>
      /// <param name="value">The value of the element to add. The value can be a null reference (Nothing
      /// in Visual Basic) for reference types.</param>
      /// <returns>true if the key/value pair was added to the <see cref="ConcurrentDictionary{TKey,
      /// TValue}"/>
      /// successfully; otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The <see cref="ConcurrentDictionary{TKey, TValue}"/>
      /// contains too many elements.</exception>
      public bool TryAdd (TKey key, TValue value)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
         TValue dummy;
         return TryAddInternal (key, value, false, true, out dummy);
      }
        /// <summary>
        /// Attempts to add the specified key and value to the <see cref="ConcurrentDictionary{TKey,
        /// TValue}"/>.
        /// </summary>
        /// <param name="key">The key of the element to add.</param>
        /// <param name="value">The value of the element to add. The value can be a null reference (Nothing
        /// in Visual Basic) for reference types.</param>
        /// <returns>true if the key/value pair was added to the <see cref="ConcurrentDictionary{TKey,
        /// TValue}"/>
        /// successfully; otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The <see cref="ConcurrentDictionary{TKey, TValue}"/>
        /// contains too many elements.</exception>
        public bool TryAdd(TKey key, TValue value)
        {
            if (key == null)
                throw new ArgumentNullException("key");
            TValue dummy;
            return TryAddInternal(key, value, false, true, out dummy);
        }
      /// <summary>
      /// Determines whether the <see cref="ConcurrentDictionary{TKey, TValue}"/> contains the specified
      /// key.
      /// </summary>
      /// <param name="key">The key to locate in the <see cref="ConcurrentDictionary{TKey,
      /// TValue}"/>.</param>
      /// <returns>true if the <see cref="ConcurrentDictionary{TKey, TValue}"/> contains an element with
      /// the specified key; otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      public bool ContainsKey (TKey key)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Determines whether the <see cref="ConcurrentDictionary{TKey, TValue}"/> contains the specified
        /// key.
        /// </summary>
        /// <param name="key">The key to locate in the <see cref="ConcurrentDictionary{TKey,
        /// TValue}"/>.</param>
        /// <returns>true if the <see cref="ConcurrentDictionary{TKey, TValue}"/> contains an element with
        /// the specified key; otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        public bool ContainsKey(TKey key)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         TValue throwAwayValue;
         return TryGetValue (key, out throwAwayValue);
      }
            TValue throwAwayValue;
            return TryGetValue(key, out throwAwayValue);
        }
      /// <summary>
      /// Attempts to remove and return the the value with the specified key from the
      /// <see cref="ConcurrentDictionary{TKey, TValue}"/>.
      /// </summary>
      /// <param name="key">The key of the element to remove and return.</param>
      /// <param name="value">When this method returns, <paramref name="value"/> contains the object removed from the
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/> or the default value of <typeparamref
      /// name="TValue"/>
      /// if the operation failed.</param>
      /// <returns>true if an object was removed successfully; otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      public bool TryRemove (TKey key, out TValue value)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Attempts to remove and return the the value with the specified key from the
        /// <see cref="ConcurrentDictionary{TKey, TValue}"/>.
        /// </summary>
        /// <param name="key">The key of the element to remove and return.</param>
        /// <param name="value">When this method returns, <paramref name="value"/> contains the object removed from the
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/> or the default value of <typeparamref
        /// name="TValue"/>
        /// if the operation failed.</param>
        /// <returns>true if an object was removed successfully; otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        public bool TryRemove(TKey key, out TValue value)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         return TryRemoveInternal (key, out value, false, default(TValue));
      }
            return TryRemoveInternal(key, out value, false, default(TValue));
        }
      /// <summary>
      /// Removes the specified key from the dictionary if it exists and returns its associated value.
      /// If matchValue flag is set, the key will be removed only if is associated with a particular
      /// value.
      /// </summary>
      /// <param name="key">The key to search for and remove if it exists.</param>
      /// <param name="value">The variable into which the removed value, if found, is stored.</param>
      /// <param name="matchValue">Whether removal of the key is conditional on its value.</param>
      /// <param name="oldValue">The conditional value to compare against if <paramref name="matchValue"/> is true</param>
      /// <returns></returns>
      private bool TryRemoveInternal (TKey key, out TValue value, bool matchValue, TValue oldValue)
      {
         while (true) {
            Node[] buckets = m_buckets;
        /// <summary>
        /// Removes the specified key from the dictionary if it exists and returns its associated value.
        /// If matchValue flag is set, the key will be removed only if is associated with a particular
        /// value.
        /// </summary>
        /// <param name="key">The key to search for and remove if it exists.</param>
        /// <param name="value">The variable into which the removed value, if found, is stored.</param>
        /// <param name="matchValue">Whether removal of the key is conditional on its value.</param>
        /// <param name="oldValue">The conditional value to compare against if <paramref name="matchValue"/> is true</param>
        /// <returns></returns>
        private bool TryRemoveInternal(TKey key, out TValue value, bool matchValue, TValue oldValue)
        {
            while (true)
            {
                Node[] buckets = m_buckets;
            int bucketNo, lockNo;
            GetBucketAndLockNo (m_comparer.GetHashCode (key), out bucketNo, out lockNo, buckets.Length);
                int bucketNo, lockNo;
                GetBucketAndLockNo(m_comparer.GetHashCode(key), out bucketNo, out lockNo, buckets.Length);
            lock (m_locks[lockNo]) {
               // If the table just got resized, we may not be holding the right lock, and must retry.
               // This should be a rare occurence.
               if (buckets != m_buckets) {
                  continue;
               }
                lock (m_locks[lockNo])
                {
                    // If the table just got resized, we may not be holding the right lock, and must retry.
                    // This should be a rare occurence.
                    if (buckets != m_buckets)
                    {
                        continue;
                    }
               Node prev = null;
               for (Node curr = m_buckets [bucketNo]; curr != null; curr = curr.m_next) {
                  Assert ((prev == null && curr == m_buckets [bucketNo]) || prev.m_next == curr);
                    Node prev = null;
                    for (Node curr = m_buckets[bucketNo]; curr != null; curr = curr.m_next)
                    {
                        Assert((prev == null && curr == m_buckets[bucketNo]) || prev.m_next == curr);
                  if (m_comparer.Equals (curr.m_key, key)) {
                     if (matchValue) {
                        bool valuesMatch = EqualityComparer<TValue>.Default.Equals (oldValue, curr.m_value);
                        if (!valuesMatch) {
                           value = default(TValue);
                           return false;
                        }
                     }
                        if (m_comparer.Equals(curr.m_key, key))
                        {
                            if (matchValue)
                            {
                                bool valuesMatch = EqualityComparer<TValue>.Default.Equals(oldValue, curr.m_value);
                                if (!valuesMatch)
                                {
                                    value = default(TValue);
                                    return false;
                                }
                            }
                     if (prev == null) {
                        m_buckets [bucketNo] = curr.m_next;
                     } else {
                        prev.m_next = curr.m_next;
                     }
                            if (prev == null)
                            {
                                m_buckets[bucketNo] = curr.m_next;
                            }
                            else
                            {
                                prev.m_next = curr.m_next;
                            }
                     value = curr.m_value;
                     m_countPerLock [lockNo]--;
                     return true;
                  }
                  prev = curr;
               }
            }
                            value = curr.m_value;
                            m_countPerLock[lockNo]--;
                            return true;
                        }
                        prev = curr;
                    }
                }
            value = default(TValue);
            return false;
         }
      }
                value = default(TValue);
                return false;
            }
        }
      /// <summary>
      /// Attempts to get the value associated with the specified key from the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.
      /// </summary>
      /// <param name="key">The key of the value to get.</param>
      /// <param name="value">When this method returns, <paramref name="value"/> contains the object from
      /// the
      /// <see cref="ConcurrentDictionary{TKey,TValue}"/> with the spedified key or the default value of
      /// <typeparamref name="TValue"/>, if the operation failed.</param>
      /// <returns>true if the key was found in the <see cref="ConcurrentDictionary{TKey,TValue}"/>;
      /// otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      public bool TryGetValue (TKey key, out TValue value)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Attempts to get the value associated with the specified key from the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.
        /// </summary>
        /// <param name="key">The key of the value to get.</param>
        /// <param name="value">When this method returns, <paramref name="value"/> contains the object from
        /// the
        /// <see cref="ConcurrentDictionary{TKey,TValue}"/> with the spedified key or the default value of
        /// <typeparamref name="TValue"/>, if the operation failed.</param>
        /// <returns>true if the key was found in the <see cref="ConcurrentDictionary{TKey,TValue}"/>;
        /// otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        public bool TryGetValue(TKey key, out TValue value)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         int bucketNo, lockNoUnused;
            int bucketNo, lockNoUnused;
         // We must capture the m_buckets field in a local variable. It is set to a new table on each table resize.
         Node[] buckets = m_buckets;
         GetBucketAndLockNo (m_comparer.GetHashCode (key), out bucketNo, out lockNoUnused, buckets.Length);
            // We must capture the m_buckets field in a local variable. It is set to a new table on each table resize.
            Node[] buckets = m_buckets;
            GetBucketAndLockNo(m_comparer.GetHashCode(key), out bucketNo, out lockNoUnused, buckets.Length);
         // We can get away w/out a lock here.
         Node n = buckets [bucketNo];
            // We can get away w/out a lock here.
            Node n = buckets[bucketNo];
         // The memory barrier ensures that the load of the fields of 'n' doesn’t move before the load from buckets[i].
         Thread.MemoryBarrier ();
         while (n != null) {
            if (m_comparer.Equals (n.m_key, key)) {
               value = n.m_value;
               return true;
            }
            n = n.m_next;
         }
            // The memory barrier ensures that the load of the fields of 'n' doesn’t move before the load from buckets[i].
            Thread.MemoryBarrier();
            while (n != null)
            {
                if (m_comparer.Equals(n.m_key, key))
                {
                    value = n.m_value;
                    return true;
                }
                n = n.m_next;
            }
         value = default(TValue);
         return false;
      }
            value = default(TValue);
            return false;
        }
      /// <summary>
      /// Compares the existing value for the specified key with a specified value, and if they’re equal,
      /// updates the key with a third value.
      /// </summary>
      /// <param name="key">The key whose value is compared with <paramref name="comparisonValue"/> and
      /// possibly replaced.</param>
      /// <param name="newValue">The value that replaces the value of the element with <paramref
      /// name="key"/> if the comparison results in equality.</param>
      /// <param name="comparisonValue">The value that is compared to the value of the element with
      /// <paramref name="key"/>.</param>
      /// <returns>true if the value with <paramref name="key"/> was equal to <paramref
      /// name="comparisonValue"/> and replaced with <paramref name="newValue"/>; otherwise,
      /// false.</returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null
      /// reference.</exception>
      public bool TryUpdate (TKey key, TValue newValue, TValue comparisonValue)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Compares the existing value for the specified key with a specified value, and if they’re equal,
        /// updates the key with a third value.
        /// </summary>
        /// <param name="key">The key whose value is compared with <paramref name="comparisonValue"/> and
        /// possibly replaced.</param>
        /// <param name="newValue">The value that replaces the value of the element with <paramref
        /// name="key"/> if the comparison results in equality.</param>
        /// <param name="comparisonValue">The value that is compared to the value of the element with
        /// <paramref name="key"/>.</param>
        /// <returns>true if the value with <paramref name="key"/> was equal to <paramref
        /// name="comparisonValue"/> and replaced with <paramref name="newValue"/>; otherwise,
        /// false.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null
        /// reference.</exception>
        public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         int hashcode = m_comparer.GetHashCode (key);
         IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
            int hashcode = m_comparer.GetHashCode(key);
            IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
         while (true) {
            int bucketNo;
            int lockNo;
            while (true)
            {
                int bucketNo;
                int lockNo;
            Node[] buckets = m_buckets;
            GetBucketAndLockNo (hashcode, out bucketNo, out lockNo, buckets.Length);
                Node[] buckets = m_buckets;
                GetBucketAndLockNo(hashcode, out bucketNo, out lockNo, buckets.Length);
            lock (m_locks[lockNo]) {
               // If the table just got resized, we may not be holding the right lock, and must retry.
               // This should be a rare occurence.
               if (buckets != m_buckets) {
                  continue;
               }
                lock (m_locks[lockNo])
                {
                    // If the table just got resized, we may not be holding the right lock, and must retry.
                    // This should be a rare occurence.
                    if (buckets != m_buckets)
                    {
                        continue;
                    }
               // Try to find this key in the bucket
               Node prev = null;
               for (Node node = buckets [bucketNo]; node != null; node = node.m_next) {
                  Assert ((prev == null && node == m_buckets [bucketNo]) || prev.m_next == node);
                  if (m_comparer.Equals (node.m_key, key)) {
                     if (valueComparer.Equals (node.m_value, comparisonValue)) {
                        // Replace the old node with a new node. Unfortunately, we cannot simply
                        // change node.m_value in place. We don't know the size of TValue, so
                        // its writes may not be atomic.
                        Node newNode = new Node (node.m_key, newValue, hashcode, node.m_next);
                    // Try to find this key in the bucket
                    Node prev = null;
                    for (Node node = buckets[bucketNo]; node != null; node = node.m_next)
                    {
                        Assert((prev == null && node == m_buckets[bucketNo]) || prev.m_next == node);
                        if (m_comparer.Equals(node.m_key, key))
                        {
                            if (valueComparer.Equals(node.m_value, comparisonValue))
                            {
                                // Replace the old node with a new node. Unfortunately, we cannot simply
                                // change node.m_value in place. We don't know the size of TValue, so
                                // its writes may not be atomic.
                                Node newNode = new Node(node.m_key, newValue, hashcode, node.m_next);
                        if (prev == null) {
                           buckets [bucketNo] = newNode;
                        } else {
                           prev.m_next = newNode;
                        }
                                if (prev == null)
                                {
                                    buckets[bucketNo] = newNode;
                                }
                                else
                                {
                                    prev.m_next = newNode;
                                }
                        return true;
                     }
                                return true;
                            }
                     return false;
                  }
                            return false;
                        }
                  prev = node;
               }
                        prev = node;
                    }
               //didn't find the key
               return false;
            }
         }
      }
                    //didn't find the key
                    return false;
                }
            }
        }
      /// <summary>
      /// Removes all keys and values from the <see cref="ConcurrentDictionary{TKey,TValue}"/>.
      /// </summary>
      public void Clear ()
      {
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
        /// <summary>
        /// Removes all keys and values from the <see cref="ConcurrentDictionary{TKey,TValue}"/>.
        /// </summary>
        public void Clear()
        {
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
            m_buckets = new Node[DEFAULT_CAPACITY];
            Array.Clear (m_countPerLock, 0, m_countPerLock.Length);
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                m_buckets = new Node[DEFAULT_CAPACITY];
                Array.Clear(m_countPerLock, 0, m_countPerLock.Length);
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection"/> to an array of
      /// type <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>, starting at the
      /// specified array index.
      /// </summary>
      /// <param name="array">The one-dimensional array of type <see
      /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
      /// that is the destination of the <see
      /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/> elements copied from the <see
      /// cref="T:System.Collections.ICollection"/>. The array must have zero-based indexing.</param>
      /// <param name="index">The zero-based index in <paramref name="array"/> at which copying
      /// begins.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than
      /// 0.</exception>
      /// <exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than
      /// the length of the <paramref name="array"/>. -or- The number of elements in the source <see
      /// cref="T:System.Collections.ICollection"/>
      /// is greater than the available space from <paramref name="index"/> to the end of the destination
      /// <paramref name="array"/>.</exception>
      void ICollection<KeyValuePair<TKey, TValue>>.CopyTo (KeyValuePair<TKey, TValue>[] array, int index)
      {
         if (array == null)
            throw new ArgumentNullException ("array");
         if (index < 0)
            throw new ArgumentOutOfRangeException ("index", GetResource ("ConcurrentDictionary_IndexIsNegative"));
        /// <summary>
        /// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection"/> to an array of
        /// type <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>, starting at the
        /// specified array index.
        /// </summary>
        /// <param name="array">The one-dimensional array of type <see
        /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
        /// that is the destination of the <see
        /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/> elements copied from the <see
        /// cref="T:System.Collections.ICollection"/>. The array must have zero-based indexing.</param>
        /// <param name="index">The zero-based index in <paramref name="array"/> at which copying
        /// begins.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than
        /// 0.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than
        /// the length of the <paramref name="array"/>. -or- The number of elements in the source <see
        /// cref="T:System.Collections.ICollection"/>
        /// is greater than the available space from <paramref name="index"/> to the end of the destination
        /// <paramref name="array"/>.</exception>
        void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
        {
            if (array == null)
                throw new ArgumentNullException("array");
            if (index < 0)
                throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative"));
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
            int count = 0;
                int count = 0;
            for (int i = 0; i < m_locks.Length; i++) {
               count += m_countPerLock [i];
            }
                for (int i = 0; i < m_locks.Length; i++)
                {
                    count += m_countPerLock[i];
                }
            if (array.Length - count < index || count < 0) { //"count" itself or "count + index" can overflow
               throw new ArgumentException (GetResource ("ConcurrentDictionary_ArrayNotLargeEnough"));
            }
                if (array.Length - count < index || count < 0)
                { //"count" itself or "count + index" can overflow
                    throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough"));
                }
            CopyToPairs (array, index);
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                CopyToPairs(array, index);
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Copies the key and value pairs stored in the <see cref="ConcurrentDictionary{TKey,TValue}"/> to a
      /// new array.
      /// </summary>
      /// <returns>A new array containing a snapshot of key and value pairs copied from the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
      public KeyValuePair<TKey, TValue>[] ToArray ()
      {
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
            int count = 0;
            checked {
               for (int i = 0; i < m_locks.Length; i++) {
                  count += m_countPerLock [i];
               }
            }
        /// <summary>
        /// Copies the key and value pairs stored in the <see cref="ConcurrentDictionary{TKey,TValue}"/> to a
        /// new array.
        /// </summary>
        /// <returns>A new array containing a snapshot of key and value pairs copied from the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
        public KeyValuePair<TKey, TValue>[] ToArray()
        {
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
                int count = 0;
                checked
                {
                    for (int i = 0; i < m_locks.Length; i++)
                    {
                        count += m_countPerLock[i];
                    }
                }
            KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[count];
                KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[count];
            CopyToPairs (array, 0);
            return array;
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                CopyToPairs(array, 0);
                return array;
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
      ///
      /// Important: the caller must hold all locks in m_locks before calling CopyToPairs.
      /// </summary>
      private void CopyToPairs (KeyValuePair<TKey, TValue>[] array, int index)
      {
         Node[] buckets = m_buckets;
         for (int i = 0; i < buckets.Length; i++) {
            for (Node current = buckets [i]; current != null; current = current.m_next) {
               array [index] = new KeyValuePair<TKey, TValue> (current.m_key, current.m_value);
               index++; //this should never flow, CopyToPairs is only called when there's no overflow risk
            }
         }
      }
        /// <summary>
        /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
        ///
        /// Important: the caller must hold all locks in m_locks before calling CopyToPairs.
        /// </summary>
        private void CopyToPairs(KeyValuePair<TKey, TValue>[] array, int index)
        {
            Node[] buckets = m_buckets;
            for (int i = 0; i < buckets.Length; i++)
            {
                for (Node current = buckets[i]; current != null; current = current.m_next)
                {
                    array[index] = new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);
                    index++; //this should never flow, CopyToPairs is only called when there's no overflow risk
                }
            }
        }
      /// <summary>
      /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
      ///
      /// Important: the caller must hold all locks in m_locks before calling CopyToEntries.
      /// </summary>
      private void CopyToEntries (DictionaryEntry[] array, int index)
      {
         Node[] buckets = m_buckets;
         for (int i = 0; i < buckets.Length; i++) {
            for (Node current = buckets [i]; current != null; current = current.m_next) {
               array [index] = new DictionaryEntry (current.m_key, current.m_value);
               index++;  //this should never flow, CopyToEntries is only called when there's no overflow risk
            }
         }
      }
        /// <summary>
        /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
        ///
        /// Important: the caller must hold all locks in m_locks before calling CopyToEntries.
        /// </summary>
        private void CopyToEntries(DictionaryEntry[] array, int index)
        {
            Node[] buckets = m_buckets;
            for (int i = 0; i < buckets.Length; i++)
            {
                for (Node current = buckets[i]; current != null; current = current.m_next)
                {
                    array[index] = new DictionaryEntry(current.m_key, current.m_value);
                    index++;  //this should never flow, CopyToEntries is only called when there's no overflow risk
                }
            }
        }
      /// <summary>
      /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
      ///
      /// Important: the caller must hold all locks in m_locks before calling CopyToObjects.
      /// </summary>
      private void CopyToObjects (object[] array, int index)
      {
         Node[] buckets = m_buckets;
         for (int i = 0; i < buckets.Length; i++) {
            for (Node current = buckets [i]; current != null; current = current.m_next) {
               array [index] = new KeyValuePair<TKey, TValue> (current.m_key, current.m_value);
               index++; //this should never flow, CopyToObjects is only called when there's no overflow risk
            }
         }
      }
        /// <summary>
        /// Copy dictionary contents to an array - shared implementation between ToArray and CopyTo.
        ///
        /// Important: the caller must hold all locks in m_locks before calling CopyToObjects.
        /// </summary>
        private void CopyToObjects(object[] array, int index)
        {
            Node[] buckets = m_buckets;
            for (int i = 0; i < buckets.Length; i++)
            {
                for (Node current = buckets[i]; current != null; current = current.m_next)
                {
                    array[index] = new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);
                    index++; //this should never flow, CopyToObjects is only called when there's no overflow risk
                }
            }
        }
      /// <summary>Returns an enumerator that iterates through the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.</summary>
      /// <returns>An enumerator for the <see cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
      /// <remarks>
      /// The enumerator returned from the dictionary is safe to use concurrently with
      /// reads and writes to the dictionary, however it does not represent a moment-in-time snapshot
      /// of the dictionary.  The contents exposed through the enumerator may contain modifications
      /// made to the dictionary after <see cref="GetEnumerator"/> was called.
      /// </remarks>
      public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator ()
      {
         Node[] buckets = m_buckets;
        /// <summary>Returns an enumerator that iterates through the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.</summary>
        /// <returns>An enumerator for the <see cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
        /// <remarks>
        /// The enumerator returned from the dictionary is safe to use concurrently with
        /// reads and writes to the dictionary, however it does not represent a moment-in-time snapshot
        /// of the dictionary.  The contents exposed through the enumerator may contain modifications
        /// made to the dictionary after <see cref="GetEnumerator"/> was called.
        /// </remarks>
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            Node[] buckets = m_buckets;
         for (int i = 0; i < buckets.Length; i++) {
            Node current = buckets [i];
            for (int i = 0; i < buckets.Length; i++)
            {
                Node current = buckets[i];
            // The memory barrier ensures that the load of the fields of 'current' doesn’t move before the load from buckets[i].
            Thread.MemoryBarrier ();
            while (current != null) {
               yield return new KeyValuePair<TKey, TValue> (current.m_key, current.m_value);
               current = current.m_next;
            }
         }
      }
                // The memory barrier ensures that the load of the fields of 'current' doesn’t move before the load from buckets[i].
                Thread.MemoryBarrier();
                while (current != null)
                {
                    yield return new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);
                    current = current.m_next;
                }
            }
        }
      /// <summary>
      /// Shared internal implementation for inserts and updates.
      /// If key exists, we always return false; and if updateIfExists == true we force update with value;
      /// If key doesn't exist, we always add value and return true;
      /// </summary>
      private bool TryAddInternal (TKey key, TValue value, bool updateIfExists, bool acquireLock, out TValue resultingValue)
      {
         int hashcode = m_comparer.GetHashCode (key);
        /// <summary>
        /// Shared internal implementation for inserts and updates.
        /// If key exists, we always return false; and if updateIfExists == true we force update with value;
        /// If key doesn't exist, we always add value and return true;
        /// </summary>
        private bool TryAddInternal(TKey key, TValue value, bool updateIfExists, bool acquireLock, out TValue resultingValue)
        {
            int hashcode = m_comparer.GetHashCode(key);
         while (true) {
            int bucketNo, lockNo;
            while (true)
            {
                int bucketNo, lockNo;
            Node[] buckets = m_buckets;
            GetBucketAndLockNo (hashcode, out bucketNo, out lockNo, buckets.Length);
                Node[] buckets = m_buckets;
                GetBucketAndLockNo(hashcode, out bucketNo, out lockNo, buckets.Length);
            bool resizeDesired = false;
            bool lockTaken = false;
            try {
               if (acquireLock) {
                  Monitor.Enter (m_locks [lockNo]);
                  lockTaken = true;
               }
                bool resizeDesired = false;
                bool lockTaken = false;
                try
                {
                    if (acquireLock)
                    {
                        Monitor.Enter(m_locks[lockNo]);
                        lockTaken = true;
                    }
               // If the table just got resized, we may not be holding the right lock, and must retry.
               // This should be a rare occurence.
               if (buckets != m_buckets) {
                  continue;
               }
                    // If the table just got resized, we may not be holding the right lock, and must retry.
                    // This should be a rare occurence.
                    if (buckets != m_buckets)
                    {
                        continue;
                    }
               // Try to find this key in the bucket
               Node prev = null;
               for (Node node = buckets [bucketNo]; node != null; node = node.m_next) {
                  Assert ((prev == null && node == m_buckets [bucketNo]) || prev.m_next == node);
                  if (m_comparer.Equals (node.m_key, key)) {
                     // The key was found in the dictionary. If updates are allowed, update the value for that key.
                     // We need to create a new node for the update, in order to support TValue types that cannot
                     // be written atomically, since lock-free reads may be happening concurrently.
                     if (updateIfExists) {
                        Node newNode = new Node (node.m_key, value, hashcode, node.m_next);
                        if (prev == null) {
                           buckets [bucketNo] = newNode;
                        } else {
                           prev.m_next = newNode;
                        }
                        resultingValue = value;
                     } else {
                        resultingValue = node.m_value;
                     }
                     return false;
                  }
                  prev = node;
               }
                    // Try to find this key in the bucket
                    Node prev = null;
                    for (Node node = buckets[bucketNo]; node != null; node = node.m_next)
                    {
                        Assert((prev == null && node == m_buckets[bucketNo]) || prev.m_next == node);
                        if (m_comparer.Equals(node.m_key, key))
                        {
                            // The key was found in the dictionary. If updates are allowed, update the value for that key.
                            // We need to create a new node for the update, in order to support TValue types that cannot
                            // be written atomically, since lock-free reads may be happening concurrently.
                            if (updateIfExists)
                            {
                                Node newNode = new Node(node.m_key, value, hashcode, node.m_next);
                                if (prev == null)
                                {
                                    buckets[bucketNo] = newNode;
                                }
                                else
                                {
                                    prev.m_next = newNode;
                                }
                                resultingValue = value;
                            }
                            else
                            {
                                resultingValue = node.m_value;
                            }
                            return false;
                        }
                        prev = node;
                    }
               // The key was not found in the bucket. Insert the key-value pair.
               buckets [bucketNo] = new Node (key, value, hashcode, buckets [bucketNo]);
               checked {
                  m_countPerLock [lockNo]++;
               }
                    // The key was not found in the bucket. Insert the key-value pair.
                    buckets[bucketNo] = new Node(key, value, hashcode, buckets[bucketNo]);
                    checked
                    {
                        m_countPerLock[lockNo]++;
                    }
               //
               // If this lock has element / bucket ratio greater than 1, resize the entire table.
               // Note: the formula is chosen to avoid overflow, but has a small inaccuracy due to
               // rounding.
               //
               if (m_countPerLock [lockNo] > buckets.Length / m_locks.Length) {
                  resizeDesired = true;
               }
            } finally {
               if (lockTaken)
                  Monitor.Exit (m_locks [lockNo]);
            }
                    //
                    // If this lock has element / bucket ratio greater than 1, resize the entire table.
                    // Note: the formula is chosen to avoid overflow, but has a small inaccuracy due to
                    // rounding.
                    //
                    if (m_countPerLock[lockNo] > buckets.Length / m_locks.Length)
                    {
                        resizeDesired = true;
                    }
                }
                finally
                {
                    if (lockTaken)
                        Monitor.Exit(m_locks[lockNo]);
                }
            //
            // The fact that we got here means that we just performed an insertion. If necessary, we will grow the table.
            //
            // Concurrency notes:
            // - Notice that we are not holding any locks at when calling GrowTable. This is necessary to prevent deadlocks.
            // - As a result, it is possible that GrowTable will be called unnecessarily. But, GrowTable will obtain lock 0
            //   and then verify that the table we passed to it as the argument is still the current table.
            //
            if (resizeDesired) {
               GrowTable (buckets);
            }
                //
                // The fact that we got here means that we just performed an insertion. If necessary, we will grow the table.
                //
                // Concurrency notes:
                // - Notice that we are not holding any locks at when calling GrowTable. This is necessary to prevent deadlocks.
                // - As a result, it is possible that GrowTable will be called unnecessarily. But, GrowTable will obtain lock 0
                //   and then verify that the table we passed to it as the argument is still the current table.
                //
                if (resizeDesired)
                {
                    GrowTable(buckets);
                }
            resultingValue = value;
            return true;
         }
      }
                resultingValue = value;
                return true;
            }
        }
      /// <summary>
      /// Gets or sets the value associated with the specified key.
      /// </summary>
      /// <param name="key">The key of the value to get or set.</param>
      /// <value>The value associated with the specified key. If the specified key is not found, a get
      /// operation throws a
      /// <see cref="T:Sytem.Collections.Generic.KeyNotFoundException"/>, and a set operation creates a new
      /// element with the specified key.</value>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">The property is retrieved and
      /// <paramref name="key"/>
      /// does not exist in the collection.</exception>
      public TValue this [TKey key] {
         get {
            TValue value;
            if (!TryGetValue (key, out value)) {
               throw new KeyNotFoundException ();
            }
            return value;
         }
         set {
            if (key == null)
               throw new ArgumentNullException ("key");
            TValue dummy;
            TryAddInternal (key, value, true, true, out dummy);
         }
      }
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <param name="key">The key of the value to get or set.</param>
        /// <value>The value associated with the specified key. If the specified key is not found, a get
        /// operation throws a
        /// <see cref="T:Sytem.Collections.Generic.KeyNotFoundException"/>, and a set operation creates a new
        /// element with the specified key.</value>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">The property is retrieved and
        /// <paramref name="key"/>
        /// does not exist in the collection.</exception>
        public TValue this[TKey key]
        {
            get
            {
                TValue value;
                if (!TryGetValue(key, out value))
                {
                    throw new KeyNotFoundException();
                }
                return value;
            }
            set
            {
                if (key == null)
                    throw new ArgumentNullException("key");
                TValue dummy;
                TryAddInternal(key, value, true, true, out dummy);
            }
        }
      /// <summary>
      /// Gets the number of key/value pairs contained in the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.
      /// </summary>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <value>The number of key/value paris contained in the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.</value>
      /// <remarks>Count has snapshot semantics and represents the number of items in the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>
      /// at the moment when Count was accessed.</remarks>
      public int Count {
         get {
            int count = 0;
        /// <summary>
        /// Gets the number of key/value pairs contained in the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.
        /// </summary>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <value>The number of key/value paris contained in the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.</value>
        /// <remarks>Count has snapshot semantics and represents the number of items in the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>
        /// at the moment when Count was accessed.</remarks>
        public int Count
        {
            get
            {
                int count = 0;
            int acquiredLocks = 0;
            try {
               // Acquire all locks
               AcquireAllLocks (ref acquiredLocks);
                int acquiredLocks = 0;
                try
                {
                    // Acquire all locks
                    AcquireAllLocks(ref acquiredLocks);
               // Compute the count, we allow overflow
               for (int i = 0; i < m_countPerLock.Length; i++) {
                  count += m_countPerLock [i];
               }
                    // Compute the count, we allow overflow
                    for (int i = 0; i < m_countPerLock.Length; i++)
                    {
                        count += m_countPerLock[i];
                    }
            } finally {
               // Release locks that have been acquired earlier
               ReleaseLocks (0, acquiredLocks);
            }
                }
                finally
                {
                    // Release locks that have been acquired earlier
                    ReleaseLocks(0, acquiredLocks);
                }
            return count;
         }
      }
                return count;
            }
        }
      /// <summary>
      /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// if the key does not already exist.
      /// </summary>
      /// <param name="key">The key of the element to add.</param>
      /// <param name="valueFactory">The function used to generate a value for the key</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="valueFactory"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <returns>The value for the key.  This will be either the existing value for the key if the
      /// key is already in the dictionary, or the new value for the key as returned by valueFactory
      /// if the key was not in the dictionary.</returns>
      public TValue GetOrAdd (TKey key, Func<TKey, TValue> valueFactory)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
         if (valueFactory == null)
            throw new ArgumentNullException ("valueFactory");
        /// <summary>
        /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// if the key does not already exist.
        /// </summary>
        /// <param name="key">The key of the element to add.</param>
        /// <param name="valueFactory">The function used to generate a value for the key</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="valueFactory"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <returns>The value for the key.  This will be either the existing value for the key if the
        /// key is already in the dictionary, or the new value for the key as returned by valueFactory
        /// if the key was not in the dictionary.</returns>
        public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
        {
            if (key == null)
                throw new ArgumentNullException("key");
            if (valueFactory == null)
                throw new ArgumentNullException("valueFactory");
         TValue resultingValue;
         if (TryGetValue (key, out resultingValue)) {
            return resultingValue;
         }
         TryAddInternal (key, valueFactory (key), false, true, out resultingValue);
         return resultingValue;
      }
            TValue resultingValue;
            if (TryGetValue(key, out resultingValue))
            {
                return resultingValue;
            }
            TryAddInternal(key, valueFactory(key), false, true, out resultingValue);
            return resultingValue;
        }
      /// <summary>
      /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/>
      /// if the key does not already exist.
      /// </summary>
      /// <param name="key">The key of the element to add.</param>
      /// <param name="value">the value to be added, if the key does not already exist</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <returns>The value for the key.  This will be either the existing value for the key if the
      /// key is already in the dictionary, or the new value if the key was not in the dictionary.</returns>
      public TValue GetOrAdd (TKey key, TValue value)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/>
        /// if the key does not already exist.
        /// </summary>
        /// <param name="key">The key of the element to add.</param>
        /// <param name="value">the value to be added, if the key does not already exist</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <returns>The value for the key.  This will be either the existing value for the key if the
        /// key is already in the dictionary, or the new value if the key was not in the dictionary.</returns>
        public TValue GetOrAdd(TKey key, TValue value)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         TValue resultingValue;
         TryAddInternal (key, value, false, true, out resultingValue);
         return resultingValue;
      }
            TValue resultingValue;
            TryAddInternal(key, value, false, true, out resultingValue);
            return resultingValue;
        }
      /// <summary>
      /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key does not already
      /// exist, or updates a key/value pair in the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key
      /// already exists.
      /// </summary>
      /// <param name="key">The key to be added or whose value should be updated</param>
      /// <param name="addValueFactory">The function used to generate a value for an absent key</param>
      /// <param name="updateValueFactory">The function used to generate a new value for an existing key
      /// based on the key's existing value</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="addValueFactory"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="updateValueFactory"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <returns>The new value for the key.  This will be either be the result of addValueFactory (if the key was
      /// absent) or the result of updateValueFactory (if the key was present).</returns>
      public TValue AddOrUpdate (TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
         if (addValueFactory == null)
            throw new ArgumentNullException ("addValueFactory");
         if (updateValueFactory == null)
            throw new ArgumentNullException ("updateValueFactory");
        /// <summary>
        /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key does not already
        /// exist, or updates a key/value pair in the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key
        /// already exists.
        /// </summary>
        /// <param name="key">The key to be added or whose value should be updated</param>
        /// <param name="addValueFactory">The function used to generate a value for an absent key</param>
        /// <param name="updateValueFactory">The function used to generate a new value for an existing key
        /// based on the key's existing value</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="addValueFactory"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="updateValueFactory"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <returns>The new value for the key.  This will be either be the result of addValueFactory (if the key was
        /// absent) or the result of updateValueFactory (if the key was present).</returns>
        public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
        {
            if (key == null)
                throw new ArgumentNullException("key");
            if (addValueFactory == null)
                throw new ArgumentNullException("addValueFactory");
            if (updateValueFactory == null)
                throw new ArgumentNullException("updateValueFactory");
         TValue newValue, resultingValue;
         while (true) {
            TValue oldValue;
            if (TryGetValue (key, out oldValue))
 {                //key exists, try to update
               newValue = updateValueFactory (key, oldValue);
               if (TryUpdate (key, newValue, oldValue)) {
                  return newValue;
               }
            } else { //try add
               newValue = addValueFactory (key);
               if (TryAddInternal (key, newValue, false, true, out resultingValue)) {
                  return resultingValue;
               }
            }
         }
      }
            TValue newValue, resultingValue;
            while (true)
            {
                TValue oldValue;
                if (TryGetValue(key, out oldValue))
                {                //key exists, try to update
                    newValue = updateValueFactory(key, oldValue);
                    if (TryUpdate(key, newValue, oldValue))
                    {
                        return newValue;
                    }
                }
                else
                { //try add
                    newValue = addValueFactory(key);
                    if (TryAddInternal(key, newValue, false, true, out resultingValue))
                    {
                        return resultingValue;
                    }
                }
            }
        }
      /// <summary>
      /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key does not already
      /// exist, or updates a key/value pair in the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key
      /// already exists.
      /// </summary>
      /// <param name="key">The key to be added or whose value should be updated</param>
      /// <param name="addValue">The value to be added for an absent key</param>
      /// <param name="updateValueFactory">The function used to generate a new value for an existing key based on
      /// the key's existing value</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="updateValueFactory"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <returns>The new value for the key.  This will be either be the result of addValueFactory (if the key was
      /// absent) or the result of updateValueFactory (if the key was present).</returns>
      public TValue AddOrUpdate (TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
         if (updateValueFactory == null)
            throw new ArgumentNullException ("updateValueFactory");
         TValue newValue, resultingValue;
         while (true) {
            TValue oldValue;
            if (TryGetValue (key, out oldValue))
 {                //key exists, try to update
               newValue = updateValueFactory (key, oldValue);
               if (TryUpdate (key, newValue, oldValue)) {
                  return newValue;
               }
            } else { //try add
               if (TryAddInternal (key, addValue, false, true, out resultingValue)) {
                  return resultingValue;
               }
            }
         }
      }
        /// <summary>
        /// Adds a key/value pair to the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key does not already
        /// exist, or updates a key/value pair in the <see cref="ConcurrentDictionary{TKey,TValue}"/> if the key
        /// already exists.
        /// </summary>
        /// <param name="key">The key to be added or whose value should be updated</param>
        /// <param name="addValue">The value to be added for an absent key</param>
        /// <param name="updateValueFactory">The function used to generate a new value for an existing key based on
        /// the key's existing value</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="updateValueFactory"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <returns>The new value for the key.  This will be either be the result of addValueFactory (if the key was
        /// absent) or the result of updateValueFactory (if the key was present).</returns>
        public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
        {
            if (key == null)
                throw new ArgumentNullException("key");
            if (updateValueFactory == null)
                throw new ArgumentNullException("updateValueFactory");
            TValue newValue, resultingValue;
            while (true)
            {
                TValue oldValue;
                if (TryGetValue(key, out oldValue))
                {                //key exists, try to update
                    newValue = updateValueFactory(key, oldValue);
                    if (TryUpdate(key, newValue, oldValue))
                    {
                        return newValue;
                    }
                }
                else
                { //try add
                    if (TryAddInternal(key, addValue, false, true, out resultingValue))
                    {
                        return resultingValue;
                    }
                }
            }
        }
      /// <summary>
      /// Gets a value that indicates whether the <see cref="ConcurrentDictionary{TKey,TValue}"/> is empty.
      /// </summary>
      /// <value>true if the <see cref="ConcurrentDictionary{TKey,TValue}"/> is empty; otherwise,
      /// false.</value>
      public bool IsEmpty {
         get {
            int acquiredLocks = 0;
            try {
               // Acquire all locks
               AcquireAllLocks (ref acquiredLocks);
        /// <summary>
        /// Gets a value that indicates whether the <see cref="ConcurrentDictionary{TKey,TValue}"/> is empty.
        /// </summary>
        /// <value>true if the <see cref="ConcurrentDictionary{TKey,TValue}"/> is empty; otherwise,
        /// false.</value>
        public bool IsEmpty
        {
            get
            {
                int acquiredLocks = 0;
                try
                {
                    // Acquire all locks
                    AcquireAllLocks(ref acquiredLocks);
               for (int i = 0; i < m_countPerLock.Length; i++) {
                  if (m_countPerLock [i] != 0) {
                     return false;
                  }
               }
            } finally {
               // Release locks that have been acquired earlier
               ReleaseLocks (0, acquiredLocks);
            }
                    for (int i = 0; i < m_countPerLock.Length; i++)
                    {
                        if (m_countPerLock[i] != 0)
                        {
                            return false;
                        }
                    }
                }
                finally
                {
                    // Release locks that have been acquired earlier
                    ReleaseLocks(0, acquiredLocks);
                }
            return true;
         }
      }
                return true;
            }
        }
      #region IDictionary<TKey,TValue> members
        #region IDictionary<TKey,TValue> members
      /// <summary>
      /// Adds the specified key and value to the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
      /// </summary>
      /// <param name="key">The object to use as the key of the element to add.</param>
      /// <param name="value">The object to use as the value of the element to add.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <exception cref="T:System.ArgumentException">
      /// An element with the same key already exists in the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.</exception>
      void IDictionary<TKey, TValue>.Add (TKey key, TValue value)
      {
         if (!TryAdd (key, value)) {
            throw new ArgumentException (GetResource ("ConcurrentDictionary_KeyAlreadyExisted"));
         }
      }
        /// <summary>
        /// Adds the specified key and value to the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
        /// </summary>
        /// <param name="key">The object to use as the key of the element to add.</param>
        /// <param name="value">The object to use as the value of the element to add.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <exception cref="T:System.ArgumentException">
        /// An element with the same key already exists in the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.</exception>
        void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
        {
            if (!TryAdd(key, value))
            {
                throw new ArgumentException(GetResource("ConcurrentDictionary_KeyAlreadyExisted"));
            }
        }
      /// <summary>
      /// Removes the element with the specified key from the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
      /// </summary>
      /// <param name="key">The key of the element to remove.</param>
      /// <returns>true if the element is successfully remove; otherwise false. This method also returns
      /// false if
      /// <paramref name="key"/> was not found in the original <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
      /// </returns>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      bool IDictionary<TKey, TValue>.Remove (TKey key)
      {
         TValue throwAwayValue;
         return TryRemove (key, out throwAwayValue);
      }
        /// <summary>
        /// Removes the element with the specified key from the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
        /// </summary>
        /// <param name="key">The key of the element to remove.</param>
        /// <returns>true if the element is successfully remove; otherwise false. This method also returns
        /// false if
        /// <paramref name="key"/> was not found in the original <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        bool IDictionary<TKey, TValue>.Remove(TKey key)
        {
            TValue throwAwayValue;
            return TryRemove(key, out throwAwayValue);
        }
      /// <summary>
      /// Gets a collection containing the keys in the <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
      /// </summary>
      /// <value>An <see cref="T:System.Collections.Generic.ICollection{TKey}"/> containing the keys in the
      /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</value>
      public ICollection<TKey> Keys {
         get { return GetKeys (); }
      }
        /// <summary>
        /// Gets a collection containing the keys in the <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
        /// </summary>
        /// <value>An <see cref="T:System.Collections.Generic.ICollection{TKey}"/> containing the keys in the
        /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</value>
        public ICollection<TKey> Keys
        {
            get { return GetKeys(); }
        }
      /// <summary>
      /// Gets a collection containing the values in the <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
      /// </summary>
      /// <value>An <see cref="T:System.Collections.Generic.ICollection{TValue}"/> containing the values in
      /// the
      /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</value>
      public ICollection<TValue> Values {
         get { return GetValues (); }
      }
        /// <summary>
        /// Gets a collection containing the values in the <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
        /// </summary>
        /// <value>An <see cref="T:System.Collections.Generic.ICollection{TValue}"/> containing the values in
        /// the
        /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</value>
        public ICollection<TValue> Values
        {
            get { return GetValues(); }
        }
      #endregion
        #endregion
      #region ICollection<KeyValuePair<TKey,TValue>> Members
        #region ICollection<KeyValuePair<TKey,TValue>> Members
      /// <summary>
      /// Adds the specified value to the <see cref="T:System.Collections.Generic.ICollection{TValue}"/>
      /// with the specified key.
      /// </summary>
      /// <param name="keyValuePair">The <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
      /// structure representing the key and value to add to the <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</param>
      /// <exception cref="T:System.ArgumentNullException">The <paramref name="keyValuePair"/> of <paramref
      /// name="keyValuePair"/> is null.</exception>
      /// <exception cref="T:System.OverflowException">The <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>
      /// contains too many elements.</exception>
      /// <exception cref="T:System.ArgumentException">An element with the same key already exists in the
      /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/></exception>
      void ICollection<KeyValuePair<TKey, TValue>>.Add (KeyValuePair<TKey, TValue> keyValuePair)
      {
         ((IDictionary<TKey, TValue>)this).Add (keyValuePair.Key, keyValuePair.Value);
      }
        /// <summary>
        /// Adds the specified value to the <see cref="T:System.Collections.Generic.ICollection{TValue}"/>
        /// with the specified key.
        /// </summary>
        /// <param name="keyValuePair">The <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
        /// structure representing the key and value to add to the <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</param>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="keyValuePair"/> of <paramref
        /// name="keyValuePair"/> is null.</exception>
        /// <exception cref="T:System.OverflowException">The <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>
        /// contains too many elements.</exception>
        /// <exception cref="T:System.ArgumentException">An element with the same key already exists in the
        /// <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/></exception>
        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
        {
            ((IDictionary<TKey, TValue>)this).Add(keyValuePair.Key, keyValuePair.Value);
        }
      /// <summary>
      /// Determines whether the <see cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/>
      /// contains a specific key and value.
      /// </summary>
      /// <param name="keyValuePair">The <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
      /// structure to locate in the <see
      /// cref="T:System.Collections.Generic.ICollection{TValue}"/>.</param>
      /// <returns>true if the <paramref name="keyValuePair"/> is found in the <see
      /// cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/>; otherwise, false.</returns>
      bool ICollection<KeyValuePair<TKey, TValue>>.Contains (KeyValuePair<TKey, TValue> keyValuePair)
      {
         TValue value;
         if (!TryGetValue (keyValuePair.Key, out value)) {
            return false;
         }
         return EqualityComparer<TValue>.Default.Equals (value, keyValuePair.Value);
      }
        /// <summary>
        /// Determines whether the <see cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/>
        /// contains a specific key and value.
        /// </summary>
        /// <param name="keyValuePair">The <see cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
        /// structure to locate in the <see
        /// cref="T:System.Collections.Generic.ICollection{TValue}"/>.</param>
        /// <returns>true if the <paramref name="keyValuePair"/> is found in the <see
        /// cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/>; otherwise, false.</returns>
        bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
        {
            TValue value;
            if (!TryGetValue(keyValuePair.Key, out value))
            {
                return false;
            }
            return EqualityComparer<TValue>.Default.Equals(value, keyValuePair.Value);
        }
      /// <summary>
      /// Gets a value indicating whether the dictionary is read-only.
      /// </summary>
      /// <value>true if the <see cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/> is
      /// read-only; otherwise, false. For <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>, this property always returns
      /// false.</value>
      bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
         get { return false; }
      }
        /// <summary>
        /// Gets a value indicating whether the dictionary is read-only.
        /// </summary>
        /// <value>true if the <see cref="T:System.Collections.Generic.ICollection{TKey,TValue}"/> is
        /// read-only; otherwise, false. For <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>, this property always returns
        /// false.</value>
        bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
        {
            get { return false; }
        }
      /// <summary>
      /// Removes a key and value from the dictionary.
      /// </summary>
      /// <param name="keyValuePair">The <see
      /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
      /// structure representing the key and value to remove from the <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</param>
      /// <returns>true if the key and value represented by <paramref name="keyValuePair"/> is successfully
      /// found and removed; otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException">The Key property of <paramref
      /// name="keyValuePair"/> is a null reference (Nothing in Visual Basic).</exception>
      bool ICollection<KeyValuePair<TKey, TValue>>.Remove (KeyValuePair<TKey, TValue> keyValuePair)
      {
         if (keyValuePair.Key == null)
            throw new ArgumentNullException (GetResource ("ConcurrentDictionary_ItemKeyIsNull"));
        /// <summary>
        /// Removes a key and value from the dictionary.
        /// </summary>
        /// <param name="keyValuePair">The <see
        /// cref="T:System.Collections.Generic.KeyValuePair{TKey,TValue}"/>
        /// structure representing the key and value to remove from the <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.</param>
        /// <returns>true if the key and value represented by <paramref name="keyValuePair"/> is successfully
        /// found and removed; otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException">The Key property of <paramref
        /// name="keyValuePair"/> is a null reference (Nothing in Visual Basic).</exception>
        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
        {
            if (keyValuePair.Key == null)
                throw new ArgumentNullException(GetResource("ConcurrentDictionary_ItemKeyIsNull"));
         TValue throwAwayValue;
         return TryRemoveInternal (keyValuePair.Key, out throwAwayValue, true, keyValuePair.Value);
      }
            TValue throwAwayValue;
            return TryRemoveInternal(keyValuePair.Key, out throwAwayValue, true, keyValuePair.Value);
        }
      #endregion
        #endregion
      #region IEnumerable Members
        #region IEnumerable Members
      /// <summary>Returns an enumerator that iterates through the <see
      /// cref="ConcurrentDictionary{TKey,TValue}"/>.</summary>
      /// <returns>An enumerator for the <see cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
      /// <remarks>
      /// The enumerator returned from the dictionary is safe to use concurrently with
      /// reads and writes to the dictionary, however it does not represent a moment-in-time snapshot
      /// of the dictionary.  The contents exposed through the enumerator may contain modifications
      /// made to the dictionary after <see cref="GetEnumerator"/> was called.
      /// </remarks>
      IEnumerator IEnumerable.GetEnumerator ()
      {
         return ((ConcurrentDictionary<TKey, TValue>)this).GetEnumerator ();
      }
        /// <summary>Returns an enumerator that iterates through the <see
        /// cref="ConcurrentDictionary{TKey,TValue}"/>.</summary>
        /// <returns>An enumerator for the <see cref="ConcurrentDictionary{TKey,TValue}"/>.</returns>
        /// <remarks>
        /// The enumerator returned from the dictionary is safe to use concurrently with
        /// reads and writes to the dictionary, however it does not represent a moment-in-time snapshot
        /// of the dictionary.  The contents exposed through the enumerator may contain modifications
        /// made to the dictionary after <see cref="GetEnumerator"/> was called.
        /// </remarks>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((ConcurrentDictionary<TKey, TValue>)this).GetEnumerator();
        }
      #endregion
        #endregion
      #region IDictionary Members
        #region IDictionary Members
      /// <summary>
      /// Adds the specified key and value to the dictionary.
      /// </summary>
      /// <param name="key">The object to use as the key.</param>
      /// <param name="value">The object to use as the value.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.OverflowException">The dictionary contains too many
      /// elements.</exception>
      /// <exception cref="T:System.ArgumentException">
      /// <paramref name="key"/> is of a type that is not assignable to the key type <typeparamref
      /// name="TKey"/> of the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>. -or-
      /// <paramref name="value"/> is of a type that is not assignable to <typeparamref name="TValue"/>,
      /// the type of values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
      /// -or- A value with the same key already exists in the <see
      /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
      /// </exception>
      void IDictionary.Add (object key, object value)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
         if (!(key is TKey))
            throw new ArgumentException (GetResource ("ConcurrentDictionary_TypeOfKeyIncorrect"));
        /// <summary>
        /// Adds the specified key and value to the dictionary.
        /// </summary>
        /// <param name="key">The object to use as the key.</param>
        /// <param name="value">The object to use as the value.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.OverflowException">The dictionary contains too many
        /// elements.</exception>
        /// <exception cref="T:System.ArgumentException">
        /// <paramref name="key"/> is of a type that is not assignable to the key type <typeparamref
        /// name="TKey"/> of the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>. -or-
        /// <paramref name="value"/> is of a type that is not assignable to <typeparamref name="TValue"/>,
        /// the type of values in the <see cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
        /// -or- A value with the same key already exists in the <see
        /// cref="T:System.Collections.Generic.Dictionary{TKey,TValue}"/>.
        /// </exception>
        void IDictionary.Add(object key, object value)
        {
            if (key == null)
                throw new ArgumentNullException("key");
            if (!(key is TKey))
                throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
         TValue typedValue;
         try {
            typedValue = (TValue)value;
         } catch (InvalidCastException) {
            throw new ArgumentException (GetResource ("ConcurrentDictionary_TypeOfValueIncorrect"));
         }
            TValue typedValue;
            try
            {
                typedValue = (TValue)value;
            }
            catch (InvalidCastException)
            {
                throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
            }
         ((IDictionary<TKey, TValue>)this).Add ((TKey)key, typedValue);
      }
            ((IDictionary<TKey, TValue>)this).Add((TKey)key, typedValue);
        }
      /// <summary>
      /// Gets whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> contains an
      /// element with the specified key.
      /// </summary>
      /// <param name="key">The key to locate in the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</param>
      /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> contains
      /// an element with the specified key; otherwise, false.</returns>
      /// <exception cref="T:System.ArgumentNullException"> <paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      bool IDictionary.Contains (object key)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Gets whether the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> contains an
        /// element with the specified key.
        /// </summary>
        /// <param name="key">The key to locate in the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</param>
        /// <returns>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> contains
        /// an element with the specified key; otherwise, false.</returns>
        /// <exception cref="T:System.ArgumentNullException"> <paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        bool IDictionary.Contains(object key)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         return (key is TKey) && ((ConcurrentDictionary<TKey, TValue>)this).ContainsKey ((TKey)key);
      }
            return (key is TKey) && ((ConcurrentDictionary<TKey, TValue>)this).ContainsKey((TKey)key);
        }
      /// <summary>Provides an <see cref="T:System.Collections.Generics.IDictionaryEnumerator"/> for the
      /// <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</summary>
      /// <returns>An <see cref="T:System.Collections.Generics.IDictionaryEnumerator"/> for the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</returns>
      IDictionaryEnumerator IDictionary.GetEnumerator ()
      {
         return new DictionaryEnumerator (this);
      }
        /// <summary>Provides an <see cref="T:System.Collections.Generics.IDictionaryEnumerator"/> for the
        /// <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</summary>
        /// <returns>An <see cref="T:System.Collections.Generics.IDictionaryEnumerator"/> for the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</returns>
        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            return new DictionaryEnumerator(this);
        }
      /// <summary>
      /// Gets a value indicating whether the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> has a fixed size.
      /// </summary>
      /// <value>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> has a
      /// fixed size; otherwise, false. For <see
      /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>, this property always
      /// returns false.</value>
      bool IDictionary.IsFixedSize {
         get { return false; }
      }
        /// <summary>
        /// Gets a value indicating whether the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> has a fixed size.
        /// </summary>
        /// <value>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> has a
        /// fixed size; otherwise, false. For <see
        /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>, this property always
        /// returns false.</value>
        bool IDictionary.IsFixedSize
        {
            get { return false; }
        }
      /// <summary>
      /// Gets a value indicating whether the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> is read-only.
      /// </summary>
      /// <value>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> is
      /// read-only; otherwise, false. For <see
      /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>, this property always
      /// returns false.</value>
      bool IDictionary.IsReadOnly {
         get { return false; }
      }
        /// <summary>
        /// Gets a value indicating whether the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> is read-only.
        /// </summary>
        /// <value>true if the <see cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/> is
        /// read-only; otherwise, false. For <see
        /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>, this property always
        /// returns false.</value>
        bool IDictionary.IsReadOnly
        {
            get { return false; }
        }
      /// <summary>
      /// Gets an <see cref="T:System.Collections.ICollection"/> containing the keys of the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
      /// </summary>
      /// <value>An <see cref="T:System.Collections.ICollection"/> containing the keys of the <see
      /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</value>
      ICollection IDictionary.Keys {
         get { return GetKeys (); }
      }
        /// <summary>
        /// Gets an <see cref="T:System.Collections.ICollection"/> containing the keys of the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.
        /// </summary>
        /// <value>An <see cref="T:System.Collections.ICollection"/> containing the keys of the <see
        /// cref="T:System.Collections.Generic.IDictionary{TKey,TValue}"/>.</value>
        ICollection IDictionary.Keys
        {
            get { return GetKeys(); }
        }
      /// <summary>
      /// Removes the element with the specified key from the <see
      /// cref="T:System.Collections.IDictionary"/>.
      /// </summary>
      /// <param name="key">The key of the element to remove.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      void IDictionary.Remove (object key)
      {
         if (key == null)
            throw new ArgumentNullException ("key");
        /// <summary>
        /// Removes the element with the specified key from the <see
        /// cref="T:System.Collections.IDictionary"/>.
        /// </summary>
        /// <param name="key">The key of the element to remove.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        void IDictionary.Remove(object key)
        {
            if (key == null)
                throw new ArgumentNullException("key");
         TValue throwAwayValue;
         if (key is TKey) {
            this.TryRemove ((TKey)key, out throwAwayValue);
         }
      }
            TValue throwAwayValue;
            if (key is TKey)
            {
                this.TryRemove((TKey)key, out throwAwayValue);
            }
        }
      /// <summary>
      /// Gets an <see cref="T:System.Collections.ICollection"/> containing the values in the <see
      /// cref="T:System.Collections.IDictionary"/>.
      /// </summary>
      /// <value>An <see cref="T:System.Collections.ICollection"/> containing the values in the <see
      /// cref="T:System.Collections.IDictionary"/>.</value>
      ICollection IDictionary.Values {
         get { return GetValues (); }
      }
        /// <summary>
        /// Gets an <see cref="T:System.Collections.ICollection"/> containing the values in the <see
        /// cref="T:System.Collections.IDictionary"/>.
        /// </summary>
        /// <value>An <see cref="T:System.Collections.ICollection"/> containing the values in the <see
        /// cref="T:System.Collections.IDictionary"/>.</value>
        ICollection IDictionary.Values
        {
            get { return GetValues(); }
        }
      /// <summary>
      /// Gets or sets the value associated with the specified key.
      /// </summary>
      /// <param name="key">The key of the value to get or set.</param>
      /// <value>The value associated with the specified key, or a null reference (Nothing in Visual Basic)
      /// if <paramref name="key"/> is not in the dictionary or <paramref name="key"/> is of a type that is
      /// not assignable to the key type <typeparamref name="TKey"/> of the <see
      /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>.</value>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentException">
      /// A value is being assigned, and <paramref name="key"/> is of a type that is not assignable to the
      /// key type <typeparamref name="TKey"/> of the <see
      /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>. -or- A value is being
      /// assigned, and <paramref name="key"/> is of a type that is not assignable to the value type
      /// <typeparamref name="TValue"/> of the <see
      /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>
      /// </exception>
      object IDictionary.this [object key] {
         get {
            if (key == null)
               throw new ArgumentNullException ("key");
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <param name="key">The key of the value to get or set.</param>
        /// <value>The value associated with the specified key, or a null reference (Nothing in Visual Basic)
        /// if <paramref name="key"/> is not in the dictionary or <paramref name="key"/> is of a type that is
        /// not assignable to the key type <typeparamref name="TKey"/> of the <see
        /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>.</value>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="key"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException">
        /// A value is being assigned, and <paramref name="key"/> is of a type that is not assignable to the
        /// key type <typeparamref name="TKey"/> of the <see
        /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>. -or- A value is being
        /// assigned, and <paramref name="key"/> is of a type that is not assignable to the value type
        /// <typeparamref name="TValue"/> of the <see
        /// cref="T:System.Collections.Generic.ConcurrentDictionary{TKey,TValue}"/>
        /// </exception>
        object IDictionary.this[object key]
        {
            get
            {
                if (key == null)
                    throw new ArgumentNullException("key");
            TValue value;
            if (key is TKey && this.TryGetValue ((TKey)key, out value)) {
               return value;
            }
                TValue value;
                if (key is TKey && this.TryGetValue((TKey)key, out value))
                {
                    return value;
                }
            return null;
         }
         set {
            if (key == null)
               throw new ArgumentNullException ("key");
                return null;
            }
            set
            {
                if (key == null)
                    throw new ArgumentNullException("key");
            if (!(key is TKey))
               throw new ArgumentException (GetResource ("ConcurrentDictionary_TypeOfKeyIncorrect"));
            if (!(value is TValue))
               throw new ArgumentException (GetResource ("ConcurrentDictionary_TypeOfValueIncorrect"));
                if (!(key is TKey))
                    throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
                if (!(value is TValue))
                    throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
            ((ConcurrentDictionary<TKey, TValue>)this) [(TKey)key] = (TValue)value;
         }
      }
                ((ConcurrentDictionary<TKey, TValue>)this)[(TKey)key] = (TValue)value;
            }
        }
      #endregion
        #endregion
      #region ICollection Members
        #region ICollection Members
      /// <summary>
      /// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an array, starting
      /// at the specified array index.
      /// </summary>
      /// <param name="array">The one-dimensional array that is the destination of the elements copied from
      /// the <see cref="T:System.Collections.ICollection"/>. The array must have zero-based
      /// indexing.</param>
      /// <param name="index">The zero-based index in <paramref name="array"/> at which copying
      /// begins.</param>
      /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference
      /// (Nothing in Visual Basic).</exception>
      /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than
      /// 0.</exception>
      /// <exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than
      /// the length of the <paramref name="array"/>. -or- The number of elements in the source <see
      /// cref="T:System.Collections.ICollection"/>
      /// is greater than the available space from <paramref name="index"/> to the end of the destination
      /// <paramref name="array"/>.</exception>
      void ICollection.CopyTo (Array array, int index)
      {
         if (array == null)
            throw new ArgumentNullException ("array");
         if (index < 0)
            throw new ArgumentOutOfRangeException ("index", GetResource ("ConcurrentDictionary_IndexIsNegative"));
        /// <summary>
        /// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an array, starting
        /// at the specified array index.
        /// </summary>
        /// <param name="array">The one-dimensional array that is the destination of the elements copied from
        /// the <see cref="T:System.Collections.ICollection"/>. The array must have zero-based
        /// indexing.</param>
        /// <param name="index">The zero-based index in <paramref name="array"/> at which copying
        /// begins.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than
        /// 0.</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than
        /// the length of the <paramref name="array"/>. -or- The number of elements in the source <see
        /// cref="T:System.Collections.ICollection"/>
        /// is greater than the available space from <paramref name="index"/> to the end of the destination
        /// <paramref name="array"/>.</exception>
        void ICollection.CopyTo(Array array, int index)
        {
            if (array == null)
                throw new ArgumentNullException("array");
            if (index < 0)
                throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative"));
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
            int count = 0;
                int count = 0;
            for (int i = 0; i < m_locks.Length; i++) {
               count += m_countPerLock [i];
            }
                for (int i = 0; i < m_locks.Length; i++)
                {
                    count += m_countPerLock[i];
                }
            if (array.Length - count < index || count < 0) { //"count" itself or "count + index" can overflow
               throw new ArgumentException (GetResource ("ConcurrentDictionary_ArrayNotLargeEnough"));
            }
                if (array.Length - count < index || count < 0)
                { //"count" itself or "count + index" can overflow
                    throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough"));
                }
            // To be consistent with the behavior of ICollection.CopyTo() in Dictionary<TKey,TValue>,
            // we recognize three types of target arrays:
            //    - an array of KeyValuePair<TKey, TValue> structs
            //    - an array of DictionaryEntry structs
            //    - an array of objects
                // To be consistent with the behavior of ICollection.CopyTo() in Dictionary<TKey,TValue>,
                // we recognize three types of target arrays:
                //    - an array of KeyValuePair<TKey, TValue> structs
                //    - an array of DictionaryEntry structs
                //    - an array of objects
            KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
            if (pairs != null) {
               CopyToPairs (pairs, index);
               return;
            }
                KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
                if (pairs != null)
                {
                    CopyToPairs(pairs, index);
                    return;
                }
            DictionaryEntry[] entries = array as DictionaryEntry[];
            if (entries != null) {
               CopyToEntries (entries, index);
               return;
            }
                DictionaryEntry[] entries = array as DictionaryEntry[];
                if (entries != null)
                {
                    CopyToEntries(entries, index);
                    return;
                }
            object[] objects = array as object[];
            if (objects != null) {
               CopyToObjects (objects, index);
               return;
            }
                object[] objects = array as object[];
                if (objects != null)
                {
                    CopyToObjects(objects, index);
                    return;
                }
            throw new ArgumentException (GetResource ("ConcurrentDictionary_ArrayIncorrectType"), "array");
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayIncorrectType"), "array");
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is
      /// synchronized with the SyncRoot.
      /// </summary>
      /// <value>true if access to the <see cref="T:System.Collections.ICollection"/> is synchronized
      /// (thread safe); otherwise, false. For <see
      /// cref="T:System.Collections.Concurrent.ConcurrentDictionary{TKey,TValue}"/>, this property always
      /// returns false.</value>
      bool ICollection.IsSynchronized {
         get { return false; }
      }
        /// <summary>
        /// Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is
        /// synchronized with the SyncRoot.
        /// </summary>
        /// <value>true if access to the <see cref="T:System.Collections.ICollection"/> is synchronized
        /// (thread safe); otherwise, false. For <see
        /// cref="T:System.Collections.Concurrent.ConcurrentDictionary{TKey,TValue}"/>, this property always
        /// returns false.</value>
        bool ICollection.IsSynchronized
        {
            get { return false; }
        }
      /// <summary>
      /// Gets an object that can be used to synchronize access to the <see
      /// cref="T:System.Collections.ICollection"/>. This property is not supported.
      /// </summary>
      /// <exception cref="T:System.NotSupportedException">The SyncRoot property is not supported.</exception>
      object ICollection.SyncRoot {
         get {
            throw new NotSupportedException ();
         }
      }
        /// <summary>
        /// Gets an object that can be used to synchronize access to the <see
        /// cref="T:System.Collections.ICollection"/>. This property is not supported.
        /// </summary>
        /// <exception cref="T:System.NotSupportedException">The SyncRoot property is not supported.</exception>
        object ICollection.SyncRoot
        {
            get
            {
                throw new NotSupportedException();
            }
        }
      #endregion
        #endregion
      /// <summary>
      /// Replaces the internal table with a larger one. To prevent multiple threads from resizing the
      /// table as a result of ----s, the table of buckets that was deemed too small is passed in as
      /// an argument to GrowTable(). GrowTable() obtains a lock, and then checks whether the bucket
      /// table has been replaced in the meantime or not.
      /// </summary>
      /// <param name="buckets">Reference to the bucket table that was deemed too small.</param>
      private void GrowTable (Node[] buckets)
      {
         int locksAcquired = 0;
         try {
            // The thread that first obtains m_locks[0] will be the one doing the resize operation
            AcquireLocks (0, 1, ref locksAcquired);
        /// <summary>
        /// Replaces the internal table with a larger one. To prevent multiple threads from resizing the
        /// table as a result of ----s, the table of buckets that was deemed too small is passed in as
        /// an argument to GrowTable(). GrowTable() obtains a lock, and then checks whether the bucket
        /// table has been replaced in the meantime or not.
        /// </summary>
        /// <param name="buckets">Reference to the bucket table that was deemed too small.</param>
        private void GrowTable(Node[] buckets)
        {
            int locksAcquired = 0;
            try
            {
                // The thread that first obtains m_locks[0] will be the one doing the resize operation
                AcquireLocks(0, 1, ref locksAcquired);
            // Make sure nobody resized the table while we were waiting for lock 0:
            if (buckets != m_buckets) {
               // We assume that since the table reference is different, it was already resized. If we ever
               // decide to do table shrinking, or replace the table for other reasons, we will have to revisit
               // this logic.
               return;
            }
                // Make sure nobody resized the table while we were waiting for lock 0:
                if (buckets != m_buckets)
                {
                    // We assume that since the table reference is different, it was already resized. If we ever
                    // decide to do table shrinking, or replace the table for other reasons, we will have to revisit
                    // this logic.
                    return;
                }
            // Compute the new table size. We find the smallest integer larger than twice the previous table size, and not divisible by
            // 2,3,5 or 7. We can consider a different table-sizing policy in the future.
            int newLength;
            try {
               checked {
                  // Double the size of the buckets table and add one, so that we have an odd integer.
                  newLength = buckets.Length * 2 + 1;
                // Compute the new table size. We find the smallest integer larger than twice the previous table size, and not divisible by
                // 2,3,5 or 7. We can consider a different table-sizing policy in the future.
                int newLength;
                try
                {
                    checked
                    {
                        // Double the size of the buckets table and add one, so that we have an odd integer.
                        newLength = buckets.Length * 2 + 1;
                  // Now, we only need to check odd integers, and find the first that is not divisible
                  // by 3, 5 or 7.
                  while (newLength % 3 == 0 || newLength % 5 == 0 || newLength % 7 == 0) {
                     newLength += 2;
                  }
                        // Now, we only need to check odd integers, and find the first that is not divisible
                        // by 3, 5 or 7.
                        while (newLength % 3 == 0 || newLength % 5 == 0 || newLength % 7 == 0)
                        {
                            newLength += 2;
                        }
                  Assert (newLength % 2 != 0);
               }
            } catch (OverflowException) {
               // If we were to resize the table, its new size will not fit into a 32-bit signed int. Just return.
               return;
            }
                        Assert(newLength % 2 != 0);
                    }
                }
                catch (OverflowException)
                {
                    // If we were to resize the table, its new size will not fit into a 32-bit signed int. Just return.
                    return;
                }
            Node[] newBuckets = new Node[newLength];
            int[] newCountPerLock = new int[m_locks.Length];
                Node[] newBuckets = new Node[newLength];
                int[] newCountPerLock = new int[m_locks.Length];
            // Now acquire all other locks for the table
            AcquireLocks (1, m_locks.Length, ref locksAcquired);
                // Now acquire all other locks for the table
                AcquireLocks(1, m_locks.Length, ref locksAcquired);
            // Copy all data into a new table, creating new nodes for all elements
            for (int i = 0; i < buckets.Length; i++) {
               Node current = buckets [i];
               while (current != null) {
                  Node next = current.m_next;
                  int newBucketNo, newLockNo;
                  GetBucketAndLockNo (current.m_hashcode, out newBucketNo, out newLockNo, newBuckets.Length);
                // Copy all data into a new table, creating new nodes for all elements
                for (int i = 0; i < buckets.Length; i++)
                {
                    Node current = buckets[i];
                    while (current != null)
                    {
                        Node next = current.m_next;
                        int newBucketNo, newLockNo;
                        GetBucketAndLockNo(current.m_hashcode, out newBucketNo, out newLockNo, newBuckets.Length);
                  newBuckets [newBucketNo] = new Node (current.m_key, current.m_value, current.m_hashcode, newBuckets [newBucketNo]);
                        newBuckets[newBucketNo] = new Node(current.m_key, current.m_value, current.m_hashcode, newBuckets[newBucketNo]);
                  checked {
                     newCountPerLock [newLockNo]++;
                  }
                        checked
                        {
                            newCountPerLock[newLockNo]++;
                        }
                  current = next;
               }
            }
                        current = next;
                    }
                }
            // And finally adjust m_buckets and m_countPerLock to point to data for the new table
            m_buckets = newBuckets;
            m_countPerLock = newCountPerLock;
                // And finally adjust m_buckets and m_countPerLock to point to data for the new table
                m_buckets = newBuckets;
                m_countPerLock = newCountPerLock;
         } finally {
            // Release all locks that we took earlier
            ReleaseLocks (0, locksAcquired);
         }
      }
            }
            finally
            {
                // Release all locks that we took earlier
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Computes the bucket and lock number for a particular key.
      /// </summary>
      private void GetBucketAndLockNo (
         int hashcode, out int bucketNo, out int lockNo, int bucketCount)
      {
         bucketNo = (hashcode & 0x7fffffff) % bucketCount;
         lockNo = bucketNo % m_locks.Length;
        /// <summary>
        /// Computes the bucket and lock number for a particular key.
        /// </summary>
        private void GetBucketAndLockNo(
            int hashcode, out int bucketNo, out int lockNo, int bucketCount)
        {
            bucketNo = (hashcode & 0x7fffffff) % bucketCount;
            lockNo = bucketNo % m_locks.Length;
         Assert (bucketNo >= 0 && bucketNo < bucketCount);
         Assert (lockNo >= 0 && lockNo < m_locks.Length);
      }
            Assert(bucketNo >= 0 && bucketNo < bucketCount);
            Assert(lockNo >= 0 && lockNo < m_locks.Length);
        }
      /// <summary>
      /// The number of concurrent writes for which to optimize by default.
      /// </summary>
      private static int DefaultConcurrencyLevel {
        /// <summary>
        /// The number of concurrent writes for which to optimize by default.
        /// </summary>
        private static int DefaultConcurrencyLevel
        {
         get { return DEFAULT_CONCURRENCY_MULTIPLIER * Environment.ProcessorCount; }
      }
            get { return DEFAULT_CONCURRENCY_MULTIPLIER * Environment.ProcessorCount; }
        }
      /// <summary>
      /// Acquires all locks for this hash table, and increments locksAcquired by the number
      /// of locks that were successfully acquired. The locks are acquired in an increasing
      /// order.
      /// </summary>
      private void AcquireAllLocks (ref int locksAcquired)
      {
         AcquireLocks (0, m_locks.Length, ref locksAcquired);
         Assert (locksAcquired == m_locks.Length);
      }
        /// <summary>
        /// Acquires all locks for this hash table, and increments locksAcquired by the number
        /// of locks that were successfully acquired. The locks are acquired in an increasing
        /// order.
        /// </summary>
        private void AcquireAllLocks(ref int locksAcquired)
        {
            AcquireLocks(0, m_locks.Length, ref locksAcquired);
            Assert(locksAcquired == m_locks.Length);
        }
      /// <summary>
      /// Acquires a contiguous range of locks for this hash table, and increments locksAcquired
      /// by the number of locks that were successfully acquired. The locks are acquired in an
      /// increasing order.
      /// </summary>
      private void AcquireLocks (int fromInclusive, int toExclusive, ref int locksAcquired)
      {
         Assert (fromInclusive <= toExclusive);
        /// <summary>
        /// Acquires a contiguous range of locks for this hash table, and increments locksAcquired
        /// by the number of locks that were successfully acquired. The locks are acquired in an
        /// increasing order.
        /// </summary>
        private void AcquireLocks(int fromInclusive, int toExclusive, ref int locksAcquired)
        {
            Assert(fromInclusive <= toExclusive);
         for (int i = fromInclusive; i < toExclusive; i++) {
            bool lockTaken = false;
            try {
               Monitor.Enter (m_locks [i]);
               lockTaken = true;
            } finally {
               if (lockTaken) {
                  locksAcquired++;
               }
            }
         }
      }
            for (int i = fromInclusive; i < toExclusive; i++)
            {
                bool lockTaken = false;
                try
                {
                    Monitor.Enter(m_locks[i]);
                    lockTaken = true;
                }
                finally
                {
                    if (lockTaken)
                    {
                        locksAcquired++;
                    }
                }
            }
        }
      /// <summary>
      /// Releases a contiguous range of locks.
      /// </summary>
      private void ReleaseLocks (int fromInclusive, int toExclusive)
      {
         Assert (fromInclusive <= toExclusive);
        /// <summary>
        /// Releases a contiguous range of locks.
        /// </summary>
        private void ReleaseLocks(int fromInclusive, int toExclusive)
        {
            Assert(fromInclusive <= toExclusive);
         for (int i = fromInclusive; i < toExclusive; i++) {
            Monitor.Exit (m_locks [i]);
         }
      }
            for (int i = fromInclusive; i < toExclusive; i++)
            {
                Monitor.Exit(m_locks[i]);
            }
        }
      /// <summary>
      /// Gets a collection containing the keys in the dictionary.
      /// </summary>
      private ReadOnlyCollection<TKey> GetKeys ()
      {
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
            List<TKey> keys = new List<TKey> ();
        /// <summary>
        /// Gets a collection containing the keys in the dictionary.
        /// </summary>
        private ReadOnlyCollection<TKey> GetKeys()
        {
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
                List<TKey> keys = new List<TKey>();
            for (int i = 0; i < m_buckets.Length; i++) {
               Node current = m_buckets [i];
               while (current != null) {
                  keys.Add (current.m_key);
                  current = current.m_next;
               }
            }
                for (int i = 0; i < m_buckets.Length; i++)
                {
                    Node current = m_buckets[i];
                    while (current != null)
                    {
                        keys.Add(current.m_key);
                        current = current.m_next;
                    }
                }
            return new ReadOnlyCollection<TKey> (keys);
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                return new ReadOnlyCollection<TKey>(keys);
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// Gets a collection containing the values in the dictionary.
      /// </summary>
      private ReadOnlyCollection<TValue> GetValues ()
      {
         int locksAcquired = 0;
         try {
            AcquireAllLocks (ref locksAcquired);
            List<TValue> values = new List<TValue> ();
        /// <summary>
        /// Gets a collection containing the values in the dictionary.
        /// </summary>
        private ReadOnlyCollection<TValue> GetValues()
        {
            int locksAcquired = 0;
            try
            {
                AcquireAllLocks(ref locksAcquired);
                List<TValue> values = new List<TValue>();
            for (int i = 0; i < m_buckets.Length; i++) {
               Node current = m_buckets [i];
               while (current != null) {
                  values.Add (current.m_value);
                  current = current.m_next;
               }
            }
                for (int i = 0; i < m_buckets.Length; i++)
                {
                    Node current = m_buckets[i];
                    while (current != null)
                    {
                        values.Add(current.m_value);
                        current = current.m_next;
                    }
                }
            return new ReadOnlyCollection<TValue> (values);
         } finally {
            ReleaseLocks (0, locksAcquired);
         }
      }
                return new ReadOnlyCollection<TValue>(values);
            }
            finally
            {
                ReleaseLocks(0, locksAcquired);
            }
        }
      /// <summary>
      /// A helper method for asserts.
      /// </summary>
      [Conditional ("DEBUG")]
      private void Assert (bool condition)
      {
         if (!condition) {
            throw new Exception ("Assertion failed.");
         }
      }
        /// <summary>
        /// A helper method for asserts.
        /// </summary>
        [Conditional("DEBUG")]
        private void Assert(bool condition)
        {
            if (!condition)
            {
                throw new Exception("Assertion failed.");
            }
        }
      /// <summary>
      /// A helper function to obtain the string for a particular resource key.
      /// </summary>
      /// <param name="key"></param>
      /// <returns></returns>
      private string GetResource (string key)
      {
         Assert (key != null);
        /// <summary>
        /// A helper function to obtain the string for a particular resource key.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private string GetResource(string key)
        {
            Assert(key != null);
         return key;
      }
            return key;
        }
      /// <summary>
      /// A node in a singly-linked list representing a particular hash table bucket.
      /// </summary>
      private class Node
      {
         internal TKey m_key;
         internal TValue m_value;
         internal volatile Node m_next;
         internal int m_hashcode;
        /// <summary>
        /// A node in a singly-linked list representing a particular hash table bucket.
        /// </summary>
        private class Node
        {
            internal TKey m_key;
            internal TValue m_value;
            internal volatile Node m_next;
            internal int m_hashcode;
         internal Node (TKey key, TValue value, int hashcode)
            : this (key, value, hashcode, null)
         {
         }
            internal Node(TKey key, TValue value, int hashcode)
                : this(key, value, hashcode, null)
            {
            }
         internal Node (TKey key, TValue value, int hashcode, Node next)
         {
            m_key = key;
            m_value = value;
            m_next = next;
            m_hashcode = hashcode;
         }
      }
            internal Node(TKey key, TValue value, int hashcode, Node next)
            {
                m_key = key;
                m_value = value;
                m_next = next;
                m_hashcode = hashcode;
            }
        }
      /// <summary>
      /// A private class to represent enumeration over the dictionary that implements the
      /// IDictionaryEnumerator interface.
      /// </summary>
      private class DictionaryEnumerator : IDictionaryEnumerator
      {
         IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
         // Enumerator over the dictionary.
        /// <summary>
        /// A private class to represent enumeration over the dictionary that implements the
        /// IDictionaryEnumerator interface.
        /// </summary>
        private class DictionaryEnumerator : IDictionaryEnumerator
        {
            IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
            // Enumerator over the dictionary.
         internal DictionaryEnumerator (ConcurrentDictionary<TKey, TValue> dictionary)
         {
            m_enumerator = dictionary.GetEnumerator ();
         }
            internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary)
            {
                m_enumerator = dictionary.GetEnumerator();
            }
         public DictionaryEntry Entry {
            get { return new DictionaryEntry (m_enumerator.Current.Key, m_enumerator.Current.Value); }
         }
            public DictionaryEntry Entry
            {
                get { return new DictionaryEntry(m_enumerator.Current.Key, m_enumerator.Current.Value); }
            }
         public object Key {
            get { return m_enumerator.Current.Key; }
         }
            public object Key
            {
                get { return m_enumerator.Current.Key; }
            }
         public object Value {
            get { return m_enumerator.Current.Value; }
         }
            public object Value
            {
                get { return m_enumerator.Current.Value; }
            }
         public object Current {
            get { return this.Entry; }
         }
            public object Current
            {
                get { return this.Entry; }
            }
         public bool MoveNext ()
         {
            return m_enumerator.MoveNext ();
         }
            public bool MoveNext()
            {
                return m_enumerator.MoveNext();
            }
         public void Reset ()
         {
            m_enumerator.Reset ();
         }
      }
            public void Reset()
            {
                m_enumerator.Reset();
            }
        }
      /// <summary>
      /// Get the data array to be serialized
      /// </summary>
      [OnSerializing]
      private void OnSerializing (StreamingContext context)
      {
         // save the data into the serialization array to be saved
         m_serializationArray = ToArray ();
         m_serializationConcurrencyLevel = m_locks.Length;
         m_serializationCapacity = m_buckets.Length;
      }
        /// <summary>
        /// Get the data array to be serialized
        /// </summary>
        [OnSerializing]
        private void OnSerializing(StreamingContext context)
        {
            // save the data into the serialization array to be saved
            m_serializationArray = ToArray();
            m_serializationConcurrencyLevel = m_locks.Length;
            m_serializationCapacity = m_buckets.Length;
        }
      /// <summary>
      /// Construct the dictionary from a previously seiralized one
      /// </summary>
      [OnDeserialized]
      private void OnDeserialized (StreamingContext context)
      {
         KeyValuePair<TKey, TValue>[] array = m_serializationArray;
        /// <summary>
        /// Construct the dictionary from a previously seiralized one
        /// </summary>
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            KeyValuePair<TKey, TValue>[] array = m_serializationArray;
         m_buckets = new Node[m_serializationCapacity];
         m_countPerLock = new int[m_serializationConcurrencyLevel];
            m_buckets = new Node[m_serializationCapacity];
            m_countPerLock = new int[m_serializationConcurrencyLevel];
         m_locks = new object[m_serializationConcurrencyLevel];
         for (int i = 0; i < m_locks.Length; i++) {
            m_locks [i] = new object ();
         }
            m_locks = new object[m_serializationConcurrencyLevel];
            for (int i = 0; i < m_locks.Length; i++)
            {
                m_locks[i] = new object();
            }
         InitializeFromCollection (array);
         m_serializationArray = null;
            InitializeFromCollection(array);
            m_serializationArray = null;
      }
   }
        }
    }
}
#endif