/// <summary>
        /// Constructor for ServiceLock processor.
        /// </summary>
        /// <param name="numberThreads">The number of threads allocated to the processor.</param>
        /// <param name="terminationEvent">Stop signal</param>
        public ServiceLockProcessor(int numberThreads, ManualResetEvent terminationEvent)
        {
            _terminationEvent = terminationEvent;
            _threadStop       = new ManualResetEvent(false);

            _threadPool = new ServiceLockThreadPool(numberThreads);
            _threadPool.ThreadPoolName = "ServiceLock Pool";

            ServiceLockFactoryExtensionPoint ep = new ServiceLockFactoryExtensionPoint();

            object[] factories = ep.CreateExtensions();

            if (factories == null || factories.Length == 0)
            {
                // No extension for the ServiceLock processor.
                Platform.Log(LogLevel.Warn, "No ServiceLockFactory Extension found.");
            }
            else
            {
                foreach (object obj in factories)
                {
                    IServiceLockProcessorFactory factory = obj as IServiceLockProcessorFactory;
                    if (factory != null)
                    {
                        ServiceLockTypeEnum type = factory.GetServiceLockType();
                        _extensions.Add(type, factory);
                    }
                    else
                    {
                        Platform.Log(LogLevel.Error, "Unexpected incorrect type loaded for extension: {0}",
                                     obj.GetType());
                    }
                }
            }
        }
        /// <summary>
        /// The processing thread.
        /// </summary>
        /// <remarks>
        /// This method queries the database for ServiceLock entries to work on, and then uses
        /// a thread pool to process the entries.
        /// </remarks>
        public void Run()
        {
            // Start the thread pool
            if (!_threadPool.Active)
            {
                _threadPool.Start();
            }

            // Reset any queue items related to this service that are have the Lock bit set.
            try
            {
                ResetLocked();
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Fatal, e,
                             "Unable to reset ServiceLock items on startup.  There may be ServiceLock items orphaned in the queue.");
            }

            Platform.Log(LogLevel.Info, "ServiceLock Processor is running");
            while (true)
            {
                try
                {
                    if (_threadPool.CanQueueItem)
                    {
                        Model.ServiceLock queueListItem;

                        using (IUpdateContext updateContext = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                        {
                            IQueryServiceLock          select = updateContext.GetBroker <IQueryServiceLock>();
                            ServiceLockQueryParameters parms  = new ServiceLockQueryParameters();
                            parms.ProcessorId = ServerPlatform.ProcessorId;

                            queueListItem = select.FindOne(parms);
                            updateContext.Commit();
                        }

                        if (queueListItem == null)
                        {
                            WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(30), false);
                            _threadStop.Reset();
                        }
                        else
                        {
                            if (!_extensions.ContainsKey(queueListItem.ServiceLockTypeEnum))
                            {
                                Platform.Log(LogLevel.Error,
                                             "No extensions loaded for ServiceLockTypeEnum item type: {0}.  Failing item.",
                                             queueListItem.ServiceLockTypeEnum);

                                //Just fail the ServiceLock item, not much else we can do
                                ResetServiceLock(queueListItem);
                                continue;
                            }

                            IServiceLockProcessorFactory factory = _extensions[queueListItem.ServiceLockTypeEnum];

                            IServiceLockItemProcessor processor;
                            try
                            {
                                processor = factory.GetItemProcessor();
                            }
                            catch (Exception e)
                            {
                                Platform.Log(LogLevel.Error, e, "Unexpected exception creating ServiceLock processor.");
                                ResetServiceLock(queueListItem);
                                continue;
                            }

                            _threadPool.Enqueue(processor, queueListItem, delegate(IServiceLockItemProcessor queueProcessor, Model.ServiceLock queueItem)
                            {
                                try
                                {
                                    queueProcessor.Process(queueItem);
                                }
                                catch (Exception e)
                                {
                                    Platform.Log(LogLevel.Error, e,
                                                 "Unexpected exception when processing ServiceLock item of type {0}.  Failing Queue item. (GUID: {1})",
                                                 queueItem.ServiceLockTypeEnum,
                                                 queueItem.GetKey());

                                    ServerPlatform.Alert(AlertCategory.Application, AlertLevel.Error, "ServiceLockProcessor",
                                                         AlertTypeCodes.UnableToProcess,
                                                         null, TimeSpan.Zero,
                                                         "Exception thrown when processing {0} ServiceLock item : {1}",
                                                         queueItem.ServiceLockTypeEnum.Description, e.Message);
                                    ResetServiceLock(queueItem);
                                }

                                // Cleanup the processor
                                queueProcessor.Dispose();

                                // Signal the thread to come out of sleep mode
                                _threadStop.Set();
                            });
                        }
                    }
                    else
                    {
                        // Wait for only 5 seconds when the thread pool is all in use.
                        WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(5), false);
                        _threadStop.Reset();
                    }
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, ex, "Exception has occurred : {0}. Retry later.", ex.Message);
                    WaitHandle.WaitAny(new WaitHandle[] { _terminationEvent, _threadStop }, TimeSpan.FromSeconds(5), false);
                    _threadStop.Reset();
                }

                if (_stop)
                {
                    return;
                }
            }
        }