private static async Task <DialogTurnResult> CheckSearchEntitiesAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            Luis.searchskillLuis._Entities ents = (Luis.searchskillLuis._Entities)stepContext.Options;
            stepContext.Values["subject"] = ents.subject;
            stepContext.Values["time"]    = ents.datetime;

            if (stepContext.Values["subject"] == null)
            {
                return(await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please enter the course name.") }, cancellationToken));
            }

            else if (stepContext.Values["time"] != null)
            {
                await stepContext.Context.SendActivityAsync(MessageFactory.Text("Searching for available tutors..."), cancellationToken);

                //put this in adaptive card i guess
                Database db = new Database();
                //
                //
                //IMPORTANT: Time string format: "YYYY-MM-DDTHH" (e.g. "2019-11-11T16" where T16 = 16:00 hour)
                Microsoft.Bot.Builder.AI.Luis.DateTimeSpec[] time = (Microsoft.Bot.Builder.AI.Luis.DateTimeSpec[])stepContext.Values["time"];
                db.findTutors_SubjectTime(db.convertBotTimeToString(time), db.normalizeCourseName(stepContext.Values["subject"].ToString()));
                //////
                return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken));
            }

            else
            {
                return(await stepContext.ContinueDialogAsync());
            }
        }
        protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Get cognitive models for locale
            var locale          = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
            var cognitiveModels = _services.CognitiveModelSets[locale];

            // Check dispatch result
            var dispatchResult = await cognitiveModels.DispatchService.RecognizeAsync <DispatchLuis>(dc.Context, CancellationToken.None);

            var intent = dispatchResult.TopIntent().intent;
            var test   = dispatchResult.Entities;

            Console.WriteLine(test.ToString());

            // Identify if the dispatch intent matches any Action within a Skill if so, we pass to the appropriate SkillDialog to hand-off
            var identifiedSkill = SkillRouter.IsSkill(_settings.Skills, intent.ToString());


            if (identifiedSkill != null)
            {
                // We have identiifed a skill so initialize the skill connection with the target skill
                Console.WriteLine("Found a skill! " + intent.ToString());
                var result = await dc.BeginDialogAsync(identifiedSkill.Id);

                if (result.Status == DialogTurnStatus.Complete)
                {
                    await CompleteAsync(dc);
                }
            }
            else if (intent == DispatchLuis.Intent.l_General)
            {
                // If dispatch result is General luis model
                cognitiveModels.LuisServices.TryGetValue("General", out var luisService);

                if (luisService == null)
                {
                    throw new Exception("The General LUIS Model could not be found in your Bot Services configuration.");
                }
                else
                {
                    var result = await luisService.RecognizeAsync <GeneralLuis>(dc.Context, CancellationToken.None);

                    var generalIntent = result?.TopIntent().intent;

                    // switch on general intents
                    switch (generalIntent)
                    {
                    case GeneralLuis.Intent.Escalate:
                    {
                        // start escalate dialog
                        await dc.BeginDialogAsync(nameof(EscalateDialog));

                        break;
                    }

                    case GeneralLuis.Intent.None:
                    default:
                    {
                        // No intent was identified, send confused message
                        _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                        var name = _state.ConfuseCounter++;
                        await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                        await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);

                        break;
                    }
                    }
                }
            }
            else if (intent == DispatchLuis.Intent.l_searchskill)
            {
                // If dispatch result is General luis model
                cognitiveModels.LuisServices.TryGetValue("searchskill", out var luisService);

                if (luisService == null)
                {
                    throw new Exception("The General LUIS Model could not be found in your Bot Services configuration.");
                }
                else
                {
                    var result = await luisService.RecognizeAsync <searchskillLuis>(dc.Context, CancellationToken.None);

                    // to pass in BeginDialogAsync
                    Luis.searchskillLuis._Entities entities = result.Entities;
                    var searchIntent = result?.TopIntent().intent;

                    // switch on general intents
                    switch (searchIntent)
                    {
                    case searchskillLuis.Intent.Search_by_Subject:
                    {
                        // start escalate dialog
                        await dc.BeginDialogAsync(nameof(Search_by_Subject), entities);

                        break;
                    }

                    case searchskillLuis.Intent.Search_by_Tutor:
                    {
                        await dc.BeginDialogAsync(nameof(Search_by_Tutor), entities.personName);

                        break;
                    }

                    case searchskillLuis.Intent.None:
                    default:
                    {
                        // No intent was identified, send confused message
                        _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                        var name = _state.ConfuseCounter++;
                        await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                        await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);

                        break;
                    }
                    }
                }
            }
            else if (intent == DispatchLuis.Intent.l_profileskill)
            {
                // If dispatch result is General luis model
                cognitiveModels.LuisServices.TryGetValue("profileskill", out var luisService);

                if (luisService == null)
                {
                    throw new Exception("The General LUIS Model could not be found in your Bot Services configuration.");
                }
                else
                {
                    var result = await luisService.RecognizeAsync <profileskillLuis>(dc.Context, CancellationToken.None);

                    var profileIntent = result?.TopIntent().intent;

                    // switch on general intents
                    switch (profileIntent)
                    {
                    case profileskillLuis.Intent.Edit_Profile:
                    {
                        // start edit dialog
                        await dc.BeginDialogAsync(nameof(Edit_Profile));

                        break;
                    }

                    case profileskillLuis.Intent.None:
                    default:
                    {
                        // No intent was identified, send confused message
                        _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                        var name = _state.ConfuseCounter++;
                        await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                        await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);

                        break;
                    }
                    }
                }
            }
            else if (intent == DispatchLuis.Intent.q_Faq)
            {
                cognitiveModels.QnAServices.TryGetValue("Faq", out var qnaService);

                if (qnaService == null)
                {
                    throw new Exception("The specified QnA Maker Service could not be found in your Bot Services configuration.");
                }
                else
                {
                    var answers = await qnaService.GetAnswersAsync(dc.Context, null, null);

                    if (answers != null && answers.Count() > 0)
                    {
                        await dc.Context.SendActivityAsync(answers[0].Answer, speak : answers[0].Answer);
                    }
                    else
                    {
                        _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                        var name = _state.ConfuseCounter++;
                        await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                        await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);
                    }
                }
            }
            else if (intent == DispatchLuis.Intent.q_Chitchat)
            {
                cognitiveModels.QnAServices.TryGetValue("Chitchat", out var qnaService);

                if (qnaService == null)
                {
                    throw new Exception("The specified QnA Maker Service could not be found in your Bot Services configuration.");
                }
                else
                {
                    var answers = await qnaService.GetAnswersAsync(dc.Context, null, null);

                    if (answers != null && answers.Count() > 0)
                    {
                        await dc.Context.SendActivityAsync(answers[0].Answer, speak : answers[0].Answer);
                    }
                    else
                    {
                        _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                        var name = _state.ConfuseCounter++;
                        await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                        await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);
                    }
                }
            }
            else
            {
                // If dispatch intent does not map to configured models, send "confused" response.
                // Alternatively as a form of backup you can try QnAMaker for anything not understood by dispatch.
                _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                var name = _state.ConfuseCounter++;
                await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);
            }


            if (_state.ConfuseCounter >= 3)
            {
                _state = await _onboardingState.GetAsync(dc.Context, () => new OnboardingState());

                var name = _state.ConfuseCounter = 0;
                await _onboardingState.SetAsync(dc.Context, _state, cancellationToken);

                await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Help);
            }
        }