FaultException TransformException(
            IMethodInvocation input,
            Exception exception)
        {
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            Exception outException = null;

            try
            {
                if (!Facility.ExceptionManager.HandleException(exception, ExceptionHandlingPolicyName, out outException))
                {
                    return(null);
                }
            }
            catch (Exception x)
            {
                Facility.LogWriter.LogError(
                    $@"
Facility.ExceptionManager.HandleException throws:
{x.DumpString(1)}
when processing
{exception.DumpString(1)}");

                if (ExceptionHandlingPolicyName == ExceptionPolicyProvider.LogAndSwallowPolicyName)
                {
                    return(null);
                }

                if (outException == null)
                {
                    outException = exception;
                }
            }

            var faultException = outException as FaultException;

            // try to get the fault, if any
            var fault = (faultException != null &&
                         faultException.GetType().IsGenericType)
                            ? faultException
                        .GetType()
                        .GetProperty(nameof(FaultException <Fault> .Detail))
                        ?.GetValue(faultException) as Fault
                            : null;

            // can we return the faultException as we got it
            if (fault != null && IsFaultSupported(input, fault.GetType()))
            {
                return(faultException);
            }

            // if the base fault is supported one with all fields copied either to properties or to the Data collection.
            // Send it with status code 500 to indicate that the fault must be added to the protocol
            if (IsFaultSupported(input, typeof(Fault)))
            {
                fault = Fault.FaultFactory <Exception>(exception);
                return(new WebFaultException <Fault>(fault, HttpStatusCode.InternalServerError));
            }

            // otherwise construct base WebFaultException with some debug data in the Data property that will be dumped in the logs
            var exceptionToReturn = new WebFaultException(HttpStatusCode.InternalServerError);

            if (fault != null)
            {
                return(exceptionToReturn
                       .PopulateData(
                           new SortedDictionary <string, string>
                {
                    ["HandlingInstanceId"] = fault.HandlingInstanceId.ToString(),
                    ["Fault"] = fault.DumpString(),
                }));
            }

            return(exceptionToReturn
                   .PopulateData(
                       new SortedDictionary <string, string>
            {
                ["Exception"] = exception.DumpString(),
            }));
        }