public async Task ProcessAsync(SearchResultHandlerContext context)
        {
            await Task.Yield();

            foreach (var searchResult in context.SearchResults)
            {
                string entityName = searchResult.Document[Document.EntityNameFieldName].ToString();

                if (entityName != Document.MetadataEntityName)
                {
                    continue;
                }

                foreach (var highlight in searchResult.Highlights)
                {
                    foreach (string fragment in highlight.Value)
                    {
                        foreach (var fragmentToken in FragmentHelper.GetTokensFromFragment(fragment, context.SearchParameters.HighlightPreTag, context.SearchParameters.HighlightPostTag))
                        {
                            //
                            // Question: what if the same word shows in multiple positions?
                            //
                            var searchToken = context.SearchTokens.FirstOrDefault(p => StringComparer.OrdinalIgnoreCase.Equals(p.Token, fragmentToken.Token));

                            if (searchToken == null)
                            {
                                _logger.LogWarning($"Token value '{fragmentToken.Token}' isn't matched.");
                                continue;
                            }

                            //
                            // Question: why offset is nullable?
                            //
                            string matchedText = context.SearchText[(int)searchToken.StartOffset..(int)searchToken.EndOffset];
        private IEnumerable <(string, int)> FindMatchedTexts(SearchResultHandlerContext context, string fragment)
        {
            var fragmentTokens = FragmentHelper.GetTokensFromFragment(fragment, context.SearchParameters.HighlightPreTag, context.SearchParameters.HighlightPostTag);

            var fragmentTokenBindings = CreateTokenBindings(fragmentTokens.ToList(), context.SearchTokens);

            for (int length = fragmentTokenBindings.Count; length > 0; length--)
            {
                for (int index = 0; index + length - 1 < fragmentTokenBindings.Count; index++)
                {
                    var startFragmentTokenBindings = fragmentTokenBindings[index];
                    var endFragmentTokenBindings   = fragmentTokenBindings[index + length - 1];

                    if (startFragmentTokenBindings == endFragmentTokenBindings)
                    {
                        foreach (var startSearchToken in startFragmentTokenBindings.SearchTokens)
                        {
                            yield return(context.SearchText[((int)startSearchToken.StartOffset)..((int)startSearchToken.EndOffset)], (int)startSearchToken.StartOffset);