protected void ProcessQueue()
        {
            try
            {
                while (_run)
                {
                    // Update time this thread was last alive
                    _threads[Thread.CurrentThread] = DateTime.Now;

                    // Check if increase of number of threads is desired
                    CheckThreadIncrementRequired();

                    // Wait until we receive a work item
                    IWork work = _workQueue.Dequeue(_startInfo.ThreadIdleTimeout, _cancelWaitHandle);

                    if (work == null)
                    {
                        // Dequeue has returned null or we should shutdown
                        if (_threads.Count > _startInfo.MinimumThreads)
                        {
                            lock (_syncObj)
                            {
                                if (_threads.Count > _startInfo.MinimumThreads)
                                {
                                    ServiceRegistration.Get <ILogger>().Debug("ThreadPool.ProcessQueue(): Quitting (inUse: {0}, total: {1})", _inUseThreads, _threads.Count);
                                    // remove thread from the pool
                                    if (_threads.ContainsKey(Thread.CurrentThread))
                                    {
                                        DateTime time;
                                        _threads.TryRemove(Thread.CurrentThread, out time);
                                    }
                                    break;
                                }
                            }
                        }
                        CheckForIntervalBasedWork();
                        // Skip this iteration if we got here and work is null
                        continue;
                    }

//          ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Received valid work: {1}", work.State);
                    try
                    {
                        // Only process items which have status INQUEUE (don't process CANCEL'ed items)
                        if (work.State == WorkState.INQUEUE)
                        {
                            Thread.CurrentThread.Priority = work.ThreadPriority;
                            IncInUseThreadCount();
//              ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Processing work {1}", work.Description);
                            work.Process();
//              ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Finished processing work {0}", work.Description);
                        }
                    }
                    catch (Exception e)
                    {
                        ServiceRegistration.Get <ILogger>().Warn("ThreadPool.ProcessQueue(): Exception during processing work '{0}'", e, work.Description);
                        work.State     = WorkState.ERROR;
                        work.Exception = e;
                    }
                    finally
                    {
                        if (work.State == WorkState.FINISHED || work.State == WorkState.ERROR)
                        {
                            Interlocked.Increment(ref _itemsProcessed);
//              ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): {0} items processed", _itemsProcessed);
                            DecInUseThreadCount();
//              ServiceRegistration.Get<ILogger>().Debug("ThreadPool.ProcessQueue(): Finished processing work {0}", work.Description);
                        }
                        Thread.CurrentThread.Priority = _startInfo.DefaultThreadPriority;
                    }
                    CheckForIntervalBasedWork();
                }
            }
            catch (ThreadAbortException)
            {
                ServiceRegistration.Get <ILogger>().Debug("ThreadPool.ProcessQueue(): Thread aborted");
                Thread.ResetAbort();
            }
            catch (Exception e)
            {
                ServiceRegistration.Get <ILogger>().Error("ThreadPool.ProcessQueue(): Error executing work", e);
            }
            finally
            {
                if (_threads.ContainsKey(Thread.CurrentThread))
                {
                    DateTime time;
                    _threads.TryRemove(Thread.CurrentThread, out time);
                }
            }
        }