using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Websocket.Client.Logging.LogProviders
{
	internal class NLogLogProvider : LogProviderBase
	{
		public NLogLogProvider()
		{
			if (!NLogLogProvider.IsLoggerAvailable())
			{
				throw new LibLogException("NLog.LogManager not found");
			}
			this._getLoggerByNameDelegate = NLogLogProvider.GetGetLoggerMethodCall();
		}

		public static bool ProviderIsAvailableOverride { get; set; } = true;

		public override Logger GetLogger(string name)
		{
			return new Logger(new NLogLogProvider.NLogLogger(this._getLoggerByNameDelegate(name)).Log);
		}

		public static bool IsLoggerAvailable()
		{
			return NLogLogProvider.<ProviderIsAvailableOverride>k__BackingField && NLogLogProvider.GetLogManagerType() != null;
		}

		protected override LogProviderBase.OpenNdc GetOpenNdcMethod()
		{
			ParameterExpression parameterExpression = Expression.Parameter(typeof(string), "message");
			Type type = LogProviderBase.FindType("NLog.NestedDiagnosticsLogicalContext", "NLog");
			if (type != null)
			{
				MethodInfo method = type.GetMethod("PushObject", new Type[] { typeof(object) });
				if (method != null)
				{
					return Expression.Lambda<LogProviderBase.OpenNdc>(Expression.Call(null, method, new Expression[] { parameterExpression }), new ParameterExpression[] { parameterExpression }).Compile();
				}
			}
			MethodInfo method2 = LogProviderBase.FindType("NLog.NestedDiagnosticsContext", "NLog").GetMethod("Push", new Type[] { typeof(string) });
			return Expression.Lambda<LogProviderBase.OpenNdc>(Expression.Call(null, method2, new Expression[] { parameterExpression }), new ParameterExpression[] { parameterExpression }).Compile();
		}

		protected override LogProviderBase.OpenMdc GetOpenMdcMethod()
		{
			ParameterExpression parameterExpression = Expression.Parameter(typeof(string), "key");
			Type type = LogProviderBase.FindType("NLog.NestedDiagnosticsLogicalContext", "NLog");
			if (type != null && type.GetMethod("PushObject", new Type[] { typeof(object) }) != null)
			{
				Type type2 = LogProviderBase.FindType("NLog.MappedDiagnosticsLogicalContext", "NLog");
				if (type2 != null)
				{
					MethodInfo method = type2.GetMethod("SetScoped", new Type[]
					{
						typeof(string),
						typeof(object)
					});
					if (method != null)
					{
						ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object), "value");
						MethodCallExpression methodCallExpression = Expression.Call(null, method, parameterExpression, parameterExpression2);
						Func<string, object, IDisposable> setMethodLambda = Expression.Lambda<Func<string, object, IDisposable>>(methodCallExpression, new ParameterExpression[] { parameterExpression, parameterExpression2 }).Compile();
						return (string key, object value, bool _) => setMethodLambda(key, value);
					}
				}
			}
			Type type3 = LogProviderBase.FindType("NLog.MappedDiagnosticsContext", "NLog");
			MethodInfo method2 = type3.GetMethod("Set", new Type[]
			{
				typeof(string),
				typeof(string)
			});
			MethodInfo method3 = type3.GetMethod("Remove", new Type[] { typeof(string) });
			ParameterExpression parameterExpression3 = Expression.Parameter(typeof(string), "value");
			MethodCallExpression methodCallExpression2 = Expression.Call(null, method2, parameterExpression, parameterExpression3);
			MethodCallExpression methodCallExpression3 = Expression.Call(null, method3, new Expression[] { parameterExpression });
			Action<string, string> set = Expression.Lambda<Action<string, string>>(methodCallExpression2, new ParameterExpression[] { parameterExpression, parameterExpression3 }).Compile();
			Action<string> remove = Expression.Lambda<Action<string>>(methodCallExpression3, new ParameterExpression[] { parameterExpression }).Compile();
			return delegate(string key, object value, bool _)
			{
				set(key, value.ToString());
				return new DisposableAction(delegate
				{
					remove(key);
				});
			};
		}

		private static Type GetLogManagerType()
		{
			return LogProviderBase.FindType("NLog.LogManager", "NLog");
		}

		private static Func<string, object> GetGetLoggerMethodCall()
		{
			MethodInfo method = NLogLogProvider.GetLogManagerType().GetMethod("GetLogger", new Type[] { typeof(string) });
			ParameterExpression parameterExpression;
			return Expression.Lambda<Func<string, object>>(Expression.Call(null, method, new Expression[] { parameterExpression }), new ParameterExpression[] { parameterExpression }).Compile();
		}

		private readonly Func<string, object> _getLoggerByNameDelegate;

		internal class NLogLogger
		{
			internal NLogLogger(object logger)
			{
				this._logger = logger;
			}

			private static bool Initialize()
			{
				bool flag;
				try
				{
					Type type = LogProviderBase.FindType("NLog.LogLevel", "NLog");
					if (type == null)
					{
						throw new LibLogException("Type NLog.LogLevel was not found.");
					}
					List<FieldInfo> list = type.GetFields().ToList<FieldInfo>();
					NLogLogProvider.NLogLogger.s_levelTrace = list.First((FieldInfo x) => x.Name == "Trace").GetValue(null);
					NLogLogProvider.NLogLogger.s_levelDebug = list.First((FieldInfo x) => x.Name == "Debug").GetValue(null);
					NLogLogProvider.NLogLogger.s_levelInfo = list.First((FieldInfo x) => x.Name == "Info").GetValue(null);
					NLogLogProvider.NLogLogger.s_levelWarn = list.First((FieldInfo x) => x.Name == "Warn").GetValue(null);
					NLogLogProvider.NLogLogger.s_levelError = list.First((FieldInfo x) => x.Name == "Error").GetValue(null);
					NLogLogProvider.NLogLogger.s_levelFatal = list.First((FieldInfo x) => x.Name == "Fatal").GetValue(null);
					Type type2 = LogProviderBase.FindType("NLog.LogEventInfo", "NLog");
					if (type2 == null)
					{
						throw new LibLogException("Type NLog.LogEventInfo was not found.");
					}
					ConstructorInfo constructorPortable = type2.GetConstructorPortable(new Type[]
					{
						type,
						typeof(string),
						typeof(IFormatProvider),
						typeof(string),
						typeof(object[]),
						typeof(Exception)
					});
					ParameterExpression parameterExpression = Expression.Parameter(typeof(string));
					ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object));
					ParameterExpression parameterExpression3 = Expression.Parameter(typeof(string));
					ParameterExpression parameterExpression4 = Expression.Parameter(typeof(object[]));
					ParameterExpression parameterExpression5 = Expression.Parameter(typeof(Exception));
					UnaryExpression unaryExpression = Expression.Convert(parameterExpression2, type);
					NLogLogProvider.NLogLogger.s_logEventInfoFact = Expression.Lambda<Func<string, object, string, object[], Exception, object>>(Expression.New(constructorPortable, new Expression[]
					{
						unaryExpression,
						parameterExpression,
						Expression.Constant(null, typeof(IFormatProvider)),
						parameterExpression3,
						parameterExpression4,
						parameterExpression5
					}), new ParameterExpression[] { parameterExpression, parameterExpression2, parameterExpression3, parameterExpression4, parameterExpression5 }).Compile();
					Type type3 = LogProviderBase.FindType("NLog.Logger", "NLog");
					NLogLogProvider.NLogLogger.s_loggerNameDelegate = NLogLogProvider.NLogLogger.GetLoggerNameDelegate(type3);
					NLogLogProvider.NLogLogger.s_logEventDelegate = NLogLogProvider.NLogLogger.GetLogEventDelegate(type3, type2);
					NLogLogProvider.NLogLogger.s_isTraceEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsTraceEnabled");
					NLogLogProvider.NLogLogger.s_isDebugEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsDebugEnabled");
					NLogLogProvider.NLogLogger.s_isInfoEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsInfoEnabled");
					NLogLogProvider.NLogLogger.s_isWarnEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsWarnEnabled");
					NLogLogProvider.NLogLogger.s_isErrorEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsErrorEnabled");
					NLogLogProvider.NLogLogger.s_isFatalEnabledDelegate = NLogLogProvider.NLogLogger.GetIsEnabledDelegate(type3, "IsFatalEnabled");
					NLogLogProvider.NLogLogger.s_traceDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Trace");
					NLogLogProvider.NLogLogger.s_debugDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Debug");
					NLogLogProvider.NLogLogger.s_infoDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Info");
					NLogLogProvider.NLogLogger.s_warnDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Warn");
					NLogLogProvider.NLogLogger.s_errorDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Error");
					NLogLogProvider.NLogLogger.s_fatalDelegate = NLogLogProvider.NLogLogger.GetLogDelegate(type3, "Fatal");
					NLogLogProvider.NLogLogger.s_traceExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "TraceException");
					NLogLogProvider.NLogLogger.s_debugExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "DebugException");
					NLogLogProvider.NLogLogger.s_infoExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "InfoException");
					NLogLogProvider.NLogLogger.s_warnExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "WarnException");
					NLogLogProvider.NLogLogger.s_errorExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "ErrorException");
					NLogLogProvider.NLogLogger.s_fatalExceptionDelegate = NLogLogProvider.NLogLogger.GetLogExceptionDelegate(type3, "FatalException");
					NLogLogProvider.NLogLogger.s_structuredLoggingEnabled = NLogLogProvider.NLogLogger.IsStructuredLoggingEnabled();
					return true;
				}
				catch (Exception ex)
				{
					NLogLogProvider.NLogLogger.s_initializeException = ex;
					flag = false;
				}
				return flag;
			}

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate GetIsEnabledDelegate(Type loggerType, object propertyName)
			{
				PropertyInfo property = loggerType.GetProperty(propertyName);
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				return Expression.Lambda<NLogLogProvider.NLogLogger.IsEnabledDelegate>(Expression.Property(Expression.Convert(parameterExpression, loggerType), property), new ParameterExpression[] { parameterExpression }).Compile();
			}

			private static NLogLogProvider.NLogLogger.LoggerNameDelegate GetLoggerNameDelegate(Type loggerType)
			{
				PropertyInfo property = loggerType.GetProperty("Name");
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				return Expression.Lambda<NLogLogProvider.NLogLogger.LoggerNameDelegate>(Expression.Property(Expression.Convert(parameterExpression, loggerType), property), new ParameterExpression[] { parameterExpression }).Compile();
			}

			private static NLogLogProvider.NLogLogger.LogDelegate GetLogDelegate(Type loggerType, object name)
			{
				MethodInfo method = loggerType.GetMethod(name, new Type[] { typeof(string) });
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				Expression expression = Expression.Convert(parameterExpression, loggerType);
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(string));
				return Expression.Lambda<NLogLogProvider.NLogLogger.LogDelegate>(Expression.Call(expression, method, new Expression[] { parameterExpression2 }), new ParameterExpression[] { parameterExpression, parameterExpression2 }).Compile();
			}

			private static NLogLogProvider.NLogLogger.LogEventDelegate GetLogEventDelegate(Type loggerType, Type logEventType)
			{
				MethodInfo method = loggerType.GetMethod("Log", new Type[]
				{
					typeof(Type),
					logEventType
				});
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				Expression expression = Expression.Convert(parameterExpression, loggerType);
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(Type));
				ParameterExpression parameterExpression3 = Expression.Parameter(typeof(object));
				UnaryExpression unaryExpression = Expression.Convert(parameterExpression3, logEventType);
				return Expression.Lambda<NLogLogProvider.NLogLogger.LogEventDelegate>(Expression.Call(expression, method, parameterExpression2, unaryExpression), new ParameterExpression[] { parameterExpression, parameterExpression2, parameterExpression3 }).Compile();
			}

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate GetLogExceptionDelegate(Type loggerType, object name)
			{
				MethodInfo method = loggerType.GetMethod(name, new Type[]
				{
					typeof(string),
					typeof(Exception)
				});
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				Expression expression = Expression.Convert(parameterExpression, loggerType);
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(string));
				ParameterExpression parameterExpression3 = Expression.Parameter(typeof(Exception));
				return Expression.Lambda<NLogLogProvider.NLogLogger.LogExceptionDelegate>(Expression.Call(expression, method, parameterExpression2, parameterExpression3), new ParameterExpression[] { parameterExpression, parameterExpression2, parameterExpression3 }).Compile();
			}

			public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception, params object[] formatParameters)
			{
				if (!NLogLogProvider.NLogLogger.Initialized.Value)
				{
					throw new LibLogException("Unable to log due to problem initializing the log provider. See inner exception for details.", NLogLogProvider.NLogLogger.s_initializeException);
				}
				if (messageFunc == null)
				{
					return this.IsLogLevelEnable(logLevel);
				}
				if (NLogLogProvider.NLogLogger.s_logEventInfoFact != null)
				{
					if (this.IsLogLevelEnable(logLevel))
					{
						string text = messageFunc();
						if (!NLogLogProvider.NLogLogger.s_structuredLoggingEnabled)
						{
							IEnumerable<string> enumerable;
							text = LogMessageFormatter.FormatStructuredMessage(text, formatParameters, out enumerable);
							formatParameters = null;
						}
						Type type = typeof(NLogLogProvider.NLogLogger);
						Type declaringType = messageFunc.Method.DeclaringType;
						if (!(declaringType == typeof(LogExtensions)) && (!(declaringType != null) || !(declaringType.DeclaringType == typeof(LogExtensions))))
						{
							if (declaringType == typeof(LoggerExecutionWrapper) || (declaringType != null && declaringType.DeclaringType == typeof(LoggerExecutionWrapper)))
							{
								type = typeof(LoggerExecutionWrapper);
							}
						}
						else
						{
							type = typeof(LogExtensions);
						}
						object obj = this.TranslateLevel(logLevel);
						object obj2 = NLogLogProvider.NLogLogger.s_logEventInfoFact(NLogLogProvider.NLogLogger.s_loggerNameDelegate(this._logger), obj, text, formatParameters, exception);
						NLogLogProvider.NLogLogger.s_logEventDelegate(this._logger, type, obj2);
						return true;
					}
					return false;
				}
				else
				{
					messageFunc = LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters);
					if (exception != null)
					{
						return this.LogException(logLevel, messageFunc, exception);
					}
					switch (logLevel)
					{
					case LogLevel.Debug:
						if (NLogLogProvider.NLogLogger.s_isDebugEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_debugDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					case LogLevel.Info:
						if (NLogLogProvider.NLogLogger.s_isInfoEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_infoDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					case LogLevel.Warn:
						if (NLogLogProvider.NLogLogger.s_isWarnEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_warnDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					case LogLevel.Error:
						if (NLogLogProvider.NLogLogger.s_isErrorEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_errorDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					case LogLevel.Fatal:
						if (NLogLogProvider.NLogLogger.s_isFatalEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_fatalDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					default:
						if (NLogLogProvider.NLogLogger.s_isTraceEnabledDelegate(this._logger))
						{
							NLogLogProvider.NLogLogger.s_traceDelegate(this._logger, messageFunc());
							return true;
						}
						break;
					}
					return false;
				}
			}

			private bool LogException(LogLevel logLevel, Func<string> messageFunc, Exception exception)
			{
				switch (logLevel)
				{
				case LogLevel.Debug:
					if (NLogLogProvider.NLogLogger.s_isDebugEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_debugExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				case LogLevel.Info:
					if (NLogLogProvider.NLogLogger.s_isInfoEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_infoExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				case LogLevel.Warn:
					if (NLogLogProvider.NLogLogger.s_isWarnEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_warnExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				case LogLevel.Error:
					if (NLogLogProvider.NLogLogger.s_isErrorEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_errorExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				case LogLevel.Fatal:
					if (NLogLogProvider.NLogLogger.s_isFatalEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_fatalExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				default:
					if (NLogLogProvider.NLogLogger.s_isTraceEnabledDelegate(this._logger))
					{
						NLogLogProvider.NLogLogger.s_traceExceptionDelegate(this._logger, messageFunc(), exception);
						return true;
					}
					break;
				}
				return false;
			}

			private bool IsLogLevelEnable(LogLevel logLevel)
			{
				switch (logLevel)
				{
				case LogLevel.Debug:
					return NLogLogProvider.NLogLogger.s_isDebugEnabledDelegate(this._logger);
				case LogLevel.Info:
					return NLogLogProvider.NLogLogger.s_isInfoEnabledDelegate(this._logger);
				case LogLevel.Warn:
					return NLogLogProvider.NLogLogger.s_isWarnEnabledDelegate(this._logger);
				case LogLevel.Error:
					return NLogLogProvider.NLogLogger.s_isErrorEnabledDelegate(this._logger);
				case LogLevel.Fatal:
					return NLogLogProvider.NLogLogger.s_isFatalEnabledDelegate(this._logger);
				default:
					return NLogLogProvider.NLogLogger.s_isTraceEnabledDelegate(this._logger);
				}
			}

			private object TranslateLevel(LogLevel logLevel)
			{
				switch (logLevel)
				{
				case LogLevel.Trace:
					return NLogLogProvider.NLogLogger.s_levelTrace;
				case LogLevel.Debug:
					return NLogLogProvider.NLogLogger.s_levelDebug;
				case LogLevel.Info:
					return NLogLogProvider.NLogLogger.s_levelInfo;
				case LogLevel.Warn:
					return NLogLogProvider.NLogLogger.s_levelWarn;
				case LogLevel.Error:
					return NLogLogProvider.NLogLogger.s_levelError;
				case LogLevel.Fatal:
					return NLogLogProvider.NLogLogger.s_levelFatal;
				default:
					throw new ArgumentOutOfRangeException("logLevel", logLevel, null);
				}
			}

			private static bool IsStructuredLoggingEnabled()
			{
				Type type = LogProviderBase.FindType("NLog.Config.ConfigurationItemFactory", "NLog");
				if (type != null)
				{
					PropertyInfo property = type.GetProperty("ParseMessageTemplates");
					if (property != null)
					{
						PropertyInfo property2 = type.GetProperty("Default");
						if (property2 != null)
						{
							object value = property2.GetValue(null, null);
							if (value != null)
							{
								bool? flag = property.GetValue(value, null) as bool?;
								if (!(!flag.GetValueOrDefault() & (flag != null)))
								{
									return true;
								}
							}
						}
					}
				}
				return false;
			}

			private static Func<string, object, string, object[], Exception, object> s_logEventInfoFact;

			private static object s_levelTrace;

			private static object s_levelDebug;

			private static object s_levelInfo;

			private static object s_levelWarn;

			private static object s_levelError;

			private static object s_levelFatal;

			private static bool s_structuredLoggingEnabled;

			private static readonly Lazy<bool> Initialized = new Lazy<bool>(new Func<bool>(NLogLogProvider.NLogLogger.Initialize));

			private static Exception s_initializeException;

			private static NLogLogProvider.NLogLogger.LoggerNameDelegate s_loggerNameDelegate;

			private static NLogLogProvider.NLogLogger.LogEventDelegate s_logEventDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isTraceEnabledDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isDebugEnabledDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isInfoEnabledDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isWarnEnabledDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isErrorEnabledDelegate;

			private static NLogLogProvider.NLogLogger.IsEnabledDelegate s_isFatalEnabledDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_traceDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_debugDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_infoDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_warnDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_errorDelegate;

			private static NLogLogProvider.NLogLogger.LogDelegate s_fatalDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_traceExceptionDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_debugExceptionDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_infoExceptionDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_warnExceptionDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_errorExceptionDelegate;

			private static NLogLogProvider.NLogLogger.LogExceptionDelegate s_fatalExceptionDelegate;

			private readonly object _logger;

			private delegate string LoggerNameDelegate(object logger);

			private delegate void LogEventDelegate(object logger, Type wrapperType, object logEvent);

			private delegate bool IsEnabledDelegate(object logger);

			private delegate void LogDelegate(object logger, string message);

			private delegate void LogExceptionDelegate(object logger, string message, Exception exception);
		}
	}
}
