/// <summary>
        /// Acquires a lock of the specified type and returns an opaque lock object
        /// that will release the lock when disposed.
        ///
        /// <code>using (blocks.AcquireLock(RequestLock.Read)) {}</code>
        /// </summary>
        /// <returns>An opaque lock object that will release lock on disposal.</returns>
        public IDisposable AcquireLock(RequestLock requestLock)
        {
            // Acquire the lock based on the requested type.
            IDisposable acquiredLock;

            switch (requestLock)
            {
            case RequestLock.Read:
                acquiredLock = new NestableReadLock(accessLock);
                break;

            case RequestLock.UpgradableRead:
                acquiredLock = new NestableUpgradableReadLock(accessLock);
                break;

            case RequestLock.Write:
                acquiredLock = new NestableWriteLock(accessLock);
                break;

            default:
                throw new InvalidOperationException(
                          "Could not acquire lock with unknown type: " + requestLock);
            }

            // Return the resulting lock.
            return(acquiredLock);
        }
        /// <summary>
        /// Acquires a read lock on both the block and the block collection.
        /// </summary>
        /// <param name="collectionLock">The lock on the block collection.</param>
        /// <param name="blockLock">The lock object used to acquire the lock.</param>
        /// <param name="requestLock"></param>
        public BlockLock(
            IDisposable collectionLock,
            ReaderWriterLockSlim accessLock,
            RequestLock requestLock)
        {
            // Keep track of the collection lock so we can release it.
            this.collectionLock = collectionLock;

            // Acquire the lock based on the requested type.
            switch (requestLock)
            {
            case RequestLock.Read:
                blockLock = new NestableReadLock(accessLock);
                break;

            case RequestLock.UpgradableRead:
                blockLock = new NestableUpgradableReadLock(accessLock);
                break;

            case RequestLock.Write:
                blockLock = new NestableWriteLock(accessLock);
                break;

            default:
                throw new InvalidOperationException(
                          "Could not acquire lock with unknown type: " + requestLock);
            }
        }