/// <summary>
        /// Constructs a hash table with the specified capacity
        /// </summary>
        public HashTable(int initialCapacity)
        {
            if (initialCapacity < 1)
            {
                throw new ArgumentOutOfRangeException("initialCapacity");
            }

            _array = new HashTableArray <TKey, TValue>(initialCapacity);

            // when the count exceeds this value, the next Add will cause the
            // array to grow
            _maxItemsAtCurrentSize = (int)(initialCapacity * _fillFactor) + 1;
        }
        /// <summary>
        /// Adds the key/value pair to the hash table.  If the key already exists in the
        /// hash table an ArgumentException will be thrown
        /// </summary>
        /// <param name="key">The key of the item being added</param>
        /// <param name="value">The value of the item being added</param>
        public void Add(TKey key, TValue value)
        {
            // if we are at capacity, the array needs to grow
            if (_count >= _maxItemsAtCurrentSize)
            {
                // allocate a larger array
                HashTableArray <TKey, TValue> largerArray = new HashTableArray <TKey, TValue>(_array.Capacity * 2);

                // and re-add each item to the new array
                foreach (HashTableNodePair <TKey, TValue> node in _array.Items)
                {
                    largerArray.Add(node.Key, node.Value);
                }

                // the larger array is now the hash table storage
                _array = largerArray;

                // update the new max items cached value
                _maxItemsAtCurrentSize = (int)(_array.Capacity * _fillFactor) + 1;
            }

            _array.Add(key, value);
            _count++;
        }