/// <summary>
        /// Creates the result object for the specified query parameters.
        /// </summary>
        /// <param name="source">The source object for the request.</param>
        /// <param name="context">The data service context.</param>
        /// <param name="callback">The AsyncCallback delegate.</param>
        /// <param name="state">The state object for the callback.</param>
        /// <param name="method">async method name at the source.</param>
        /// <returns>Result representing the create request. The request has not been initiated yet.</returns>
        private QueryResult CreateExecuteResult(object source, DataServiceContext context, AsyncCallback callback, object state, string method)
        {
            Debug.Assert(context != null, "context is null");

            QueryComponents qc          = this.QueryComponents(context.Model);
            RequestInfo     requestInfo = new RequestInfo(context);

            Debug.Assert(
                string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0 ||
                string.CompareOrdinal(XmlConstants.HttpMethodGet, qc.HttpMethod) == 0 ||
                string.CompareOrdinal(XmlConstants.HttpMethodDelete, qc.HttpMethod) == 0,
                "Only get, post and delete are supported in the execute pipeline, which should have been caught earlier");

            if (qc.UriOperationParameters != null)
            {
                Debug.Assert(qc.UriOperationParameters.Any(), "qc.UriOperationParameters.Any()");
                Serializer serializer = new Serializer(requestInfo);
                this.RequestUri = serializer.WriteUriOperationParametersToUri(this.RequestUri, qc.UriOperationParameters);
            }

            HeaderCollection headers = new HeaderCollection();

            if (string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0)
            {
                if (qc.BodyOperationParameters == null)
                {
                    // set the content length to be 0 if there are no operation parameters.
                    headers.SetHeader(XmlConstants.HttpContentLength, "0");
                }
                else
                {
                    context.Format.SetRequestContentTypeForOperationParameters(headers);
                }
            }

            // Validate and set the request DSV and MDSV header
            headers.SetRequestVersion(qc.Version, requestInfo.MaxProtocolVersionAsVersion);

            requestInfo.Format.SetRequestAcceptHeaderForQuery(headers, qc);

            // We currently do not have a descriptor to expose to the user for invoking something through Execute. Ideally we could expose an OperationDescriptor.
            ODataRequestMessageWrapper requestMessage = new RequestInfo(context).WriteHelper.CreateRequestMessage(context.CreateRequestArgsAndFireBuildingRequest(qc.HttpMethod, this.RequestUri, headers, context.HttpStack, null /*descriptor*/));

            requestMessage.FireSendingRequest2(null /*descriptor*/);

            if (qc.BodyOperationParameters != null)
            {
                Debug.Assert(string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0, "qc.HttpMethod == XmlConstants.HttpMethodPost");
                Debug.Assert(qc.BodyOperationParameters.Any(), "unexpected body operation parameter count of zero.");

                Serializer serializer = new Serializer(requestInfo, context.EntityParameterSendOption);
                serializer.WriteBodyOperationParameters(qc.BodyOperationParameters, requestMessage);

                // pass in the request stream so that request payload can be written to the http webrequest.
                return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state, requestMessage.CachedRequestStream));
            }

            return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state));
        }
        /// <summary>
        /// Loads the metadata and converts it into an EdmModel that is then used by a dataservice context
        /// This allows the user to use the DataServiceContext directly without having to manually pass an IEdmModel in the Format
        /// </summary>
        /// <returns>A service model to be used in format tracking</returns>
        internal IEdmModel LoadServiceModelFromNetwork()
        {
            HttpWebRequestMessage    httpRequest;
            BuildingRequestEventArgs requestEventArgs = null;

            // test hook for injecting a network request to use instead of the default
            if (InjectMetadataHttpNetworkRequest != null)
            {
                httpRequest = InjectMetadataHttpNetworkRequest();
            }
            else
            {
                requestEventArgs = new BuildingRequestEventArgs(
                    "GET",
                    context.GetMetadataUri(),
                    null,
                    null,
                    context.HttpStack);

                // fire the right events if they exist to allow user to modify the request
                if (context.HasBuildingRequestEventHandlers)
                {
                    requestEventArgs = context.CreateRequestArgsAndFireBuildingRequest(
                        requestEventArgs.Method,
                        requestEventArgs.RequestUri,
                        requestEventArgs.HeaderCollection,
                        requestEventArgs.ClientHttpStack,
                        requestEventArgs.Descriptor);
                }

                DataServiceClientRequestMessageArgs args = new DataServiceClientRequestMessageArgs(
                    requestEventArgs.Method,
                    requestEventArgs.RequestUri,
                    context.UseDefaultCredentials,
                    context.UsePostTunneling,
                    requestEventArgs.Headers);

                httpRequest = new HttpWebRequestMessage(args);
            }

            Descriptor descriptor = requestEventArgs != null ? requestEventArgs.Descriptor : null;

            // fire the right events if they exist
            if (context.HasSendingRequest2EventHandlers)
            {
                SendingRequest2EventArgs eventArgs = new SendingRequest2EventArgs(
                    httpRequest,
                    descriptor,
                    false);

                context.FireSendingRequest2(eventArgs);
            }

            Task <IODataResponseMessage> asyncResponse =
                Task <IODataResponseMessage> .Factory.FromAsync(httpRequest.BeginGetResponse, httpRequest.EndGetResponse,
                                                                httpRequest);

            IODataResponseMessage response = asyncResponse.GetAwaiter().GetResult();

            ReceivingResponseEventArgs responseEvent = new ReceivingResponseEventArgs(response, descriptor);

            context.FireReceivingResponseEvent(responseEvent);

            using (StreamReader streamReader = new StreamReader(response.GetStream()))
                using (XmlReader xmlReader = XmlReader.Create(streamReader))
                {
                    return(CsdlReader.Parse(xmlReader));
                }
        }
        /// <summary>
        /// Synchronizely get the query set count from the server by executing the $count=value query
        /// </summary>
        /// <param name="context">The context</param>
        /// <returns>The server side count of the query set</returns>
        internal long GetQuerySetCount(DataServiceContext context)
        {
            Debug.Assert(null != context, "context is null");
            Version requestVersion = this.QueryComponents(context.Model).Version;

            if (requestVersion == null)
            {
                requestVersion = Util.ODataVersion4;
            }

            QueryResult               response       = null;
            QueryComponents           qc             = this.QueryComponents(context.Model);
            Uri                       requestUri     = qc.Uri;
            DataServiceRequest <long> serviceRequest = new DataServiceRequest <long>(requestUri, qc, null);

            HeaderCollection headers = new HeaderCollection();

            // Validate and set the request DSV header
            headers.SetRequestVersion(requestVersion, context.MaxProtocolVersionAsVersion);
            context.Format.SetRequestAcceptHeaderForCount(headers);

            string httpMethod = XmlConstants.HttpMethodGet;
            ODataRequestMessageWrapper request = context.CreateODataRequestMessage(
                context.CreateRequestArgsAndFireBuildingRequest(httpMethod, requestUri, headers, context.HttpStack, null /*descriptor*/),
                null /*descriptor*/);

            response = new QueryResult(this, Util.ExecuteMethodName, serviceRequest, request, new RequestInfo(context), null, null);

            try
            {
                response.ExecuteQuery();

                if (HttpStatusCode.NoContent != response.StatusCode)
                {
                    StreamReader sr = new StreamReader(response.GetResponseStream());
                    long         r  = -1;
                    try
                    {
                        r = XmlConvert.ToInt64(sr.ReadToEnd());
                    }
                    finally
                    {
                        sr.Close();
                    }

                    return(r);
                }
                else
                {
                    throw new DataServiceQueryException(Strings.DataServiceRequest_FailGetCount, response.Failure);
                }
            }
            catch (InvalidOperationException ex)
            {
                QueryOperationResponse operationResponse = null;
                operationResponse = response.GetResponse <long>(MaterializeAtom.EmptyResults);
                if (null != operationResponse)
                {
                    operationResponse.Error = ex;
                    throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, operationResponse);
                }

                throw;
            }
        }