private void ExecuteTransition(Transition transition)
        {
            // Default checking, if this is a valid transaction
            if (this.CurrentState.StateName != transition.SourceStateName)
            {
                string message = string.Format("Transition has wrong source state {0}, when system is in {1}",
                                    transition.SourceStateName, this.CurrentState.StateName);
                this.RaiseStateMachineSystemEvent("State machine: Default guard execute transition.", message);
                return;
            }
            if (!this.StateList.ContainsKey(transition.TargetStateName))
            {
                string message = string.Format("Transition has wrong target state {0}, when system is in {1}. State not in global State List",
                                    transition.SourceStateName, this.CurrentState.StateName);
                this.RaiseStateMachineSystemEvent("State machine: Default guard execute transition.", message);
                return;
            }

            // Self transition - Just do the transition without executing exit, entry actions or guards
            if (transition.SourceStateName == transition.TargetStateName)
            {
                transition.TransitionActionList.ForEach(t => t.Execute());
                return; // Important: return directly from self transition
            }

            // Run all exit actions of the old state
            this.CurrentState.ExitActions.ForEach(a => a.Execute());

            // Run all guards of the transition
            transition.GuardList.ForEach(g => g.Execute());
            string info = transition.GuardList.Count + " guard actions executed!";
            this.RaiseStateMachineSystemEvent("State machine: ExcuteTransition", info);

            // Run all actions of the transition
            transition.TransitionActionList.ForEach(t => t.Execute());

            ////////////////
            // State change
            ////////////////
            info = transition.TransitionActionList.Count + " transition actions executed.";
            this.RaiseStateMachineSystemEvent("State machine: Begin state change.", info);

            // First resolve the target state with the help of its name
            var targetState = this.GetStateFromStateList(transition.TargetStateName);

            // Transition succesfsul - Change state
            this.PreviousState = this.CurrentState;
            this.CurrentState = targetState;

            // run all entry actions of the new state
            foreach (var entryAction in this.CurrentState.EntryActions)
            {
                entryAction.Execute();
            }

            this.RaiseStateMachineSystemEvent("State machine: State change completed successfully.", "Previous state: " +
                                     this.PreviousState.StateName + " - New state = " + this.CurrentState.StateName);
        }
        /// <summary>
        /// Build telephone state configuration
        /// </summary>
        private void BuildConfig()
        {
            // Transitions and actions
            #region preparation of transitions and actions
            TelephoneActivities = new TelephoneActivities();

            // create actions and map action methods into the corresponding action object
            // Device actions
            var actionBellRings = new StateMachineAction("ActionBellRings", this.TelephoneActivities.ActionBellRings);
            var actionBellSilent = new StateMachineAction("ActionBellSilent", this.TelephoneActivities.ActionBellSilent);
            var actionLineOff = new StateMachineAction("ActionLineOff", this.TelephoneActivities.ActionLineOff);
            var actionLineActive = new StateMachineAction("ActionLineActive", this.TelephoneActivities.ActionLineActive);
            
            // View Actions
            var actionViewPhoneRings = new StateMachineAction("ActionViewPhoneRings", this.TelephoneActivities.ActionViewPhoneRings);
            var actionViewPhoneIdle = new StateMachineAction("ActionViewPhoneIdle", this.TelephoneActivities.ActionViewPhoneIdle);
            var actionViewTalking = new StateMachineAction("ActionViewTalking", this.TelephoneActivities.ActionViewTalking);

            // Error Actions
            var actionViewErrorPhoneRings = new StateMachineAction("ActionViewErrorPhoneRings", TelephoneActivities.ActionErrorPhoneRings);

            // Create transitions and corresponding triggers, states need to be added
            var emptyList = new List<StateMachineAction>(); // to avoid null reference exceptions, use an empty list
            // transition IncomingCall
            var IncomingCallActions = new List<StateMachineAction>();
            IncomingCallActions.Add(actionViewPhoneRings);
            var transIncomingCall = new Transition("TransitionIncomingCall", "StatePhoneIdle", "StatePhoneRings", emptyList, IncomingCallActions, "OnLineExternalActive");

            // transition CallBlocked
            var CallBlockedActions = new List<StateMachineAction>();
            CallBlockedActions.Add(actionViewPhoneIdle);
            var transCallBlocked = new Transition("TransitionCallBlocked", "StatePhoneRings", "StatePhoneIdle", emptyList, CallBlockedActions, "OnReceiverDown");
            
            // transition CallAccepted
            var CallAcceptedActions = new List<StateMachineAction>();
            CallAcceptedActions.Add(actionViewTalking);
            var transCallAccepted = new Transition("TransitionCallAccepted", "StatePhoneRings", "StateTalking", emptyList, CallAcceptedActions, "OnReceiverUp");
            
            // transition CallEnded
            var CallEndedActions = new List<StateMachineAction>();
            CallEndedActions.Add(actionViewPhoneIdle);
            var transCallEnded = new Transition("TransitionCallEnded", "StateTalking", "StatePhoneIdle", emptyList, CallEndedActions, "OnReceiverDown");

            // transition ErrorPhoneRings - self-transition on PhoneRings state
            var errorPhoneRingsActions = new List<StateMachineAction>();
            errorPhoneRingsActions.Add(actionViewErrorPhoneRings);
            var transErrorPhoneRings = new Transition("TransitionErrorPhoneRings", "StatePhoneRings", "StatePhoneRings", emptyList, errorPhoneRingsActions, "OnBellBroken");

            #endregion

            #region Assemble all states
            // create states
            // state: PhoneIdle
            var transitionsPhoneIdle = new Dictionary<string, Transition>();
            var entryActionsPhoneIdle = new List<StateMachineAction>();
            var exitActionsPhoneIdle = new List<StateMachineAction>();
            transitionsPhoneIdle.Add("TransitionIncomingCall", transIncomingCall);
            // Always specify all action lists, even empty ones, do not pass null into a state Lists are read via foreach, which will return an error
            var phoneIdle = new State("StatePhoneIdle", transitionsPhoneIdle, entryActionsPhoneIdle, exitActionsPhoneIdle, true);

            // state: PhoneRings
            var transitionsPhoneRings = new Dictionary<string, Transition>();
            var entryActionsPhoneRings = new List<StateMachineAction>();
            entryActionsPhoneRings.Add(actionBellRings);
            var exitActionsPhoneRings = new List<StateMachineAction>();
            exitActionsPhoneRings.Add(actionBellSilent);
            transitionsPhoneRings.Add("TransitionCallBlocked", transCallBlocked);
            transitionsPhoneRings.Add("TransitionCallAccepted", transCallAccepted);
            transitionsPhoneRings.Add("TransitionErrorPhoneRings", transErrorPhoneRings);
            // Always specify all action lists, even empty ones, do not pass null into a state Lists are read via foreach, which will return an error
            var phoneRings = new State("StatePhoneRings", transitionsPhoneRings, entryActionsPhoneRings, exitActionsPhoneRings);

            // state: Talking
            var transitionsTalking = new Dictionary<string, Transition>();
            var entryActionsTalking = new List<StateMachineAction>();
            entryActionsTalking.Add(actionLineActive);
            var exitActionsTalking = new List<StateMachineAction>();
            exitActionsTalking.Add(actionLineOff);
            transitionsTalking.Add("TransitionCallEnded", transCallEnded);
            // Always specify all action lists, even empty ones, do not pass null into a state Lists are read via foreach, which will return an error
            var talking = new State("StateTalking", transitionsTalking, entryActionsTalking, exitActionsTalking);

            this.TelephoneStateMachineStateList = new Dictionary<string, State>
            {
                {"StatePhoneIdle", phoneIdle},
                {"StatePhoneRings", phoneRings},
                {"StateTalking", talking}
            };

            #endregion

            // Application Services
            #region Appilcation Services
            // Get application services
            this.TelephoneEventManager = EventManager.Instance;
            this.TelephoneViewManager = ViewManager.Instance;
            this.TelephoneLogManager = LogManager.Instance;
            this.TelephoneDeviceManager = DeviceManager.Instance;

            #endregion
        }