/// <inheritdoc />
        public ISerializedResult Serialize(IResult result, IContentTypeProvider contentTypeProvider)
        {
            switch (result)
            {
            case Report report:
                contentTypeProvider.SerializeCollection(new[] { report.ReportBody }, report.Body, report.Request);
                return(report);

            case Head head:
                head.Headers.EntityCount = head.EntityCount.ToString();
                return(head);

            case IEntities <object> entities:

                ISerializedResult SerializeEntities()
                {
                    var entityCount = contentTypeProvider.SerializeCollection((dynamic)entities, entities.Body, entities.Request);

                    if (entityCount == 0)
                    {
                        return(new NoContent(entities.Request));
                    }
                    entities.Body.Seek(0, SeekOrigin.Begin);
                    entities.Headers.EntityCount = entityCount.ToString();
                    entities.EntityCount         = entityCount;
                    if (entities.IsPaged)
                    {
                        var pager = entities.GetNextPageLink();
                        entities.Headers.Pager = pager.ToUriString();
                    }
                    entities.SetContentDisposition(contentTypeProvider.ContentDispositionFileExtension);
                    return(entities);
                }

                if (entities.Request.Headers.Destination == null)
                {
                    return(SerializeEntities());
                }
                try
                {
                    var parameters = new HeaderRequestParameters(entities.Request.Headers.Destination);
                    if (parameters.IsInternal)
                    {
                        var internalRequest    = entities.Context.CreateRequest(parameters.URI, parameters.Method, null, parameters.Headers);
                        var serializedEntities = SerializeEntities();
                        if (!(serializedEntities is Content content))
                        {
                            return(serializedEntities);
                        }
                        internalRequest.SetBody(content.Body);
                        return(internalRequest.Evaluate().Serialize());
                    }
                    var serialized      = SerializeEntities();
                    var externalRequest = new HttpRequest(serialized, parameters, serialized.Body);
                    var response        = externalRequest.GetResponseAsync().Result
                                          ?? throw new InvalidExternalDestination(externalRequest, "No response");
                    if (response.StatusCode >= HttpStatusCode.BadRequest)
                    {
                        throw new InvalidExternalDestination(externalRequest,
                                                             $"Received {response.StatusCode.ToCode()} - {response.StatusDescription}. {response.Headers.Info}");
                    }
                    if (serialized.Headers.AccessControlAllowOrigin is string h)
                    {
                        response.Headers.AccessControlAllowOrigin = h;
                    }
                    return(new ExternalDestinationResult(entities.Request, response));
                }
                catch (HttpRequestException re)
                {
                    throw new InvalidSyntax(ErrorCodes.InvalidDestination, $"{re.Message} in the Destination header");
                }

            default: return(result as ISerializedResult);
            }
        }
        private async Task SerializeContentDataCollection <T>(IAsyncEnumerable <T> dataCollection, Content content, ISerializedResult toSerialize,
                                                              IContentTypeProvider contentTypeProvider, CancellationToken cancellationToken) where T : class
        {
            content.SetContentDisposition(contentTypeProvider.ContentDispositionFileExtension);

            if (contentTypeProvider is not IJsonProvider jsonProvider)
            {
                await contentTypeProvider.SerializeCollection(dataCollection, toSerialize.Body, content.Request, cancellationToken).ConfigureAwait(false);

                return;
            }

            var swr = new StreamWriter(toSerialize.Body, Encoding.UTF8, 4096, true);

#if NETSTANDARD2_1
            await using (swr)
#else
            using (swr)
#endif
            {
                using var jwr = JsonProvider.GetJsonWriter(swr);
                await jwr.WriteStartObjectAsync(cancellationToken).ConfigureAwait(false);

                await jwr.WritePropertyNameAsync("Status", cancellationToken).ConfigureAwait(false);

                await jwr.WriteValueAsync("success", cancellationToken).ConfigureAwait(false);

                await jwr.WritePropertyNameAsync("ResourceType", cancellationToken).ConfigureAwait(false);

                await jwr.WriteValueAsync(content.ResourceType.FullName, cancellationToken).ConfigureAwait(false);

                await jwr.WritePropertyNameAsync("Data", cancellationToken).ConfigureAwait(false);

                var entityCount = await jsonProvider.SerializeCollection(dataCollection, jwr, cancellationToken).ConfigureAwait(false);

                toSerialize.EntityCount = entityCount;
                await jwr.WritePropertyNameAsync("DataCount", cancellationToken).ConfigureAwait(false);

                await jwr.WriteValueAsync(entityCount, cancellationToken).ConfigureAwait(false);

                if (content is IEntities entities)
                {
                    if (toSerialize.HasPreviousPage)
                    {
                        var previousPageLink = entities.GetPreviousPageLink(toSerialize.EntityCount);
                        await jwr.WritePropertyNameAsync("PreviousPage", cancellationToken).ConfigureAwait(false);

                        await jwr.WriteValueAsync(previousPageLink.ToUriString(), cancellationToken).ConfigureAwait(false);
                    }
                    if (toSerialize.HasNextPage)
                    {
                        var nextPageLink = entities.GetNextPageLink(toSerialize.EntityCount, -1);
                        await jwr.WritePropertyNameAsync("NextPage", cancellationToken).ConfigureAwait(false);

                        await jwr.WriteValueAsync(nextPageLink.ToUriString(), cancellationToken).ConfigureAwait(false);
                    }
                }
                await jwr.WritePropertyNameAsync("TimeElapsedMs", cancellationToken).ConfigureAwait(false);

                var milliseconds = toSerialize.TimeElapsed.GetRESTableElapsedMs();
                await jwr.WriteValueAsync(milliseconds, cancellationToken).ConfigureAwait(false);

                await jwr.WriteEndObjectAsync(cancellationToken).ConfigureAwait(false);

                if (entityCount == 0)
                {
                    content.MakeNoContent();
                }
            }
        }