/// <summary>
        /// This method is firing the EventHandlingFailedEvent.
        /// </summary>
        /// <param name="sender">Sender of the event.</param>
        /// <param name="args">Arguments of the event.</param>
        internal virtual void OnEventHandlingFailedEvent(object sender, EventHandlingFailedEventArgs args)
        {
            if (Logger.IsDebugEnabled)
            {
                var message = string.Format(CultureInfo.CurrentUICulture, Resources.FiniteStateMachineFailedHandlingAnEventState_Event_, args.CurrentState.Name, args.FsmEvent.Message);
                Logger.Debug(message);
            }

            var eventHandlingFailedEvent = this.EventHandlingFailedEvent;

            if (eventHandlingFailedEvent != null)
            {
                eventHandlingFailedEvent(this, args);
            }
        }
        private void QueueThread(object param)
        {
            if (Logger.IsDebugEnabled)
            {
                Logger.Debug(Resources.FiniteStateMachineIsStartingItsQueueThread);
            }

            var fsm = param as FiniteStateMachine;

            if (fsm == null)
            {
                throw new ArgumentNullException(@"param"); // illegal parameter
            }

            fsm.threadStartedEvent.Set();

            while (fsm.IsEventHandlerThreadRunning)
            {
                var fsmEvent = fsm.EventQueue.NextEventGet();

                if (fsmEvent != null)
                {
                    try
                    {
                        fsm.ProcessEvent(fsmEvent);
                    }
                    catch (Exception ex)
                    {
                        var args = new EventHandlingFailedEventArgs(fsm.CurrentState, fsmEvent, ex);
                        this.OnEventHandlingFailedEvent(this, args);
                    }
                }
                else
                {
                    fsm.EventQueue.QueueEvent.WaitOne();
                }
            }

            fsm.isEventHandlerThreadRunning = false;
            fsm.eventHandlerThread          = null;
        }