/// <summary>
        /// Returns a task that completes when the write lock for the specified <paramref name="key"/> has been aquired.
        /// The aquired Releaser must be disposed to release the write lock.
        /// </summary>
        /// <returns></returns>
        public Task <Releaser> WriterLockAsync(TKey key)
        {
            //Get or create the lock for this key
            AsyncReaderWriterWrapper wrapper = GetLockForKeyAndIncrement(key);

            //Obtain the write lock
            return(wrapper.Lock.WriterLockAsync().ContinueWith(t => new Releaser(key, this, t.Result)));
        }
        /// <summary>
        /// Gets or creates the <see cref="AsyncReaderWriterWrapper"/> for the specified <paramref name="key"/> and increments the number
        /// of references to the <see cref="AsyncReaderWriterWrapper"/>.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected AsyncReaderWriterWrapper GetLockForKeyAndIncrement(TKey key)
        {
            lock (_syncObj)
            {
                AsyncReaderWriterWrapper wrapper;
                if (!_locks.TryGetValue(key, out wrapper))
                {
                    _locks[key] = wrapper = new AsyncReaderWriterWrapper();
                }
                else if (wrapper.ReferenceCount == 0)
                {
                    _unusedKeys.Remove(key);
                }

                wrapper.ReferenceCount++;
                return(wrapper);
            }
        }