public virtual async Task <SearchResponse <T> > SearchAsync(SearchRequest request,
                                                                    CancellationToken cancellationToken)
        {
            // Validate parameters.
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            // Validate search request.
            request.Validate();

            // Create the pre and post tag for highlighting.
            string preAndPostTag = CreatePreAndPostTag();

            // Search.
            ISearchResponse <T> response = await ElasticClient.SearchAsync <T>(
                d => d.UpdateSearchDescriptor(Index, request, preAndPostTag), cancellationToken).ConfigureAwait(false);

            // Validate the response.
            response.ThrowIfError();

            // Create a copy of pre and post tag.
            var preAndPostTagCopy = preAndPostTag;

            // Return the response.
            return(new SearchResponse <T> {
                Request = request,
                MaximumScore = (decimal)response.MaxScore,
                TotalHits = (int)response.Total,
                Hits = response.Hits.Select(h => h.ToHit(preAndPostTagCopy)).ToReadOnlyCollection()
            });
        }