private StateMachine<ImportFinancialGuaranteeStatus, Trigger> CreateStateMachine()
        {
            var stateMachine = new StateMachine<ImportFinancialGuaranteeStatus, Trigger>(() => Status, s => Status = s);

            stateMachine.OnTransitioned(OnTransitionAction);

            completeTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Complete);

            stateMachine.Configure(ImportFinancialGuaranteeStatus.ApplicationReceived)
                .Permit(Trigger.Complete, ImportFinancialGuaranteeStatus.ApplicationComplete);

            stateMachine.Configure(ImportFinancialGuaranteeStatus.ApplicationComplete)
                .OnEntryFrom(completeTrigger, OnComplete)
                .Permit(Trigger.Approve, ImportFinancialGuaranteeStatus.Approved)
                .Permit(Trigger.Refuse, ImportFinancialGuaranteeStatus.Refused);

            stateMachine.Configure(ImportFinancialGuaranteeStatus.Approved)
                .Permit(Trigger.Release, ImportFinancialGuaranteeStatus.Released);
                
            return stateMachine;
        }
示例#2
0
        public Story(EntityWorld world)
        {
            Acts = new List<IStoryAct>(new[] { new ActOne() });
            State = new StateMachine<StoryUpdateFunction, string>(Acts[0].Master);
            State.OnTransitioned(OnTransition);

            for (int i = 0; i < Acts.Count; i++)
            {
                var act = Acts[i];
                act.ConfigureStates(State);

                State.Configure(act.Master)
                    .Permit(Triggers.NextAct, i < Acts.Count - 1 ? (StoryUpdateFunction)Acts[i + 1].Master : EndOfStory);
            }
            World = world;
            State.Fire(ActOne.Triggers.Start);
        }
