/// <summary>
        /// Associates a local operation with the incoming method.
        /// </summary>
        /// <param name="message">The incoming <see cref="Message"/> to be associated with an operation.</param>
        /// <returns>The name of the operation to be associated with the message.</returns>
        string IDispatchOperationSelector.SelectOperation(ref Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            HttpRequestMessage requestMessage = message.ToHttpRequestMessage();
            if (requestMessage == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.HttpOperationSelectorNullRequest,
                        this.GetType().Name));
            }

            string operation = this.SelectOperation(requestMessage);
            if (operation == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.HttpOperationSelectorNullOperation,
                        this.GetType().Name));
            }

            return operation;
        }
        /// <summary>
        /// Called after an inbound message has been received but before the message
        /// is dispatched to the intended operation.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="channel">The incoming channel.</param>
        /// <param name="instanceContext">The current service instance.</param>
        /// <returns>The object used to correlate state. This object is passed back 
        /// in the <see cref="BeforeSendReply(ref Message, Object)"/> method.</returns>
        object IDispatchMessageInspector.AfterReceiveRequest(
            ref Message request,
            IClientChannel channel,
            InstanceContext instanceContext)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            HttpRequestMessage httpRequest = request.ToHttpRequestMessage();

            if (httpRequest == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.HttpMessageInspectorNullRequest,
                        this.GetType().Name));
            }

            return this.AfterReceiveRequest(httpRequest);
        }
        /// <summary>
        /// Returns a service object given the specified <see cref="InstanceContext"/> object.
        /// </summary>
        /// <param name="instanceContext">he current <see cref="InstanceContext"/> object.</param>
        /// <param name="message">The message that triggered the creation of a service object.</param>
        /// <returns>The service object.</returns>
        object IInstanceProvider.GetInstance(InstanceContext instanceContext, Message message)
        {
            if (instanceContext == null)
            {
                throw new ArgumentNullException("instanceContext");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            HttpRequestMessage request = message.ToHttpRequestMessage();
            if (request == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.HttpInstanceProviderNullRequest,
                        this.GetType().Name));
            }

            return this.GetInstance(instanceContext, request);
        }
        /// <summary>
        /// Deserializes a message into an array of parameters.
        /// </summary>
        /// <param name="message">The incoming message.</param>
        /// <param name="parameters">The objects that are passed to the operation as parameters.</param>
        void IDispatchMessageFormatter.DeserializeRequest(Message message, object[] parameters)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            HttpRequestMessage request = message.ToHttpRequestMessage();
            if (request == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.HttpMessageFormatterNullRequest,
                        this.GetType().Name));
            }

            this.DeserializeRequest(request, parameters);
        }
        private static Message ConfigureRequestMessage(Message message)
        {
            if (message == null)
            {
                return null;
            }

            HttpRequestMessageProperty requestProperty = message.GetHttpRequestMessageProperty();
            if (requestProperty == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        SR.RequestMissingHttpRequestMessageProperty,
                        HttpRequestMessageProperty.Name,
                        typeof(HttpRequestMessageProperty).FullName));
            }

            Uri uri = message.Headers.To;
            if (uri == null)
            {
                throw new InvalidOperationException(SR.RequestMissingToHeader);
            }

            HttpRequestMessage httpRequestMessage = message.ToHttpRequestMessage();
            if (httpRequestMessage == null)
            {
                httpRequestMessage = new HttpRequestMessage();
                httpRequestMessage.Content = new StringContent(String.Empty);
                httpRequestMessage.Content.Headers.ContentLength = 0;
                message.Close();
                message = httpRequestMessage.ToMessage();
            }
            else
            {
                message.Headers.Clear();
                message.Properties.Clear();
                httpRequestMessage.Headers.Clear();
                httpRequestMessage.GetProperties().Clear();
            }

            message.Headers.To = uri;

            httpRequestMessage.RequestUri = uri;
            httpRequestMessage.Method = new HttpMethod(requestProperty.Method);

            foreach (var headerName in requestProperty.Headers.AllKeys)
            {
                if (headerName.StartsWith("content-", StringComparison.OrdinalIgnoreCase) ||
                    headerName.Equals("Allow", StringComparison.OrdinalIgnoreCase) ||
                    headerName.Equals("Expires") ||
                    headerName.Equals("Expires", StringComparison.OrdinalIgnoreCase))
                {
                    httpRequestMessage.Content.Headers.Remove(headerName);
                    httpRequestMessage.Content.Headers.Add(headerName, requestProperty.Headers[headerName]);
                    continue;
                }

                httpRequestMessage.Headers.Remove(headerName);
                httpRequestMessage.Headers.Add(headerName, requestProperty.Headers[headerName]);
            }

            return message;
        }