/// <summary>
        /// Converts a standard <see cref="HttpRequest"/> to a <see cref="RequestModel"/>
        /// Copies over: URL, HTTP method, HTTP headers, query string params, POST params, user IP, route params
        /// </summary>
        /// <param name="request"></param>
        /// <param name="session"></param>
        /// <param name="scrubParams"></param>
        /// <returns></returns>
        public static RequestModel CreateFromHttpRequest(HttpRequest request, HttpSessionState session, string[] scrubParams = null)
        {
            var m = new RequestModel();

            m.Url = request.Url.ToString();
            m.Method = request.HttpMethod;
            m.Headers = request.Headers.ToDictionary();
            m.Session = session.ToDictionary();

            m.QueryStringParameters = request.QueryString.ToDictionary();
            m.PostParameters = request.Form.ToDictionary();

            // add posted files to the post collection
            if (request.Files.Count > 0)
                foreach (var file in request.Files.Describe())
                    m.PostParameters.Add(file.Key, "FILE: " + file.Value);

            // if the X-Forwarded-For header exists, use that as the user's IP.
            // that will be the true remote IP of a user behind a proxy server or load balancer
            m.UserIp = IpFromXForwardedFor(request) ?? request.UserHostAddress;

            m.Parameters = request.RequestContext.RouteData.Values.ToDictionary(v => v.Key, v => v.Describe());

            if (scrubParams != null)
            {
                m.Headers = Scrub(m.Headers, scrubParams);
                m.Session = Scrub(m.Session, scrubParams);
                m.QueryStringParameters = Scrub(m.QueryStringParameters, scrubParams);
                m.PostParameters = Scrub(m.PostParameters, scrubParams);
            }

            return m;
        }