示例#3
0
        /// <summary>
        ///     Main client thread.
        /// </summary>
        private void ClientThread()
        {
            _gameState.Reset();

            _connection = DotaGameConnection.CreateWith(_details);
            _handshake = new DotaHandshake(_details, _gameState, _connection);
            _signon = new DotaSignon(_gameState, _connection, _details);
            _game = new DotaGame(_gameState, _connection);
            _commandGenerator = new UserCmdGenerator(_gameState, _connection);

            foreach (var cont in Controllers)
                cont.Initialize(_details.SteamId, _gameState, _commandGenerator);

            long handshake_requested = 0;
            long handshake_giveup = new TimeSpan(0, 0, 0, 10).Ticks;

            // Map states in the StateMachine to handlers
            var metastates = new Dictionary<States, Metastates>() {
                { States.HANDSHAKE_REQUEST, Metastates.HANDSHAKE },
                { States.HANDSHAKE_CONNECT, Metastates.HANDSHAKE },
                { States.CONNECTED, Metastates.SIGNON },
                { States.LOADING, Metastates.SIGNON },
                { States.PRESPAWN, Metastates.SIGNON },
                { States.SPAWN, Metastates.SIGNON },
                { States.PLAY, Metastates.GAME },
            };

            var processors = new Dictionary<Metastates, IHandler>() {
                { Metastates.HANDSHAKE, _handshake },
                { Metastates.SIGNON, _signon },
                { Metastates.GAME, _game }
            };


            _stateMachine = new StateMachine<States, Events>(States.DISCONNECTED);
            //temporary shit
            _stateMachine.OnTransitioned(transition =>
            {
                if (transition.Source == transition.Destination) return;
                Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.SessionStateTransition(transition.Source, transition.Destination)));
            });

            _stateMachine.OnUnhandledTrigger((states, events) =>
            {
                Console.WriteLine("Unhandled trigger: " + events.ToString("G"));

            });

            var disconnected = new Action(() =>
            {
                if (_connection == null) return;
                Running = true;
                Stop();
            });

            _stateMachine.Configure(States.DISCONNECTED)
                .Ignore(Events.TICK)
                .Ignore(Events.DISCONNECTED)
                .OnEntry(disconnected)
                .Permit(Events.REQUEST_CONNECT, States.HANDSHAKE_REQUEST);
            _stateMachine.Configure(States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED)
                .OnEntry(() =>
                {
                    Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.HandshakeRejected(_handshake.rejected_reason)));
                    _stateMachine.Fire(Events.DISCONNECTED);
                });
            _stateMachine.Configure(States.HANDSHAKE_REQUEST)
                .OnEntry(() => handshake_requested = DateTime.Now.Ticks)
                .OnEntry(_handshake.RequestHandshake)
                .Ignore(Events.TICK)
                .Permit(Events.HANDSHAKE_CHALLENGE, States.HANDSHAKE_CONNECT)
                .Permit(Events.REJECTED, States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.HANDSHAKE_CONNECT)
                .OnEntry(_handshake.RespondHandshake)
                .Ignore(Events.TICK)
                .PermitReentry(Events.HANDSHAKE_CHALLENGE) // possibly re-enter?
                .Permit(Events.HANDSHAKE_COMPLETE, States.CONNECTED)
                .Permit(Events.REJECTED, States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.CONNECTED)
                .OnEntry(_signon.EnterConnected)
                .Ignore(Events.TICK)
                .Permit(Events.LOADING_START, States.LOADING)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.LOADING)
                .OnEntry(_signon.EnterNew)
                .Ignore(Events.TICK)
                .Permit(Events.CONNECTED, States.CONNECTED)
                .Permit(Events.PRESPAWN_START, States.PRESPAWN)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.PRESPAWN)
                .OnEntry(_signon.EnterPrespawn)
                .Ignore(Events.TICK)
                .Permit(Events.SPAWNED, States.SPAWN)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.SPAWN)
                .OnEntry(_signon.EnterSpawn)
                .Ignore(Events.TICK)
                .Permit(Events.BASELINE, States.PLAY)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.PLAY)
                .OnEntryFrom(Events.BASELINE, () =>
                {
                    _game.EnterGame();
                    _commandGenerator.Reset();
                })
                .OnEntryFrom(Events.TICK, () =>
                {
                    _gameState.Update();
                    foreach(var cont in Controllers) cont.Tick();
                    _commandGenerator.Tick();
                    _gameState.Created.Clear();
                    _gameState.Deleted.Clear();
                })
                .PermitReentry(Events.TICK)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);

            _stateMachine.Fire(Events.REQUEST_CONNECT);

            long next_tick = DateTime.Now.Ticks;
            while (Running && _stateMachine.State != States.DISCONNECTED && _stateMachine.State != States.HANDSHAKE_REJECTED)
            {
                try
                {
                    if (next_tick > DateTime.Now.Ticks)
                    {
                        Thread.Sleep(1);
                        continue;
                    }

                    if (_stateMachine == null) break;

                    if (_stateMachine.State == States.HANDSHAKE_REQUEST &&
                        (DateTime.Now.Ticks - handshake_requested) > handshake_giveup)
                    {
                        _stateMachine.Fire(Events.DISCONNECTED);
                        continue;
                    }

                    if (_connection.state == DotaGameConnection.State.Closed)
                    {
                        _stateMachine.Fire(Events.DISCONNECTED);
                        continue;
                    }

                    if (_connection == null) break;

                    List<byte[]> outBand = _connection.GetOutOfBand();
                    List<DotaGameConnection.Message> inBand = _connection.GetInBand();

                    foreach (byte[] message in outBand)
                    {
                        Nullable<Events> e = processors[metastates[_stateMachine.State]].Handle(message);
                        if (e.HasValue)
                        {
                            _stateMachine.Fire(e.Value);
                        }
                    }

                    foreach (DotaGameConnection.Message message in inBand)
                    {
                        Nullable<Events> e = processors[metastates[_stateMachine.State]].Handle(message);
                        if (e.HasValue)
                        {
                            _stateMachine.Fire(e.Value);
                        }
                    }

                    _stateMachine.Fire(Events.TICK);

                    if (_gameState.TickInterval > 0)
                    {
                        next_tick += (uint)(_gameState.TickInterval * 1000 * 10000 /* ticks per ms */);
                    }
                    else
                    {
                        next_tick += 50 * 1000;
                    }
                    int remain = (int)(next_tick - DateTime.Now.Ticks) / 10000;
                    if (remain > 0)
                    {
                        Thread.Sleep(1);
                    }
                    else if (remain < 0)
                    {
                        next_tick = DateTime.Now.Ticks;
                    }
                }
                catch (Exception ex)
                {
                    Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.LogMessage("Ignored error in session loop, " + ex.Message)));
                }
            }

            if (Running) Stop();
        }
        private void ConfigureStateMachine()
        {
            _fsm = new StateMachine<State, Trigger>(State.Unmonitored);

            _fsm.OnTransitioned(OnStateMachineTransitioned);

            _fsm.Configure(State.Unmonitored)
                .Permit(Trigger.Watch, State.Connecting)
                .OnEntry(OnUnmonitoredState);

            _fsm.Configure(State.Monitored)
                .Permit(Trigger.Unwatch, State.Unmonitored)
                .OnEntry(OnMonitoredState);

            _fsm.Configure(State.Disconnected)
                .SubstateOf(State.Monitored)
                .PermitReentry(Trigger.Disconnect)
                .Permit(Trigger.Connect, State.Connecting)
                .OnEntry(OnDisconnectedState);

            _fsm.Configure(State.Connecting)
                .SubstateOf(State.Disconnected)
                .Permit(Trigger.Connected, State.Connected)
                .OnEntry(OnConnectingState);

            _fsm.Configure(State.Restarting)
                .SubstateOf(State.Disconnected)
                .Permit(Trigger.Connected, State.Connected);

            _fsm.Configure(State.Upgrading)
                .SubstateOf(State.Disconnected)
                .Permit(Trigger.Connected, State.Connected);

            _fsm.Configure(State.Connected)
                .SubstateOf(State.Monitored)
                .Permit(Trigger.Restart, State.Restarting)
                .Permit(Trigger.Upgrade, State.Upgrading)
                .Permit(Trigger.Disconnect, State.Disconnected)
                .Permit(Trigger.Disconnected, State.Disconnected)
                .OnEntry(OnConnectedState)
                .OnExit(OnConnectedStateExit);
        }
        private StateMachine<NotificationStatus, Trigger> CreateStateMachine()
        {
            var stateMachine = new StateMachine<NotificationStatus, Trigger>(() => Status, s => Status = s);

            receivedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.NotificationReceived);
            commencedTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.AssessmentCommenced);
            completeTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.NotificationComplete);
            transmitTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Transmit);
            acknowledgedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Acknowledged);
            withdrawTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.Withdraw);
            objectTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.Object);
            withdrawConsentTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.WithdrawConsent);
            consentedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Consent);
            archiveTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Archive);

            stateMachine.OnTransitioned(OnTransitionAction);

            stateMachine.Configure(NotificationStatus.NotSubmitted)
                .Permit(Trigger.Submit, NotificationStatus.Submitted)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.Submitted)
                .SubstateOf(NotificationStatus.InDetermination)
                .OnEntryFrom(Trigger.Submit, OnSubmit)
                .Permit(Trigger.NotificationReceived, NotificationStatus.NotificationReceived);

            stateMachine.Configure(NotificationStatus.NotificationReceived)
                .SubstateOf(NotificationStatus.InDetermination)
                .OnEntryFrom(receivedTrigger, OnReceived)
                .PermitIf(Trigger.AssessmentCommenced, NotificationStatus.InAssessment, () => Dates.PaymentReceivedDate.HasValue)
                .Permit(Trigger.Object, NotificationStatus.Objected);

            stateMachine.Configure(NotificationStatus.InAssessment)
                .SubstateOf(NotificationStatus.InDetermination)
                .OnEntryFrom(commencedTrigger, OnInAssessment)
                .Permit(Trigger.NotificationComplete, NotificationStatus.ReadyToTransmit)
                .Permit(Trigger.Object, NotificationStatus.Objected);

            stateMachine.Configure(NotificationStatus.ReadyToTransmit)
                .SubstateOf(NotificationStatus.InDetermination)
                .OnEntryFrom(completeTrigger, OnCompleted)
                .Permit(Trigger.Transmit, NotificationStatus.Transmitted)
                .Permit(Trigger.Object, NotificationStatus.Objected);

            stateMachine.Configure(NotificationStatus.Transmitted)
                .SubstateOf(NotificationStatus.InDetermination)
                .OnEntryFrom(transmitTrigger, OnTransmitted)
                .Permit(Trigger.Acknowledged, NotificationStatus.DecisionRequiredBy)
                .Permit(Trigger.Object, NotificationStatus.Objected);

            stateMachine.Configure(NotificationStatus.DecisionRequiredBy)
                .OnEntryFrom(acknowledgedTrigger, OnAcknowledged)
                .Permit(Trigger.Unlock, NotificationStatus.Unlocked)
                .Permit(Trigger.Consent, NotificationStatus.Consented)
                .Permit(Trigger.Object, NotificationStatus.Objected)
                .Permit(Trigger.Withdraw, NotificationStatus.Withdrawn)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.InDetermination)
                .Permit(Trigger.Withdraw, NotificationStatus.Withdrawn)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.Withdrawn)
                .OnEntryFrom(withdrawTrigger, OnWithdrawn)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.Objected)
                .OnEntryFrom(objectTrigger, OnObjected)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.Consented)
                .OnEntryFrom(consentedTrigger, OnConsented)
                .Permit(Trigger.WithdrawConsent, NotificationStatus.ConsentWithdrawn)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.ConsentWithdrawn)
                .OnEntryFrom(withdrawConsentTrigger, OnConsentWithdrawn)
                .Permit(Trigger.Archive, NotificationStatus.FileClosed);

            stateMachine.Configure(NotificationStatus.Unlocked)
                .SubstateOf(NotificationStatus.InDetermination)
                .Permit(Trigger.Resubmit, NotificationStatus.Reassessment);

            stateMachine.Configure(NotificationStatus.Reassessment)
                .SubstateOf(NotificationStatus.InDetermination)
                .Permit(Trigger.AcceptChanges, NotificationStatus.DecisionRequiredBy)
                .Permit(Trigger.RejectChanges, NotificationStatus.Unlocked);

            stateMachine.Configure(NotificationStatus.FileClosed)
                .OnEntryFrom(archiveTrigger, OnFileClosed);

            return stateMachine;
        }
        private StateMachine<FinancialGuaranteeStatus, Trigger> CreateStateMachine()
        {
            var stateMachine = new StateMachine<FinancialGuaranteeStatus, Trigger>(() => Status, s => Status = s);

            completedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Completed);
            approvedTrigger = stateMachine.SetTriggerParameters<ApprovalData>(Trigger.Approved);
            refusedTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.Refused);
            releasedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Released);

            stateMachine.Configure(FinancialGuaranteeStatus.ApplicationReceived)
                .Permit(Trigger.Completed, FinancialGuaranteeStatus.ApplicationComplete);

            stateMachine.Configure(FinancialGuaranteeStatus.ApplicationComplete)
                .OnEntryFrom(completedTrigger, OnCompleted)
                .PermitIf(Trigger.Approved, FinancialGuaranteeStatus.Approved, () => CompletedDate.HasValue)
                .PermitIf(Trigger.Refused, FinancialGuaranteeStatus.Refused, () => CompletedDate.HasValue);

            stateMachine.Configure(FinancialGuaranteeStatus.Approved)
                .OnEntryFrom(approvedTrigger, OnApproved)
                .Permit(Trigger.Released, FinancialGuaranteeStatus.Released)
                .Permit(Trigger.Superseded, FinancialGuaranteeStatus.Superseded);

            stateMachine.Configure(FinancialGuaranteeStatus.Refused)
                .OnEntryFrom(refusedTrigger, OnRefused);

            stateMachine.Configure(FinancialGuaranteeStatus.Released)
                .OnEntryFrom(releasedTrigger, OnReleased);

            stateMachine.OnTransitioned(OnTransitionAction);

            return stateMachine;
        }
