//--- Constructors ---

        /// <summary>
        /// Creates a new ElasticPriorityThreadPool instance.
        /// </summary>
        /// <param name="minReservedThreads">Minium number of threads to reserve for the thread pool.</param>
        /// <param name="maxParallelThreads">Maximum number of parallel threads used by the thread pool.</param>
        /// <param name="maxPriority">Maximum priority number (inclusive upper bound).</param>
        /// <exception cref="InsufficientResourcesException">The ElasticPriorityThreadPool instance was unable to obtain the minimum reserved threads.</exception>
        public ElasticPriorityThreadPool(int minReservedThreads, int maxParallelThreads, int maxPriority)
        {
            _minReservedThreads = Math.Max(0, Math.Min(minReservedThreads, MAX_RESERVED_THREADS));
            _maxParallelThreads = Math.Max(Math.Max(1, minReservedThreads), Math.Min(maxParallelThreads, int.MaxValue));
            _inbox            = new LockFreePriorityQueue <Action>(maxPriority);
            _prioritizedInbox = new PrioritizedThreadPool[maxPriority];
            for (int i = 0; i < maxPriority; ++i)
            {
                _prioritizedInbox[i] = new PrioritizedThreadPool(i, this);
            }

            // initialize reserved threads
            _activeThreads = new DispatchThread[Math.Min(_maxParallelThreads, Math.Max(_minReservedThreads, Math.Min(16, _maxParallelThreads)))];
            if (_minReservedThreads > 0)
            {
                DispatchThreadScheduler.RequestThread(_minReservedThreads, AddThread);
            }
            DispatchThreadScheduler.RegisterHost(this);
            _log.DebugFormat("Create @{0}", this);
        }
        //--- Constructors ---
        /// <summary>
        /// Creates a new ElasticPriorityThreadPool instance.
        /// </summary>
        /// <param name="minReservedThreads">Minium number of threads to reserve for the thread pool.</param>
        /// <param name="maxParallelThreads">Maximum number of parallel threads used by the thread pool.</param>
        /// <param name="maxPriority">Maximum priority number (inclusive upper bound).</param>
        /// <exception cref="InsufficientResourcesException">The ElasticPriorityThreadPool instance was unable to obtain the minimum reserved threads.</exception>
        public ElasticPriorityThreadPool(int minReservedThreads, int maxParallelThreads, int maxPriority)
        {
            _minReservedThreads = Math.Max(0, Math.Min(minReservedThreads, MAX_RESERVED_THREADS));
            _maxParallelThreads = Math.Max(Math.Max(1, minReservedThreads), Math.Min(maxParallelThreads, int.MaxValue));
            _inbox = new LockFreePriorityQueue<Action>(maxPriority);
            _prioritizedInbox = new PrioritizedThreadPool[maxPriority];
            for(int i = 0; i < maxPriority; ++i) {
                _prioritizedInbox[i] = new PrioritizedThreadPool(i, this);
            }

            // initialize reserved threads
            _activeThreads = new DispatchThread[Math.Min(_maxParallelThreads, Math.Max(_minReservedThreads, Math.Min(16, _maxParallelThreads)))];
            if(_minReservedThreads > 0) {
                DispatchThreadScheduler.RequestThread(_minReservedThreads, AddThread);
            }
            DispatchThreadScheduler.RegisterHost(this);
            _log.DebugFormat("Create @{0}", this);
        }