/// <summary>
            /// Gets the states.
            /// </summary>
            /// <param name="configuration">The configuration.</param>
            /// <returns></returns>
            /// <exception cref="Exception">
            /// Type '" + item.StateBehaviorClass + "' not found.
            /// or
            /// Type '" + item.StateBehaviorClass + "' is not IStateBehavior<" + typeof(FlowState).Name + ">.
            /// </exception>
            private static List <FlowState> GetStates(LuisConfiguration configuration)
            {
                int i      = 1;
                var states = new List <FlowState>();

                foreach (var item in configuration.LuisFlowStates)
                {
                    var state = new FlowState
                    {
                        Id             = i++,
                        Name           = item.Name,
                        IsInitialState = item.IsInitialState
                    };
                    if (item.StateBehaviorClass != null)
                    {
                        Type type = Type.GetType(item.StateBehaviorClass);
                        if (type == null)
                        {
                            throw new Exception("Type '" + item.StateBehaviorClass + "' not found.");
                        }

                        var isImplementing = type.GetInterfaces().Contains(typeof(IStateBehavior));
                        if (!isImplementing)
                        {
                            throw new Exception("Type '" + item.StateBehaviorClass + "' is not IStateBehavior.");
                        }

                        state.BehaviorType = type;
                    }

                    states.Add(state);
                }

                return(states);
            }
            /// <summary>
            /// Converts the specified configuration.
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="configuration">The configuration.</param>
            /// <returns></returns>
            public static LuisFlowConfiguration <FlowState> Convert(LuisConfiguration configuration)
            {
                LuisFlowConfiguration <FlowState> config = new LuisFlowConfiguration <FlowState>();

                config.States = GetStates(configuration);
                var count = config.States.Count(x => x.IsInitialState);

                if (count == 0)
                {
                    throw new Exception("An initial state is required.");
                }
                else if (count > 1)
                {
                    throw new Exception("Only one initial state is needed.");
                }

                config.Transitions = GetTransitions(config.States, configuration);
                return(config);
            }
            /// <summary>
            /// Gets the transitions.
            /// </summary>
            /// <param name="flowStates">The flow states.</param>
            /// <param name="configuration">The configuration.</param>
            /// <returns></returns>
            /// <exception cref="Exception">
            /// </exception>
            private static List <StateTransition <FlowState, string, LanguageUnderstandingResult> > GetTransitions(IEnumerable <FlowState> flowStates, LuisConfiguration configuration)
            {
                var transitions = new List <StateTransition <FlowState, string, LanguageUnderstandingResult> >();

                foreach (var luisFlowStateTransition in configuration.LuisFlowStateTransitions)
                {
                    CognitiveServices.LanguageUnderstanding.Conditions.IConditionOperator <LanguageUnderstandingResult> op = null;
                    if (luisFlowStateTransition.Condition != null)
                    {
                        var inputAndOperator = luisFlowStateTransition.Condition.AndOperator;
                        if (inputAndOperator != null)
                        {
                            op = ProcessAndOperator(inputAndOperator);
                        }
                        var inputOrOperator = luisFlowStateTransition.Condition.OrOperator;
                        if (inputOrOperator != null)
                        {
                            op = ProcessOrOperator(inputOrOperator);
                        }
                        var entityEquals = luisFlowStateTransition.Condition.IsEntityEquals;
                        if (entityEquals != null)
                        {
                            op = ProcessIsEntityEqualsOperator(entityEquals);
                        }
                    }

                    var currentState = flowStates.FirstOrDefault(x => x.Name == luisFlowStateTransition.CurrentState.Name);
                    if (currentState == null)
                    {
                        throw new Exception($"Current state '{luisFlowStateTransition.CurrentState}' is not defined among the states.");
                    }

                    var nextState = flowStates.FirstOrDefault(x => x.Name == luisFlowStateTransition.NextState.Name);
                    if (nextState == null)
                    {
                        throw new Exception($"Next state '{luisFlowStateTransition.CurrentState}' is not defined among the states.");
                    }

                    var transition = new LuisFlowStateTransition <FlowState>(currentState, nextState, luisFlowStateTransition.Intent, luisFlowStateTransition.IsFinalState, op);
                    transitions.Add(transition);
                }

                return(transitions);
            }