public override async Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken, Dictionary <string, string> telemetryProperties = null, Dictionary <string, double> telemetryMetrics = null)
        {
            var dcState = dialogContext.GetState();

            // Identify matched intents
            var recognizerResult = new RecognizerResult()
            {
                Text    = activity.Text,
                Intents = new Dictionary <string, IntentScore>(),
            };

            if (string.IsNullOrEmpty(activity.Text))
            {
                recognizerResult.Intents.Add("None", new IntentScore());
                return(recognizerResult);
            }

            List <Metadata> filters = new List <Metadata>();

            if (IncludeDialogNameInMetadata.GetValue(dcState))
            {
                filters.Add(new Metadata()
                {
                    Name = "dialogName", Value = dialogContext.ActiveDialog.Id
                });
            }

            // if there is $qna.metadata set add to filters
            var externalMetadata = this.Metadata?.GetValue(dcState);

            if (externalMetadata != null)
            {
                filters.AddRange(externalMetadata);
            }

            // Calling QnAMaker to get response.
            var qnaClient = await GetQnAMakerClientAsync(dialogContext).ConfigureAwait(false);

            var answers = await qnaClient.GetAnswersAsync(
                dialogContext.Context,
                new QnAMakerOptions
            {
                Context        = this.Context?.GetValue(dcState),
                ScoreThreshold = this.Threshold.GetValue(dcState),
                StrictFilters  = filters.ToArray(),
                Top            = this.Top.GetValue(dcState),
                QnAId          = this.QnAId.GetValue(dcState),
                RankerType     = this.RankerType.GetValue(dcState),
                IsTest         = this.IsTest
            },
                null).ConfigureAwait(false);

            if (answers.Any())
            {
                QueryResult topAnswer = null;
                foreach (var answer in answers)
                {
                    if ((topAnswer == null) || (answer.Score > topAnswer.Score))
                    {
                        topAnswer = answer;
                    }
                }

                if (topAnswer.Answer.Trim().ToLower().StartsWith(IntentPrefix))
                {
                    recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }
                else
                {
                    recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore()
                    {
                        Score = topAnswer.Score
                    });
                }

                var answerArray = new JArray();
                answerArray.Add(topAnswer.Answer);
                ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray);

                var instance = new JArray();
                instance.Add(JObject.FromObject(topAnswer));
                ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance);

                recognizerResult.Properties["answers"] = answers;
            }
            else
            {
                recognizerResult.Intents.Add("None", new IntentScore()
                {
                    Score = 1.0f
                });
            }

            this.TelemetryClient.TrackEvent("QnAMakerRecognizerResult", this.FillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties), telemetryMetrics);

            return(recognizerResult);
        }
        public async override Task <RecognizerResult> RecognizeAsync(DialogContext dialogContext, Activity activity, CancellationToken cancellationToken = default, Dictionary <System.String, System.String> telemetryProperties = null, Dictionary <System.String, System.Double> telemetryMetrics = null)
        {
            var qluceneEngine = await QLuceneEngineCache.GetEngine(dialogContext, this.KnowledgeBase).ConfigureAwait(false);

            var threshold        = Threshold.GetValue(dialogContext);
            var recognizerResult = new RecognizerResult
            {
                Text    = activity.Text,
                Intents = new Dictionary <string, IntentScore>(),
            };

            if (string.IsNullOrEmpty(activity.Text))
            {
                recognizerResult.Intents.Add("None", new IntentScore());
                return(recognizerResult);
            }
            var  rankerType = RankerType?.GetValue(dialogContext.State);
            var  strictFiltersCompoundOperationType = StrictFiltersCompoundOperationType?.GetValue(dialogContext.State);
            var  strictFilters = new List <Metadata>();
            var  context       = Context?.GetValue(dialogContext.State);
            bool includeDialogNameInMetadata = IncludeDialogNameInMetadata.GetValue(dialogContext.State);

            if (includeDialogNameInMetadata)
            {
                strictFilters.Add(new Metadata
                {
                    Name  = "dialogName",
                    Value = dialogContext.ActiveDialog.Id
                });
            }

            // if there is $qna.metadata set add to filters
            var externalMetadata = StrictFilters?.GetValue(dialogContext.State);

            if (externalMetadata != null)
            {
                strictFilters.AddRange(externalMetadata);
            }

            var topAnswer = qluceneEngine.GetAnswers(activity.Text,
                                                     strictFilters: strictFilters.ToArray(),
                                                     context: context,
                                                     threshold: threshold,
                                                     rankerType: rankerType,
                                                     strictFiltersCompoundOperationType: strictFiltersCompoundOperationType);

            if (topAnswer != null)
            {
                if (topAnswer.Answer.Trim().ToUpperInvariant().StartsWith(IntentPrefix.ToUpperInvariant(), StringComparison.Ordinal))
                {
                    recognizerResult.Intents.Add(topAnswer.Answer.Trim().Substring(IntentPrefix.Length).Trim(), new IntentScore {
                        Score = topAnswer.Score
                    });
                }
                else
                {
                    recognizerResult.Intents.Add(QnAMatchIntent, new IntentScore {
                        Score = topAnswer.Score
                    });
                }

                var answerArray = new JArray();
                answerArray.Add(topAnswer.Answer);
                ObjectPath.SetPathValue(recognizerResult, "entities.answer", answerArray);

                var instance = new JArray();
                var data     = JObject.FromObject(topAnswer);
                data["startIndex"] = 0;
                data["endIndex"]   = activity.Text.Length;
                instance.Add(data);
                ObjectPath.SetPathValue(recognizerResult, "entities.$instance.answer", instance);

                // recognizerResult.Properties["answers"] = answers;
            }
            else
            {
                recognizerResult.Intents.Add("None", new IntentScore {
                    Score = 1.0f
                });
            }

            var traceInfo = new
            {
                recognizerResult,
                options = new
                {
                    id             = this.Id,
                    knowledgeBase  = this.KnowledgeBase,
                    scoreThreshold = threshold,
                    context,
                    rankerType,
                    strictFilters = strictFilters.ToArray(),
                    includeDialogNameInMetadata,
                    strictFiltersCompoundOperationType
                }
            };

            await dialogContext.Context.TraceActivityAsync(nameof(QLuceneRecognizer), traceInfo, TraceType, TraceLabel, cancellationToken).ConfigureAwait(false);

            return(recognizerResult);
        }