/// <summary>
        /// Creates an instance of the output context for this format.
        /// </summary>
        /// <param name="message">The message to use.</param>
        /// <param name="mediaType">The specific media type being written.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>Task which represents the pending create operation.</returns>
        internal override Task <ODataOutputContext> CreateOutputContextAsync(
            ODataMessage message,
            MediaType mediaType,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(message, "message");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataOutputContext) new ODataJsonLightOutputContext(
                           this,
                           streamTask.Result,
                           mediaType,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           /*synchronous*/ false,
                           model,
                           urlResolver)));
        }
        /// <summary>
        /// Asynchronously create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>Task which when completed returns the newly created output context.</returns>
        internal static Task <ODataOutputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataOutputContext) new ODataAtomOutputContext(
                           format,
                           streamTask.Result,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           false,
                           model,
                           urlResolver)));
        }
        /// <summary>
        /// Asynchronously creates an instance of the input context for this format.
        /// </summary>
        /// <param name="readerPayloadKind">The <see cref="ODataPayloadKind"/> to read.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="contentType">The content type of the message to read.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        /// <param name="payloadKindDetectionFormatState">Format specific state stored during payload kind detection
        /// using the <see cref="ODataPayloadKindDetectionInfo.SetPayloadKindDetectionFormatState"/>.</param>
        /// <returns>Task which when completed returned the newly created input context.</returns>
        internal override Task <ODataInputContext> CreateInputContextAsync(
            ODataPayloadKind readerPayloadKind,
            ODataMessage message,
            MediaType contentType,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver,
            object payloadKindDetectionFormatState)
        {
            ExceptionUtils.CheckArgumentNotNull(message, "message");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataInputContext) new ODataJsonLightInputContext(
                           this,
                           streamTask.Result,
                           contentType,
                           encoding,
                           messageReaderSettings,
                           version,
                           readingResponse,
                           /*synchronous*/ false,
                           model,
                           urlResolver,
                           (ODataJsonLightPayloadKindDetectionState)payloadKindDetectionFormatState)));
        }
        /// <summary>
        /// Asynchronously create JSON input context.
        /// </summary>
        /// <param name="format">The format for the input context.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        /// <returns>Task which when completed returns the newly created input context.</returns>
        internal static Task <ODataInputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataInputContext) new ODataJsonInputContext(
                           format,
                           streamTask.Result,
                           encoding,
                           messageReaderSettings,
                           version,
                           readingResponse,
                           false,
                           model,
                           urlResolver)));
        }
        /// <summary>
        /// Asynchronously detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task that when completed returns the set of <see cref="ODataPayloadKind"/>s
        /// that are supported with the specified payload.</returns>
        internal override Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(
            IODataRequestMessageAsync requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            // NOTE: After getting the message stream we already (asynchronously) buffered the whole stream in memory (in the BufferedReadStream).
            //       Until we get Task-based async stream APIs and retire the BufferedReadStream, we call the synchronous method on the buffered stream.
            ODataMessage message = (ODataMessage)requestMessage;

            return(message.GetStreamAsync()
                   .FollowOnSuccessWithTask(streamTask => this.DetectPayloadKindImplementationAsync(
                                                streamTask.Result,
                                                message,
                                                /*readingResponse*/ false,
                                                detectionInfo)));
        }
 internal static Task <ODataInputContext> CreateAsync(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, IEdmModel model, IODataUrlResolver urlResolver)
 {
     return(message.GetStreamAsync().FollowOnSuccessWith <Stream, ODataInputContext>(streamTask => new ODataJsonInputContext(format, streamTask.Result, encoding, messageReaderSettings, version, readingResponse, false, model, urlResolver)));
 }
        /// <summary>
        /// Asynchronously create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>Task which when completed returns the newly created output context.</returns>
        internal static Task<ODataOutputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            return message.GetStreamAsync()
                .FollowOnSuccessWith(
                    (streamTask) => (ODataOutputContext)new ODataAtomOutputContext(
                        format,
                        streamTask.Result,
                        encoding,
                        messageWriterSettings,
                        writingResponse,
                        false,
                        model,
                        urlResolver));
        }
 internal static Task <ODataOutputContext> CreateAsync(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, IEdmModel model, IODataUrlResolver urlResolver)
 {
     return(message.GetStreamAsync().FollowOnSuccessWith <Stream, ODataOutputContext>(streamTask => new ODataAtomOutputContext(format, streamTask.Result, encoding, messageWriterSettings, writingResponse, false, model, urlResolver)));
 }