示例#7
0
        private StateMachine<MovementStatus, Trigger> CreateStateMachine()
        {
            var stateMachine = new StateMachine<MovementStatus, Trigger>(() => Status, s => Status = s);

            submittedTrigger = stateMachine.SetTriggerParameters<Guid>(Trigger.Submit);
            internallySubmittedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.SubmitInternal);
            completedTrigger = stateMachine.SetTriggerParameters<DateTime, Guid, Guid>(Trigger.Complete);
            internallyCompletedTrigger = stateMachine.SetTriggerParameters<DateTime, Guid>(Trigger.CompleteInternal);

            acceptedTrigger = stateMachine.SetTriggerParameters<AcceptedTriggerParameters>(Trigger.Receive);
            internallyAcceptedTrigger = stateMachine.SetTriggerParameters<InternallyAcceptedTriggerParameters>(Trigger.ReceiveInternal);

            stateMachine.OnTransitioned(OnTransitionAction);

            stateMachine.Configure(MovementStatus.New)
                .Permit(Trigger.Submit, MovementStatus.Submitted);

            stateMachine.Configure(MovementStatus.Submitted)
                .OnEntryFrom(submittedTrigger, OnSubmitted)
                .OnEntryFrom(internallySubmittedTrigger, OnInternallySubmitted)
                .Permit(Trigger.Receive, MovementStatus.Received)
                .Permit(Trigger.ReceiveInternal, MovementStatus.Received)
                .Permit(Trigger.Reject, MovementStatus.Rejected)
                .Permit(Trigger.Cancel, MovementStatus.Cancelled);

            stateMachine.Configure(MovementStatus.Received)
                .OnEntryFrom(acceptedTrigger, OnReceived)
                .OnEntryFrom(internallyAcceptedTrigger, OnInternallyReceived)
                .Permit(Trigger.Complete, MovementStatus.Completed)
                .Permit(Trigger.CompleteInternal, MovementStatus.Completed);

            stateMachine.Configure(MovementStatus.Completed)
                .OnEntryFrom(completedTrigger, OnCompleted)
                .OnEntryFrom(internallyCompletedTrigger, OnInternallyCompleted);

            stateMachine.Configure(MovementStatus.Captured)
                .Permit(Trigger.ReceiveInternal, MovementStatus.Received)
                .Permit(Trigger.Reject, MovementStatus.Rejected)
                .Permit(Trigger.SubmitInternal, MovementStatus.Submitted);

            return stateMachine;
        }
        private StateMachine<ImportNotificationStatus, Trigger> CreateStateMachine()
        {
            var stateMachine = new StateMachine<ImportNotificationStatus, Trigger>(() => Status, s => Status = s);

            stateMachine.OnTransitioned(OnTransition);

            receivedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Receive);
            fullyPaidTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.FullyPaid);
            beginAssessmentTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.BeginAssessment);
            completeNotificationTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.CompleteNotification);
            acknowledgeTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Acknowledge);
            consentedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.Consent);
            withdrawConsentTrigger = stateMachine.SetTriggerParameters<DateTime, string>(Trigger.WithdrawConsent);
            fileClosedTrigger = stateMachine.SetTriggerParameters<DateTime>(Trigger.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.New)
                .Permit(Trigger.Receive, ImportNotificationStatus.NotificationReceived);

            stateMachine.Configure(ImportNotificationStatus.NotificationReceived)
                .OnEntryFrom(receivedTrigger, OnReceived)
                .Permit(Trigger.Submit, ImportNotificationStatus.AwaitingPayment)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.AwaitingPayment)
                .SubstateOf(ImportNotificationStatus.Submitted)
                .Permit(Trigger.FullyPaid, ImportNotificationStatus.AwaitingAssessment)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.AwaitingAssessment)
                .SubstateOf(ImportNotificationStatus.Submitted)
                .OnEntryFrom(fullyPaidTrigger, OnFullyPaid)
                .Permit(Trigger.BeginAssessment, ImportNotificationStatus.InAssessment)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);
            
            stateMachine.Configure(ImportNotificationStatus.InAssessment)
                .OnEntryFrom(beginAssessmentTrigger, OnAssessmentStarted)
                .Permit(Trigger.CompleteNotification, ImportNotificationStatus.ReadyToAcknowledge)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.ReadyToAcknowledge)
                .OnEntryFrom(completeNotificationTrigger, OnNotificationCompleted)
                .Permit(Trigger.Acknowledge, ImportNotificationStatus.DecisionRequiredBy)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.DecisionRequiredBy)
                .OnEntryFrom(acknowledgeTrigger, OnAcknowledged)
                .Permit(Trigger.Consent, ImportNotificationStatus.Consented)
                .Permit(Trigger.Object, ImportNotificationStatus.Objected)
                .Permit(Trigger.Withdraw, ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.Consented)
                .OnEntryFrom(consentedTrigger, OnConsented)
                .Permit(Trigger.WithdrawConsent, ImportNotificationStatus.ConsentWithdrawn)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.ConsentWithdrawn)
                .OnEntryFrom(withdrawConsentTrigger, OnConsentWithdrawn)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.Objected)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.Withdrawn)
                .Permit(Trigger.FileClosed, ImportNotificationStatus.FileClosed);

            stateMachine.Configure(ImportNotificationStatus.FileClosed)
                .OnEntryFrom(fileClosedTrigger, OnFileClosed);

            return stateMachine;
        }