internal ResponseMediaTypeMatch SelectResponseMediaType(Type type, HttpRequestMessage request)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

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

            if (!CanWriteType(type))
            {
                return(null);
            }

            // Determine the best character encoding if we have any registered encoders.
            // Note that it is ok for a formatter not to register any encoders in case it doesn't
            // do any structured reading or writing.
            Encoding characterEncodingMatch = SupportedEncodings.Any() ? SelectResponseCharacterEncoding(request) : null;

            // Determine the best media type
            MediaTypeMatch mediaTypeMatch = null;

            // Match against media type mapping first
            if (TryMatchMediaTypeMapping(request, out mediaTypeMatch))
            {
                mediaTypeMatch.SetEncoding(characterEncodingMatch);
                return(new ResponseMediaTypeMatch(
                           mediaTypeMatch,
                           ResponseFormatterSelectionResult.MatchOnRequestWithMediaTypeMapping));
            }

            // Match against the accept header.
            if (TryMatchSupportedMediaType(request, out mediaTypeMatch))
            {
                mediaTypeMatch.SetEncoding(characterEncodingMatch);
                return(new ResponseMediaTypeMatch(
                           mediaTypeMatch,
                           ResponseFormatterSelectionResult.MatchOnRequestAcceptHeader));
            }

            // Match against request's content type
            HttpContent requestContent = request.Content;

            if (requestContent != null)
            {
                MediaTypeHeaderValue requestContentType = requestContent.Headers.ContentType;
                if (requestContentType != null && TryMatchSupportedMediaType(requestContentType, out mediaTypeMatch))
                {
                    mediaTypeMatch.SetEncoding(characterEncodingMatch);
                    return(new ResponseMediaTypeMatch(
                               mediaTypeMatch,
                               ResponseFormatterSelectionResult.MatchOnRequestContentType));
                }
            }

            // No match at all.
            // Pick the first supported media type and indicate we've matched only on type
            MediaTypeHeaderValue mediaType = SupportedMediaTypes.FirstOrDefault();

            mediaTypeMatch = new MediaTypeMatch(mediaType);
            mediaTypeMatch.SetEncoding(characterEncodingMatch);
            return(new ResponseMediaTypeMatch(
                       mediaTypeMatch,
                       ResponseFormatterSelectionResult.MatchOnCanWriteType));
        }