private static void AddValidationMessage(ref WorkflowConfigurationException workflowConfigurationException, string validationMessage)
        {
            if (null == workflowConfigurationException)
            {
                workflowConfigurationException = new WorkflowConfigurationException();
            }

            workflowConfigurationException.ValidationMessages.Add(validationMessage);
        }
        /// <summary>
        ///     Validate workflow configuration against a number of invariants
        /// </summary>
        internal static void ValidateWorkflowConfiguration(WorkflowConfiguration workflowConfiguration)
        {
            WorkflowConfigurationException workflowConfigurationException = null;

            // 1. make sure that workflow has exactly one initial state
            var initialStateCount = workflowConfiguration.States.Count(s => s.Type == StateTypeConfiguration.Initial);

            if (initialStateCount != 1)
            {
                AddValidationMessage(ref workflowConfigurationException, $"Workflow [{workflowConfiguration.Code}] must have exactly one initial state");
            }

            // 2. make sure that workflow has exactly one failed state
            var failedStateCount = workflowConfiguration.States.Count(s => s.Type == StateTypeConfiguration.Initial);

            if (failedStateCount != 1)
            {
                AddValidationMessage(ref workflowConfigurationException, $"Workflow [{workflowConfiguration.Code}] must have exactly one failed state");
            }

            // 3. there are no state code duplicates
            var hasDuplicateState = workflowConfiguration.States
                                    .Any(s => workflowConfiguration.States.Any(si => si != s && string.Equals(si.Code, s.Code, StringComparison.OrdinalIgnoreCase)));

            if (hasDuplicateState)
            {
                AddValidationMessage(ref workflowConfigurationException, $"Workflow [{workflowConfiguration.Code}] must have unique states");
            }

            // 4. make sure that workflow has zero or exactly one parentToNestedInitial event
            var parentToNestedInitialEventCount = workflowConfiguration.Events.Count(e => e.Type == EventTypeConfiguration.ParentToNestedInitial);

            if (parentToNestedInitialEventCount > 1)
            {
                AddValidationMessage(ref workflowConfigurationException,
                                     $"Workflow [{workflowConfiguration.Code}] must have zero or exactly one [{EventTypeConfiguration.ParentToNestedInitial:G}] event");
            }

            // 5. there are no event code duplicates
            var hasDuplicateEvents = workflowConfiguration.Events
                                     .Any(e => workflowConfiguration.Events.Any(ei => ei != e && string.Equals(ei.Code, e.Code, StringComparison.OrdinalIgnoreCase)));

            if (hasDuplicateEvents)
            {
                AddValidationMessage(ref workflowConfigurationException, $"Workflow [{workflowConfiguration.Code}] must have unique events");
            }

            // 6. do not allow state to have events and incoming asynchronousImmediate transitions simultaneously
            var statesWithEvents             = workflowConfiguration.States.Where(s => s.Events.Any()).ToList();
            var transitionsToStateWithEvents = workflowConfiguration.States.SelectMany(s => s.Transitions)
                                               .Where(t => t.Type == TransitionTypeConfiguration.AsynchronousImmediate)
                                               .Where(t => statesWithEvents.Any(s => s.Code == t.MoveToState));

            if (transitionsToStateWithEvents.Any())
            {
                AddValidationMessage(ref workflowConfigurationException,
                                     $"Workflow [{workflowConfiguration.Code}] has state(s) with events and incoming async transitions");
            }

            // 7. do not allow duplicated event declaration for the same state
            var hasStatesWithDuplicatedEvent = statesWithEvents
                                               .Any(s => s.Events.Any(e => s.Events
                                                                      .Any(ei => ei != e && string.Equals(ei.Code, e.Code, StringComparison.OrdinalIgnoreCase))));

            if (hasStatesWithDuplicatedEvent)
            {
                AddValidationMessage(ref workflowConfigurationException, $"Workflow [{workflowConfiguration.Code}] has state(s) with duplicated events");
            }

            // 8. make sure that activity -> retryPolicy -> onFailureTransitionToUse refers to an existing transition within the state
            var statesWithCustomFailureTransitions = workflowConfiguration.States
                                                     .Where(s => s.Activities.Any(a => !string.IsNullOrEmpty(a.RetryPolicy.OnFailureTransitionToUse))).ToList();

            if (statesWithCustomFailureTransitions.Any())
            {
                var hasMissConfiguredCustomFailureTransitions = statesWithCustomFailureTransitions
                                                                .Any(s => s.Activities
                                                                     .Any(a => !string.IsNullOrEmpty(a.RetryPolicy.OnFailureTransitionToUse) && !s.Transitions
                                                                          .Any(t => string.Equals(t.MoveToState, a.RetryPolicy.OnFailureTransitionToUse))));
                if (hasMissConfiguredCustomFailureTransitions)
                {
                    AddValidationMessage(ref workflowConfigurationException,
                                         $"Workflow [{workflowConfiguration.Code}] has activity(s) with configured 'onFailureTransitionToUse' but state has no such transition");
                }
            }

            if (null != workflowConfigurationException)
            {
                throw workflowConfigurationException;
            }
        }