/// <summary>
        /// Create object based on .Net exception
        /// </summary>
        /// <param name="ex">Hydrated .Net exception</param>
        public LogException(Exception ex)
            : this()
        {
            Message = ex.Message;
            Source = ex.Source;
            StackTrace = ex.StackTrace;
            HelpLink = ex.HelpLink;
            ExceptionType = ex.GetType().FullName;
            if (ex.InnerException != null)
            {
                InnerException = new LogException(ex.InnerException);
            }

            foreach (object key in ex.Data.Keys)
            {
                string keyString = key.ToString();
                Data.Add(new Property(keyString, ex.Data[key]));
            }

            //-------------------------------------------------------
            // use reflection to get all public properties on the
            //	exception being examined except those defined in
            //	_filterList (generally just those in base Exception class)
            //-------------------------------------------------------
            this.Properties = Reflector.GetPublicProperties(ex, _filterList);

            if (ex.TargetSite != null)
            {
                Method = ex.TargetSite.ToString();
                Module = ex.TargetSite.DeclaringType.Module.Name;
                Class = ex.TargetSite.DeclaringType.FullName;
            }

            if (ex is HttpException)
            {
                var webEx = ex as HttpException;
                ErrorCode = webEx.ErrorCode.ToString();
                HttpHtmlMessage = webEx.GetHtmlErrorMessage();
                HttpWebEventCode = webEx.WebEventCode;
                HttpStatusValue = webEx.GetHttpCode();
                HttpStatusCode = ((HttpStatusCode)HttpStatusValue).ToString();
            }
            else
            {
                ErrorCode = Reflector.GetProtectedProperty<int>("HResult", ex, default(int)).ToString();
            }
        }
        private void expandException(LogException ex, IDictionary<object,object> nlogProperties,string qualifier,int exceptionIndex)
        {
            if (ex.InnerException != null)
            {
                expandException(ex.InnerException, nlogProperties, qualifier + ".", exceptionIndex);
            }
            nlogProperties.Add(string.Format("Exception[{0}].{1}Message", exceptionIndex,qualifier), ex.Message);
            nlogProperties.Add(string.Format("Exception[{0}].{1}StackTrace", exceptionIndex,qualifier), ex.StackTrace);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Source", exceptionIndex,qualifier), ex.Source);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Type", exceptionIndex,qualifier), ex.ExceptionType);
            nlogProperties.Add(string.Format("Exception[{0}].{1}ErrorCode", exceptionIndex,qualifier), ex.ErrorCode);
            nlogProperties.Add(string.Format("Exception[{0}].{1}HelpLink", exceptionIndex,qualifier), ex.HelpLink);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Module", exceptionIndex, qualifier), ex.Module);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Class", exceptionIndex, qualifier), ex.Class);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Method", exceptionIndex, qualifier), ex.Method);
            if (ex.Properties.Count > 0)
            {
                foreach (var exProp in ex.Properties)
                {
                    try
                    {
                        nlogProperties.Add(string.Format("Exception[{0}].{2}{1}", exceptionIndex, exProp.Key, qualifier), exProp.Value);
                    }
                    catch(ArgumentException)
                    {
                        continue;
                    }
                }
            }

            if (ex.Data.Count > 0)
            {
                foreach (var exData in ex.Data)
                {
                    nlogProperties.Add(string.Format("Exception[{0}].{2}Data.{1}", exceptionIndex,exData.Key,qualifier), exData.Value);
                }
            }
            nlogProperties.Add(string.Format("Exception[{0}].{1}Html.EventCode", exceptionIndex,qualifier), ex.HttpWebEventCode);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Html.StatusValue", exceptionIndex,qualifier), ex.HttpStatusValue);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Html.StatusCode", exceptionIndex,qualifier), ex.HttpStatusCode);
            nlogProperties.Add(string.Format("Exception[{0}].{1}Html.Message", exceptionIndex,qualifier), ex.HttpHtmlMessage);
        }
        private void expandException(LogException logException, int exceptionIndex, IDictionary<object, object> nlogProperties)
        {
            var baseEx = logException.BaseException;
            if (logException.InnerException != null || logException.BaseException.ExceptionId != logException.ExceptionId)
            {
                nlogProperties.Add(string.Format("Exception[{0}].Base.Message", exceptionIndex), baseEx.Message);
            }
            expandException(logException, nlogProperties, "", exceptionIndex);

            nlogProperties.Add(string.Format("Exception[{0}].JSON", exceptionIndex), JsonConvert.SerializeObject(logException, Formatting.None, new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            }));
        }