Inheritance: System.Net.Http.Formatting.BufferedMediaTypeFormatter
        public void Apply(HttpConfiguration configuration)
        {
            var serializer = GetJsonSerializer();
            var helper = new TransformationHelper();
            var transformer = new JsonApiTransformer { Serializer = serializer, TransformationHelper = helper };

            var filter = new JsonApiActionFilter(transformer, this);
            configuration.Filters.Add(filter);

            var formatter = new JsonApiFormatter(this, serializer);
            configuration.Formatters.Add(formatter);
        }
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            InternalActionExecuting(actionContext, cancellationToken);

            if (actionContext.Response != null)
            {
                return actionContext.Response;
            }

            HttpActionExecutedContext executedContext;

            try
            {
                var response = await continuation();
                executedContext = new HttpActionExecutedContext(actionContext, null)
                {
                    Response = response
                };
                InternalActionExecuted(executedContext, cancellationToken);
            }
            catch (Exception exception)
            {
                var context = new Context
                {
                    Configuration = configuration,
                    RoutePrefix = string.Empty
                };

                executedContext = new HttpActionExecutedContext(actionContext, exception);
                if (executedContext.Response == null)
                {
                    var UtilJsonApiSerializerBaseException = exception as UtilJsonApiSerializerBaseException;
                    if (UtilJsonApiSerializerBaseException != null)
                    {
                        executedContext.Response = new HttpResponseMessage(UtilJsonApiSerializerBaseException.GetHttpStatusCode());
                        var transformed = jsonApiTransformer.Transform(UtilJsonApiSerializerBaseException, context);
                        var jsonApiFormatter = new JsonApiFormatter(configuration, jsonApiTransformer.Serializer);
                        executedContext.Response.Content = new ObjectContent(transformed.GetType(), transformed, jsonApiFormatter);
                    }
                    else
                    {
                        executedContext.Response = executedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new UtilJsonApiSerializerBaseException("Internal Server Error"));
                        executedContext.Response.Content = new HttpMessageContent(new HttpResponseMessage(HttpStatusCode.InternalServerError));
                    }
                }
            }

            return executedContext.Response;
        }
        public virtual void InternalActionExecuted(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            try
            {
                var objectContent = actionExecutedContext.Response.Content as ObjectContent;
                if (objectContent != null && objectContent.Formatter.GetType() == typeof(JsonApiFormatter))
                {
                    var value = objectContent.Value;
                    var context = new Context
                    {
                        Configuration = configuration,
                        RoutePrefix = GetRoutePrefix(actionExecutedContext)
                    };
                    var transformed = jsonApiTransformer.Transform(value, context);

                    var jsonApiFormatter = new JsonApiFormatter(configuration, jsonApiTransformer.Serializer);
                    actionExecutedContext.Response.Content = new ObjectContent(transformed.GetType(), transformed, jsonApiFormatter);

                    HandlePostRequests(actionExecutedContext, transformed);
                }
            }            
            catch
            {
                // Different kinds of unsupported requests may end up here. Ideally, these should be programmed against to avoid throwing.
            }
        }