/// <summary>
        /// Initializes a new instance of the <see cref="PartitionKeyRangeBatchResponse"/> class.
        /// </summary>
        /// <param name="originalOperationsCount">Original operations that generated the server responses.</param>
        /// <param name="serverResponse">Response from the server.</param>
        /// <param name="serializer">Serializer to deserialize response resource body streams.</param>
        internal PartitionKeyRangeBatchResponse(
            int originalOperationsCount,
            BatchResponse serverResponse,
            CosmosSerializer serializer)
        {
            this.StatusCode = serverResponse.StatusCode;

            this.ServerResponse          = serverResponse;
            this.resultsByOperationIndex = new BatchOperationResult[originalOperationsCount];

            StringBuilder             errorMessageBuilder = new StringBuilder();
            List <string>             activityIds         = new List <string>();
            List <ItemBatchOperation> itemBatchOperations = new List <ItemBatchOperation>();

            // We expect number of results == number of operations here
            for (int index = 0; index < serverResponse.Operations.Count; index++)
            {
                int operationIndex = serverResponse.Operations[index].OperationIndex;
                if (this.resultsByOperationIndex[operationIndex] == null ||
                    this.resultsByOperationIndex[operationIndex].StatusCode == (HttpStatusCode)StatusCodes.TooManyRequests)
                {
                    this.resultsByOperationIndex[operationIndex] = serverResponse[index];
                }
            }

            itemBatchOperations.AddRange(serverResponse.Operations);
            this.RequestCharge += serverResponse.RequestCharge;

            if (!string.IsNullOrEmpty(serverResponse.ErrorMessage))
            {
                errorMessageBuilder.AppendFormat("{0}; ", serverResponse.ErrorMessage);
            }

            this.ActivityId   = serverResponse.ActivityId;
            this.ErrorMessage = errorMessageBuilder.Length > 2 ? errorMessageBuilder.ToString(0, errorMessageBuilder.Length - 2) : null;
            this.Operations   = itemBatchOperations;
            this.Serializer   = serializer;
        }
        internal static async Task <BatchResponse> FromResponseMessageAsync(
            ResponseMessage responseMessage,
            ServerBatchRequest serverRequest,
            CosmosSerializer serializer)
        {
            using (responseMessage)
            {
                BatchResponse response = null;
                if (responseMessage.IsSuccessStatusCode && responseMessage.Content != null)
                {
                    response = await BatchResponse.PopulateFromContentAsync(responseMessage, serverRequest, serializer);

                    if (response == null)
                    {
                        // Convert any payload read failures as InternalServerError
                        response = new BatchResponse(
                            HttpStatusCode.InternalServerError,
                            SubStatusCodes.Unknown,
                            ClientResources.ServerResponseDeserializationFailure,
                            responseMessage.Headers.RequestCharge,
                            responseMessage.Headers.RetryAfter,
                            responseMessage.Headers.ActivityId,
                            serverRequest,
                            serializer);
                    }
                }
                else
                {
                    response = new BatchResponse(
                        responseMessage.StatusCode,
                        responseMessage.Headers.SubStatusCode,
                        responseMessage.ErrorMessage,
                        responseMessage.Headers.RequestCharge,
                        responseMessage.Headers.RetryAfter,
                        responseMessage.Headers.ActivityId,
                        serverRequest,
                        serializer);
                }

                if (response.results == null || response.results.Count != serverRequest.Operations.Count)
                {
                    if (responseMessage.IsSuccessStatusCode)
                    {
                        // Server should be guaranteeing number of results equal to operations when
                        // batch request is successful - so fail as InternalServerError if this is not the case.
                        response = new BatchResponse(
                            HttpStatusCode.InternalServerError,
                            SubStatusCodes.Unknown,
                            ClientResources.InvalidServerResponse,
                            responseMessage.Headers.RequestCharge,
                            responseMessage.Headers.RetryAfter,
                            responseMessage.Headers.ActivityId,
                            serverRequest,
                            serializer);
                    }

                    // When the overall response status code is TooManyRequests, propagate the RetryAfter into the individual operations.
                    int retryAfterMilliseconds = 0;

                    if ((int)responseMessage.StatusCode == (int)StatusCodes.TooManyRequests)
                    {
                        if (!responseMessage.Headers.TryGetValue(HttpConstants.HttpHeaders.RetryAfterInMilliseconds, out string retryAfter) ||
                            retryAfter == null ||
                            !int.TryParse(retryAfter, out retryAfterMilliseconds))
                        {
                            retryAfterMilliseconds = 0;
                        }
                    }

                    response.results = new List <BatchOperationResult>();
                    for (int i = 0; i < serverRequest.Operations.Count; i++)
                    {
                        response.results.Add(
                            new BatchOperationResult(response.StatusCode)
                        {
                            SubStatusCode = response.SubStatusCode,
                            RetryAfter    = TimeSpan.FromMilliseconds(retryAfterMilliseconds),
                        });
                    }
                }

                return(response);
            }
        }