/// <summary>
        /// Inserts a key value association into the dictionary.
        /// </summary>
        /// <param name="key">The key to identify the value with.</param>
        /// <param name="value">The value to associate the key with.</param>
        /// <exception cref="ArgumentNullException">Gets raised when the <paramref name="value"/> parameter is null.</exception>
        public void Insert(TKey key, TValue value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var item = new ConcurrentWeakDictionaryStrongKeysItem <TKey>(GetHashCode(key), key, new WeakReference(value));
            ConcurrentWeakDictionaryStrongKeysItem <TKey> oldItem;

            base.InsertItem(ref item, out oldItem);
        }
        /// <summary>
        /// Retrieves an existing value associated with the specified key or, if it can't be found, associates a specified value with the key and returns that later value.
        /// </summary>
        /// <param name="key">The key to find an existing value with or, if it can't be found, insert a new value with.</param>
        /// <param name="newValue">The new value to insert if an existing associated value can not be found in the dictionary.</param>
        /// <returns>The existing value if it can be found; otherwise the newly inserted value.</returns>
        /// <exception cref="ArgumentNullException">Gets raised when the <paramref name="newValue"/> parameter is null.</exception>
        public TValue GetOldest(TKey key, TValue newValue)
        {
            if (newValue == null)
            {
                throw new ArgumentNullException("newValue");
            }

            var item = new ConcurrentWeakDictionaryStrongKeysItem <TKey>(GetHashCode(key), key, new WeakReference(newValue));
            ConcurrentWeakDictionaryStrongKeysItem <TKey> oldItem;
            TValue res;

            do
            {
                if (!base.GetOldestItem(ref item, out oldItem))
                {
                    return(newValue);
                }

                res = (TValue)oldItem._Value.Target;
            }while (res == null);

            return(res);
        }
 protected internal override Type GetKeyType(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item)
 {
     return(item._Key == null ? null : item._Key.GetType());
 }
 /// <summary>
 /// Indicates if a specific content item should be treated as garbage and removed.
 /// </summary>
 /// <param name="item">The item to judge.</param>
 /// <returns>A boolean value that is true if the item is not empty and should be treated as garbage; false otherwise.</returns>
 internal protected override bool IsGarbage(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item)
 {
     return(item._Value != null && item._Value.Target == null);
 }
 /// <summary>
 /// Indicates if a specific item reference contains a valid item.
 /// </summary>
 /// <param name="item">The storeable item reference to check.</param>
 /// <returns>True if the reference doesn't refer to a valid item; false otherwise.</returns>
 /// <remarks>The statement <code>IsEmpty(default(TStoredI))</code> should always be true.</remarks>
 internal protected override bool IsEmpty(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item)
 {
     return(item._Value == null);
 }
 /// <summary>
 /// Compares two storeable items for equality.
 /// </summary>
 /// <param name="item1">Reference to the first storeable item to compare.</param>
 /// <param name="item2">Reference to the second storeable item to compare.</param>
 /// <returns>True if the two soreable items should be regarded as equal.</returns>
 internal protected override bool ItemEqualsItem(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item1, ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item2)
 {
     return(_Comparer.Equals(item1._Key, item2._Key));
 }
 /// <summary>
 /// Compares a storeable item to a search key. Should return true if they match.
 /// </summary>
 /// <param name="item">Reference to the storeable item to compare.</param>
 /// <param name="key">Reference to the search key to compare.</param>
 /// <returns>True if the storeable item and search key match; false otherwise.</returns>
 internal protected override bool ItemEqualsKey(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item, ref ConcurrentWeakDictionaryStrongKeysKey <TKey> key)
 {
     return(_Comparer.Equals(item._Key, key._Key));
 }
 /// <summary>
 /// Get a hashcode for given storeable item.
 /// </summary>
 /// <param name="item">Reference to the item to get a hash value for.</param>
 /// <returns>The hash value as an <see cref="UInt32"/>.</returns>
 /// <remarks>
 /// The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
 /// A storeable item and a matching search key should return the same hash code.
 /// So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
 /// </remarks>
 internal protected override UInt32 GetItemHashCode(ref ConcurrentWeakDictionaryStrongKeysItem <TKey> item)
 {
     return(item._Hash);
 }