You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by dp...@apache.org on 2017/06/22 20:47:49 UTC

[01/10] logging-log4net git commit: Add extension source project

Repository: logging-log4net
Updated Branches:
  refs/heads/pr/old/29 [created] ea259c6bf
  refs/heads/pr/old/32 [created] 3f428edaf
  refs/heads/pr/old/40 [created] a847990ce
  refs/heads/pr/old/43 [created] 1a8eb94da
  refs/heads/pr/old/45 [created] 4ee46ecff
Updated Tags:  refs/tags/1.2.13RC1 [created] 6dc3da926


Add extension source project


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/3f428eda
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/3f428eda
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/3f428eda

Branch: refs/heads/pr/old/32
Commit: 3f428edaf7a82ab6091b216039debd94db729bd1
Parents: 5e66799
Author: Peter Jas <ne...@yahoo.com>
Authored: Sun Aug 21 00:14:53 2016 +0000
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:11:35 2017 +0200

----------------------------------------------------------------------
 .../AspNetExtensions.cs                         |  48 +++++++++
 .../log4net.Extensions.Logging/Log4NetLogger.cs | 101 +++++++++++++++++++
 .../Log4NetLoggerProvider.cs                    |  31 ++++++
 .../log4net.Extensions.Logging/project.json     |  30 ++++++
 global.json                                     |   3 +
 netstandard/global.json                         |   3 -
 netstandard/log4net/project.json                |   1 +
 7 files changed, 214 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/AspNetExtensions.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/AspNetExtensions.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/AspNetExtensions.cs
new file mode 100644
index 0000000..8d2ba5d
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/AspNetExtensions.cs
@@ -0,0 +1,48 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Logging;
+using log4net.Config;
+using log4net.Core;
+
+namespace log4net.Extensions.Logging
+{
+    /// <summary>
+    /// Helpers for ASP.NET Core
+    /// </summary>
+    public static class AspNetExtensions
+    {
+
+        /// <summary>
+        /// Enable log4net as logging provider in ASP.NET Core.
+        /// </summary>
+        /// <param name="factory"></param>
+        /// <returns>Instance of <c>ILoggerFactory</c></returns>
+        public static ILoggerFactory AddLog4Net(this ILoggerFactory factory, Type type)
+        {
+            using (var provider = new Log4NetLoggerProvider(type))
+            {
+                factory.AddProvider(provider);
+            }
+
+            return factory;
+        }
+
+        /// <summary>
+        /// Apply log4net configuration from XML config.
+        /// </summary>
+        /// <param name="env"></param>
+        /// <param name="configFileRelativePath">relative path to log4net configuration file.</param>
+        /// <returns>Instance of <c>ILoggerFactory</c></returns>
+        public static void ConfigureLog4Net(this IHostingEnvironment env, string configFileRelativePath, Type type)
+        {
+            GlobalContext.Properties["appRoot"] = env.ContentRootPath;
+
+            var fileName = Path.Combine(env.ContentRootPath, configFileRelativePath);
+            var repository = LoggerManager.RepositorySelector.GetRepository(type.GetTypeInfo().Assembly);
+
+            XmlConfigurator.Configure(repository, new FileInfo(fileName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLogger.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLogger.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLogger.cs
new file mode 100644
index 0000000..98e1faa
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLogger.cs
@@ -0,0 +1,101 @@
+using System;
+using Microsoft.Extensions.Logging;
+using log4net;
+
+namespace log4net.Extensions.Logging
+{
+    public class Log4NetLogger : Microsoft.Extensions.Logging.ILogger
+    {
+        private readonly ILog _logger;
+
+        public Log4NetLogger(Type type)
+        {
+            _logger = LogManager.GetLogger(type);
+        }
+
+        /// <summary>
+        /// Writes a log entry.
+        /// </summary>
+        /// <param name="logLevel">Entry will be written on this level.</param>
+        /// <param name="eventId">Id of the event.</param>
+        /// <param name="state">The entry to be written. Can be also an object.</param>
+        /// <param name="exception">The exception related to this entry.</param>
+        /// <param name="formatter">Function to create a <c>string</c> message of the <paramref name="state"/> and <paramref name="exception"/>.</param>
+        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
+        {
+            if (!IsEnabled(logLevel))
+            {
+                return;
+            }
+            if (formatter == null)
+            {
+                throw new ArgumentNullException(nameof(formatter));
+            }
+
+            var message = formatter(state, exception);
+
+            switch (logLevel)
+            {
+                case LogLevel.Trace:
+                case LogLevel.Debug:
+                    _logger.Debug(message, exception);
+                    break;
+                case LogLevel.Information:
+                    _logger.Info(message, exception);
+                    break;
+                case LogLevel.Warning:
+                    _logger.Warn(message, exception);
+                    break;
+                case LogLevel.Error:
+                    _logger.Error(message, exception);
+                    break;
+                case LogLevel.Critical:
+                    _logger.Fatal(message, exception);
+                    break;
+                case LogLevel.None:
+                    break;
+                default:
+                    _logger.Warn($"Encountered unknown log level {logLevel}, writing out as Debug.");
+                    _logger.Debug(message, exception);
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Checks if the given <paramref name="logLevel"/> is enabled.
+        /// </summary>
+        /// <param name="logLevel">level to be checked.</param>
+        /// <returns><c>true</c> if enabled.</returns>
+        public bool IsEnabled(LogLevel logLevel)
+        {
+            switch (logLevel)
+            {
+                case LogLevel.Trace:
+                case LogLevel.Debug:
+                    return _logger.IsDebugEnabled;
+                case LogLevel.Information:
+                    return _logger.IsInfoEnabled;
+                case LogLevel.Warning:
+                    return _logger.IsWarnEnabled;
+                case LogLevel.Error:
+                    return _logger.IsErrorEnabled;
+                case LogLevel.Critical:
+                    return _logger.IsFatalEnabled;
+                case LogLevel.None:
+                    return false;
+                default:
+                    throw new ArgumentException($"Unknown log level {logLevel}.", nameof(logLevel));
+            }
+        }
+
+        /// <summary>
+        /// Begins a logical operation scope.
+        /// </summary>
+        /// <param name="state">The identifier for the scope.</param>
+        /// <returns>An IDisposable that ends the logical operation scope on dispose.</returns>
+        public IDisposable BeginScope<TState>(TState state)
+        {
+            return null; // TODO: Figure out what to do here?
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLoggerProvider.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLoggerProvider.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLoggerProvider.cs
new file mode 100644
index 0000000..a2d8964
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/Log4NetLoggerProvider.cs
@@ -0,0 +1,31 @@
+using System;
+using Microsoft.Extensions.Logging;
+
+namespace log4net.Extensions.Logging
+{
+    public class Log4NetLoggerProvider : IDisposable,Microsoft.Extensions.Logging.ILoggerProvider
+    {
+    	private readonly Type _type;
+
+        public Log4NetLoggerProvider(Type type)
+        {
+        	_type = type;
+        }
+
+        /// <summary>
+        /// Create a logger with the name <paramref name="name"/>.
+        /// </summary>
+        /// <param name="name">Name of the logger to be created.</param>
+        /// <returns>New Logger</returns>
+        public Microsoft.Extensions.Logging.ILogger CreateLogger(string name)
+        {
+            return new Log4NetLogger(_type);
+        }
+
+        /// <summary>
+        /// Cleanup
+        /// </summary>
+        public void Dispose()
+        { }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/project.json
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/project.json b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/project.json
new file mode 100644
index 0000000..e7cde51
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging/project.json
@@ -0,0 +1,30 @@
+{
+  "version": "1.0.0-*",
+
+  "packOptions": {
+    "requireLicenseAcceptance": false,
+    "tags": [ "logging", "log", "tracing", "logfiles", "apache", "aspnet" ],
+    "iconUrl": "https://logging.apache.org/img/feather.gif",
+    "licenseUrl": "https://raw.githubusercontent.com/apache/log4net/trunk/LICENSE",
+    "projectUrl": "https://github.com/apache/log4net",
+    "repository": {
+      "type": "git",
+      "url": "git://git.apache.org/log4net.git"
+    }
+  },
+
+  "buildOptions": {
+    "debugType": "portable"
+  },
+
+  "dependencies": {
+      "log4net": { "target": "project" },
+      "Microsoft.Extensions.Logging": "1.0.0",
+      "Microsoft.AspNetCore.Hosting": "1.0.0"
+  },
+
+  "frameworks": {
+    "net451": {},
+    "netstandard1.3": {}
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/global.json
----------------------------------------------------------------------
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..f3f8e98
--- /dev/null
+++ b/global.json
@@ -0,0 +1,3 @@
+{
+    "projects": [ "netstandard", "extensions" ]
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/netstandard/global.json
----------------------------------------------------------------------
diff --git a/netstandard/global.json b/netstandard/global.json
deleted file mode 100644
index 200ddfd..0000000
--- a/netstandard/global.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "projects": [ "log4net", "log4net.tests" ]
-}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/3f428eda/netstandard/log4net/project.json
----------------------------------------------------------------------
diff --git a/netstandard/log4net/project.json b/netstandard/log4net/project.json
index 51731de..003501e 100644
--- a/netstandard/log4net/project.json
+++ b/netstandard/log4net/project.json
@@ -1,6 +1,7 @@
 {
   "name": "log4net",
   "version": "3.0.0",
+
   "frameworks": {
     "netstandard1.3": {
       "buildOptions": {


[05/10] logging-log4net git commit: Try and trap a date when looking for the next backup number.

Posted by dp...@apache.org.
Try and trap a date when looking for the next backup number.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/ea259c6b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/ea259c6b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/ea259c6b

Branch: refs/heads/pr/old/29
Commit: ea259c6bf0f8676af232a970b7c774ca233fd0cb
Parents: 563311c
Author: Steven Nicholas <st...@snware.com>
Authored: Thu Jun 22 22:31:14 2017 +0200
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:31:14 2017 +0200

----------------------------------------------------------------------
 src/Appender/RollingFileAppender.cs | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/ea259c6b/src/Appender/RollingFileAppender.cs
----------------------------------------------------------------------
diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs
index 816549c..f0d5ab4 100644
--- a/src/Appender/RollingFileAppender.cs
+++ b/src/Appender/RollingFileAppender.cs
@@ -1010,13 +1010,20 @@ namespace log4net.Appender
             {
                 fileName = Path.GetFileNameWithoutExtension(fileName);
             }
-            
+
             int index = fileName.LastIndexOf(".");
             if (index > 0)
             {
                 // if the "yyyy-MM-dd" component of file.log.yyyy-MM-dd is passed to TryParse
-                // it will gracefully fail and return backUpIndex will be 0
+                // it will gracefully fail and return backUpIndex will be 0.
+                // If the date format does not contina any -'s then we have to do additional checks.
                 SystemInfo.TryParse(fileName.Substring(index + 1), out backUpIndex);
+
+                // We may have picked up a date in a format without "-" eg. yyyyMMdd...
+                if (backUpIndex > m_maxSizeRollBackups && m_rollDate)
+                {
+                    backUpIndex = 0;
+                }
             }
 
             return backUpIndex;


[08/10] logging-log4net git commit: Allow for dates that aren't necessarily in the yyyy-MM-dd format.

Posted by dp...@apache.org.
Allow for dates that aren't necessarily in the yyyy-MM-dd format.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/1a8eb94d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/1a8eb94d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/1a8eb94d

Branch: refs/heads/pr/old/43
Commit: 1a8eb94da4cf9b7b0f88140407486bd9defc901a
Parents: 2002917
Author: Steven Nicholas <st...@snware.com>
Authored: Wed Mar 8 09:08:26 2017 +0200
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:39:32 2017 +0200

----------------------------------------------------------------------
 src/Appender/RollingFileAppender.cs | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/1a8eb94d/src/Appender/RollingFileAppender.cs
----------------------------------------------------------------------
diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs
index 63ffaeb..82f8417 100644
--- a/src/Appender/RollingFileAppender.cs
+++ b/src/Appender/RollingFileAppender.cs
@@ -1026,7 +1026,14 @@ namespace log4net.Appender
             {
                 // if the "yyyy-MM-dd" component of file.log.yyyy-MM-dd is passed to TryParse
                 // it will gracefully fail and return backUpIndex will be 0
+                // If the date format does not contina any -'s then we have to do additional checks.
                 SystemInfo.TryParse(fileName.Substring(index + 1), out backUpIndex);
+
+                // We may have picked up a date in a format without "-" eg. yyyyMMdd...
+                if (backUpIndex > m_maxSizeRollBackups && m_rollDate)
+                {
+                    backUpIndex = 0;
+                }            
             }
 
             return backUpIndex;


[06/10] logging-log4net git commit: Implemented changes for the Util/AppenderAttachedImpl.cs class for calling log4net appenders in parallel using .NET Task Parallel Library.

Posted by dp...@apache.org.
Implemented changes for the Util/AppenderAttachedImpl.cs class for calling log4net appenders in parallel using .NET Task Parallel Library.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/897ef682
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/897ef682
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/897ef682

Branch: refs/heads/pr/old/40
Commit: 897ef682bebbc44da53812fa4001d0132e80a84a
Parents: 76f0151
Author: Harry Martyrossian <HM...@users.noreply.github.com>
Authored: Fri Dec 30 20:32:41 2016 -0800
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:37:13 2017 +0200

----------------------------------------------------------------------
 src/Util/AppenderAttachedImpl.cs      |  54 +-
 src/Util/ParallelIAppender.cs         | 214 ++++++++
 src/log4net.vs2015.csproj             | 809 +++++++++++++++++++++++++++++
 src/log4net.vs2015.sln                |  27 +
 tests/src/log4net.Tests.vs2015.csproj | 260 +++++++++
 5 files changed, 1343 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/897ef682/src/Util/AppenderAttachedImpl.cs
----------------------------------------------------------------------
diff --git a/src/Util/AppenderAttachedImpl.cs b/src/Util/AppenderAttachedImpl.cs
index fafb0b8..9da44c2 100644
--- a/src/Util/AppenderAttachedImpl.cs
+++ b/src/Util/AppenderAttachedImpl.cs
@@ -85,18 +85,20 @@ namespace log4net.Util
 				m_appenderArray = m_appenderList.ToArray();
 			}
 
-			foreach(IAppender appender in m_appenderArray)
+			int count = m_appenderArray.Length;
+			for (int i = 0; i < count; ++i)
 			{
 				try
 				{
-					appender.DoAppend(loggingEvent);
+					m_appenderArray[i].DoAppend(loggingEvent);
 				}
 				catch(Exception ex)
 				{
-					LogLog.Error(declaringType, "Failed to append to appender [" + appender.Name + "]", ex);
+					LogLog.Error(declaringType, "Failed to append to appender [" + m_appenderArray[i].Name + "]", ex);
 				}
 			}
-			return m_appenderList.Count;
+
+			return count;
 		}
 
 		/// <summary>
@@ -153,9 +155,9 @@ namespace log4net.Util
 
 		#endregion Public Instance Methods
 
-        #region Private Static Methods
+		#region Private Static Methods
 
-        /// <summary>
+		/// <summary>
 		/// Calls the DoAppende method on the <see cref="IAppender"/> with 
 		/// the <see cref="LoggingEvent"/> objects supplied.
 		/// </summary>
@@ -183,13 +185,13 @@ namespace log4net.Util
 					appender.DoAppend(loggingEvent);
 				}
 			}
-        }
+		}
 
-        #endregion
+		#endregion
 
-        #region Implementation of IAppenderAttachable
+		#region Implementation of IAppenderAttachable
 
-        /// <summary>
+		/// <summary>
 		/// Attaches an appender.
 		/// </summary>
 		/// <param name="newAppender">The appender to add.</param>
@@ -211,10 +213,19 @@ namespace log4net.Util
 			{
 				m_appenderList = new AppenderCollection(1);
 			}
+
+#if (NET_4_5 && PARALLEL_APPENDERS)
+			var newParallelIAppender = new ParallelIAppender(newAppender);
+			if (!m_appenderList.Contains(newParallelIAppender))
+			{
+				m_appenderList.Add(newParallelIAppender);
+			}
+#else
 			if (!m_appenderList.Contains(newAppender))
 			{
 				m_appenderList.Add(newAppender);
 			}
+#endif
 		}
 
 		/// <summary>
@@ -270,7 +281,8 @@ namespace log4net.Util
 					}
 				}
 			}
-			return null;   
+
+			return null;
 		}
 
 		/// <summary>
@@ -360,17 +372,17 @@ namespace log4net.Util
 
 		#endregion Private Instance Fields
 
-	    #region Private Static Fields
+		#region Private Static Fields
 
-	    /// <summary>
-	    /// The fully qualified type of the AppenderAttachedImpl class.
-	    /// </summary>
-	    /// <remarks>
-	    /// Used by the internal logger to record the Type of the
-	    /// log message.
-	    /// </remarks>
-	    private readonly static Type declaringType = typeof(AppenderAttachedImpl);
+		/// <summary>
+		/// The fully qualified type of the AppenderAttachedImpl class.
+		/// </summary>
+		/// <remarks>
+		/// Used by the internal logger to record the Type of the
+		/// log message.
+		/// </remarks>
+		private readonly static Type declaringType = typeof(AppenderAttachedImpl);
 
-	    #endregion Private Static Fields
+		#endregion Private Static Fields
 	}
 }

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/897ef682/src/Util/ParallelIAppender.cs
----------------------------------------------------------------------
diff --git a/src/Util/ParallelIAppender.cs b/src/Util/ParallelIAppender.cs
new file mode 100644
index 0000000..81b3860
--- /dev/null
+++ b/src/Util/ParallelIAppender.cs
@@ -0,0 +1,214 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more 
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership. 
+// The ASF licenses this file to you under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with 
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+#if (NET_4_5 && PARALLEL_APPENDERS)
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using log4net.Appender;
+using log4net.Core;
+
+namespace log4net.Util
+{
+	/// <summary>
+	/// This class allows AppenderAttachedImpl class to call appenders in "parallel".
+	/// </summary>
+	/// <remarks>
+	/// <para>
+	/// By implementing <see cref="IAppender"/> interface
+	/// allows AppenderAttacedImpl to call appenders in "parallel".
+	/// That allows to mitigate performance impedance between appenders and
+	/// provides better overall performance.
+	/// </para>
+	/// </remarks>
+	/// <author>Harry Martyrossian</author>
+	public class ParallelIAppender : IAppender
+	{
+		private static readonly Type declaringType = typeof(ParallelIAppender);
+		private IAppender appender;
+		private object synchObject = new object();
+		private PulseCode pulseCode = PulseCode.NotSignaled;
+		private Queue<LoggingEvent> events = new Queue<LoggingEvent>();
+		private LoggingEvent[] arrayOfEvents;
+		private Task appenderTask;
+
+		#region Public Instance Constructors
+		/// <summary>
+		/// Constructor
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Initializes a new instance of the <see cref="ParallelIAppender"/> class.
+		/// </para>
+		/// </remarks>
+		public ParallelIAppender(IAppender appender)
+		{
+			this.appender = appender;
+			this.appenderTask = Task.Run(() => this.Append());
+		}
+		#endregion Public Instance Constructors
+
+		[Flags]
+		internal enum PulseCode : int
+		{
+			NotSignaled,
+			QueueIsNotEmpty,
+			ExitThread
+		}
+
+		#region Override implementation of Object
+		/// <summary>
+		/// Determines whether two <see cref="ParallelIAppender" /> instances 
+		/// are equal.
+		/// </summary>
+		/// <param name="obj">The <see cref="object" /> to compare with the current <see cref="ParallelIAppender" />.</param>
+		/// <returns>
+		/// <c>true</c> if the specified <see cref="object" /> is equal to the current <see cref="ParallelIAppender" />; otherwise, <c>false</c>.
+		/// </returns>
+		/// <remarks>
+		/// <para>
+		/// Compares the implementations of <see cref="IAppender" /> interface.
+		/// </para>
+		/// </remarks>
+		public override bool Equals(object obj)
+		{
+			return this.Equals(obj as ParallelIAppender);
+		}
+
+		/// <summary>
+		/// Compares implementations of IAppender interface.
+		/// </summary>
+		/// <param name="obj">The object to compare against.</param>
+		/// <returns><c>true</c> if the objects are equal.</returns>
+		/// <remarks>
+		/// <para>
+		/// Compares implementations of <see cref="IAppender" /> interface, and
+		/// defers to base class if the target object is not a <see cref="ParallelIAppender" />
+		/// instance.
+		/// </para>
+		/// </remarks>
+		public virtual bool Equals(ParallelIAppender obj)
+		{
+			if (obj == null)
+			{
+				return false;
+			}
+			return this.appender.Equals(obj);
+		}
+
+		/// <summary>
+		/// Returns a hash code
+		/// </summary>
+		/// <returns>A hash code for the current implementation of the <see cref="IAppender" /> interface.</returns>
+		/// <remarks>
+		/// <para>
+		/// Returns a hash code suitable for use in hashing algorithms and data 
+		/// structures like a hash table.
+		/// </para>
+		/// <para>
+		/// Returns the hash code of the <see cref="IAppender"/> interface implementation.
+		/// </para>
+		/// </remarks>
+		public override int GetHashCode()
+		{
+			return this.appender.GetHashCode();
+		}
+		#endregion Override implementation of Object
+
+		#region Implementation of IAppender
+		string IAppender.Name
+		{
+			get
+			{
+				return this.appender.Name;
+			}
+			set
+			{
+				this.appender.Name = value;
+			}
+		}
+
+		void IAppender.Close()
+		{
+			lock (this.synchObject)
+			{
+				this.pulseCode |= PulseCode.ExitThread;
+				Monitor.Pulse(this.synchObject);
+			}
+			this.appenderTask.Wait();
+			this.appender.Close();
+		}
+
+		void IAppender.DoAppend(LoggingEvent loggingEvent)
+		{
+			lock (this.synchObject)
+			{
+				this.events.Enqueue(loggingEvent);
+				this.pulseCode |= PulseCode.QueueIsNotEmpty;
+				Monitor.Pulse(this.synchObject);
+			}
+		}
+		#endregion Implementation of IAppender
+
+		private void Append()
+		{
+			bool keepRunning = true;
+			do
+			{
+				lock (this.synchObject)
+				{
+					if (this.pulseCode == PulseCode.NotSignaled)
+					{
+						Monitor.Wait(this.synchObject);
+					}
+					if ((this.pulseCode & PulseCode.QueueIsNotEmpty) == PulseCode.QueueIsNotEmpty)
+					{
+						this.pulseCode ^= PulseCode.QueueIsNotEmpty;
+					}
+					if ((this.pulseCode & PulseCode.ExitThread) == PulseCode.ExitThread)
+					{
+						this.pulseCode ^= PulseCode.ExitThread;
+						keepRunning = false;
+					}
+					this.CopyEvents();
+				}
+				this.CallDoAppend();
+			}
+			while (keepRunning);
+		}
+
+		private void CopyEvents()
+		{
+			this.arrayOfEvents = this.events.ToArray();
+			this.events.Clear();
+		}
+
+		private void CallDoAppend()
+		{
+			var length = this.arrayOfEvents.Length;
+			for (int i = 0; i < length; ++i)
+			{
+				this.appender.DoAppend(this.arrayOfEvents[i]);
+			}
+		}
+	}
+}
+#endif

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/897ef682/src/log4net.vs2015.csproj
----------------------------------------------------------------------
diff --git a/src/log4net.vs2015.csproj b/src/log4net.vs2015.csproj
new file mode 100644
index 0000000..9594046
--- /dev/null
+++ b/src/log4net.vs2015.csproj
@@ -0,0 +1,809 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{181FE707-E161-4722-9F38-6AAAB6FAA106}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>log4net</AssemblyName>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Library</OutputType>
+    <RootNamespace>log4net</RootNamespace>
+    <StartupObject>
+    </StartupObject>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>..\build\bin\net\4.5\debug\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;DEBUG;NET;NET_2_0;NET_4_0;NET_4_5;PARALLEL_APPENDERS;</DefineConstants>
+    <DocumentationFile>log4net.xml</DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>SecurityRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>..\build\bin\net\4.5\release\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;STRONG;NET;NET_2_0;NET_4_0;NET_4_5;PARALLEL_APPENDERS;</DefineConstants>
+    <DocumentationFile>log4net.xml</DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.configuration" />
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Web">
+      <Name>System.Web</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Appender\AdoNetAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\AnsiColorTerminalAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\AppenderCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\AppenderSkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\AspNetTraceAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\BufferingAppenderSkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\BufferingForwardingAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\ColoredConsoleAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\ConsoleAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\DebugAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\EventLogAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\FileAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\ForwardingAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\IAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\IBulkAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\IFlushable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\LocalSyslogAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\ManagedColoredConsoleAppender.cs" />
+    <Compile Include="Appender\MemoryAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\NetSendAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\OutputDebugStringAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\RemoteSyslogAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\RemotingAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\RollingFileAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\SmtpAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\SmtpPickupDirAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\TelnetAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\TextWriterAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\TraceAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\UdpAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="AssemblyVersionInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\AliasDomainAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\AliasRepositoryAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\BasicConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\ConfiguratorAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\DomainAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\DOMConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\DOMConfiguratorAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\Log4NetConfigurationSectionHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\PluginAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\RepositoryAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\SecurityContextProviderAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\XmlConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Config\XmlConfiguratorAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\CompactRepositorySelector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\DefaultRepositorySelector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ErrorCode.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ExceptionEvaluator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\IAppenderAttachable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\IErrorHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\IFixingRequired.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ILogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ILoggerWrapper.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\IOptionHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\IRepositorySelector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ITriggeringEventEvaluator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\Level.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LevelCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LevelEvaluator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LevelMap.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LocationInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LogException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LoggerManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LoggerWrapperImpl.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LoggingEvent.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\LogImpl.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\MethodItem.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\SecurityContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\SecurityContextProvider.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\StackFrameItem.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\TimeEvaluator.cs" />
+    <Compile Include="Core\WrapperMap.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateFormatter\AbsoluteTimeDateFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateFormatter\DateTimeDateFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateFormatter\IDateFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateFormatter\Iso8601DateFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="DateFormatter\SimpleDateFormatter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\DenyAllFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\FilterDecision.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\FilterSkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\IFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\LevelMatchFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\LevelRangeFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\LoggerMatchFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\MdcFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\NdcFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\PropertyFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Filter\StringMatchFilter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="GlobalContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ILog.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\DynamicPatternLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\ExceptionLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\ILayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\IRawLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Layout2RawLayoutAdapter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\LayoutSkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\PatternLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AppDomainPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AspNetCachePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AspNetContextPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AspNetPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AspNetRequestPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\AspNetSessionPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\DatePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\ExceptionPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\FileLocationPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\FullLocationPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\IdentityPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\LevelPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\LineLocationPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\LoggerPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\MessagePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\MethodLocationPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\NamedPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\NdcPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\PatternLayoutConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\PropertyPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\RelativeTimePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\StackTraceDetailPatternConverter.cs" />
+    <Compile Include="Layout\Pattern\StackTracePatternConverter.cs" />
+    <Compile Include="Layout\Pattern\ThreadPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\TypeNamePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\UserNamePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\Pattern\UtcDatePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\RawLayoutConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\RawPropertyLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\RawTimeStampLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\RawUtcTimeStampLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\SimpleLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\XmlLayout.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\XmlLayoutBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\XmlLayoutSchemaLog4j.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogicalThreadContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LogManager.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="MDC.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="NDC.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ObjectRenderer\DefaultRenderer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ObjectRenderer\IObjectRenderer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ObjectRenderer\RendererMap.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\IPlugin.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\IPluginFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\PluginCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\PluginMap.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\PluginSkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Plugin\RemoteLoggingServerPlugin.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\ConfigurationChangedEventArgs.cs" />
+    <Compile Include="Repository\Hierarchy\DefaultLoggerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\Hierarchy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\ILoggerFactory.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\Logger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\LoggerKey.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\ProvisionNode.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\RootLogger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\Hierarchy\XmlHierarchyConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\IBasicRepositoryConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\ILoggerRepository.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\IXmlRepositoryConfigurator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Repository\LoggerRepositorySkeleton.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="ThreadContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\AppenderAttachedImpl.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\CompositeProperties.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ContextPropertiesBase.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ConverterInfo.cs" />
+    <Compile Include="Util\CountingQuietTextWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\CyclicBuffer.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\EmptyCollection.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\EmptyDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\FormattingInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\GlobalContextProperties.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ILogExtensions.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LevelMapping.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LevelMappingEntry.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LogicalThreadContextProperties.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LogLog.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\NativeError.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\NullDictionaryEnumerator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\NullEnumerator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\NullSecurityContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\OnlyOnceErrorHandler.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\OptionConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ParallelIAppender.cs" />
+    <Compile Include="Util\PatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternParser.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternString.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\AppDomainPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\AppSettingPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\DatePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\EnvironmentFolderPathPatternConverter.cs" />
+    <Compile Include="Util\PatternStringConverters\EnvironmentPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\IdentityPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\LiteralPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\NewLinePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\ProcessIdPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\PropertyPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\RandomStringPatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\UserNamePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PatternStringConverters\UtcDatePatternConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PropertiesDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\PropertyEntry.cs" />
+    <Compile Include="Util\ProtectCloseTextWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\QuietTextWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ReaderWriterLock.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ReadOnlyPropertiesDictionary.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ReusableStringWriter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\SystemInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\SystemStringFormat.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TextWriterAdapter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ThreadContextProperties.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LogicalThreadContextStack.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ThreadContextStack.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\LogicalThreadContextStacks.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\ThreadContextStacks.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\Transform.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\BooleanConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\ConversionNotSupportedException.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\ConverterRegistry.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\EncodingConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\IConvertFrom.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\IConvertTo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\IPAddressConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\PatternLayoutConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\PatternStringConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\TypeConverter.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TypeConverters\TypeConverterAttribute.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\WindowsSecurityContext.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/897ef682/src/log4net.vs2015.sln
----------------------------------------------------------------------
diff --git a/src/log4net.vs2015.sln b/src/log4net.vs2015.sln
new file mode 100644
index 0000000..2612780
--- /dev/null
+++ b/src/log4net.vs2015.sln
@@ -0,0 +1,27 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.Tests.vs2015", "..\tests\src\log4net.Tests.vs2015.csproj", "{B0530F10-0238-49A9-93B0-8EF412E90BCF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "log4net.vs2015", "log4net.vs2015.csproj", "{181FE707-E161-4722-9F38-6AAAB6FAA106}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B0530F10-0238-49A9-93B0-8EF412E90BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B0530F10-0238-49A9-93B0-8EF412E90BCF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{181FE707-E161-4722-9F38-6AAAB6FAA106}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{181FE707-E161-4722-9F38-6AAAB6FAA106}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/897ef682/tests/src/log4net.Tests.vs2015.csproj
----------------------------------------------------------------------
diff --git a/tests/src/log4net.Tests.vs2015.csproj b/tests/src/log4net.Tests.vs2015.csproj
new file mode 100644
index 0000000..89cd253
--- /dev/null
+++ b/tests/src/log4net.Tests.vs2015.csproj
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{B0530F10-0238-49A9-93B0-8EF412E90BCF}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>log4net.Tests</AssemblyName>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Library</OutputType>
+    <RootNamespace>log4net.Tests</RootNamespace>
+    <StartupObject>
+    </StartupObject>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>..\bin\Debug\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;DEBUG;NET;NET_2_0;NET_4_0;NET_4_5;</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>..\bin\Release\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;NET;NET_2_0;NET_4_0;NET_4_5</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <HintPath>..\..\src\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.configuration" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Runtime.Remoting">
+      <Name>System.Runtime.Remoting</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\src\AssemblyVersionInfo.cs">
+      <Link>AssemblyVersionInfo.cs</Link>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\AdoNetAppenderTest.cs" />
+    <Compile Include="Appender\AdoNet\Log4NetCommand.cs" />
+    <Compile Include="Appender\AdoNet\Log4NetConnection.cs" />
+    <Compile Include="Appender\AdoNet\Log4NetParameter.cs" />
+    <Compile Include="Appender\AdoNet\Log4NetParameterCollection.cs" />
+    <Compile Include="Appender\AdoNet\Log4NetTransaction.cs" />
+    <Compile Include="Appender\AppenderCollectionTest.cs" />
+    <Compile Include="Appender\BufferingAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\CountingAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\EventLogAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\MemoryAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\RemotingAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\SmtpPickupDirAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\RollingFileAppenderTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\StringAppender.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Appender\TraceAppenderTest.cs" />
+    <Compile Include="AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Context\LogicalThreadContextTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Context\ThreadContextTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\EvaluatorTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\FixingTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\ShutdownTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Core\StringFormatTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Hierarchy\Hierarchy.cs" />
+    <Compile Include="Hierarchy\Logger.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\DynamicPatternLayoutTest.cs" />
+    <Compile Include="Layout\PatternLayoutTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Layout\XmlLayoutTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LoggerRepository\ConfigurationMessages.cs" />
+    <Compile Include="Filter\FilterTest.cs" />
+    <Compile Include="Utils.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\CyclicBufferTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\EnvironmentPatternConverterTest.cs" />
+    <Compile Include="Util\LogLogTest.cs" />
+    <Compile Include="Util\PatternConverterTest.cs" />
+    <Compile Include="Util\PatternStringTest.cs" />
+    <Compile Include="Util\PropertiesDictionaryTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\RandomStringPatternConverterTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\SystemInfoTest.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Util\TransformTest.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\log4net.vs2012.csproj">
+      <Project>{181fe707-e161-4722-9f38-6aaab6faa106}</Project>
+      <Name>log4net.vs2012</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file


[09/10] logging-log4net git commit: improve performance get_UserName in LoggingEvent.cs

Posted by dp...@apache.org.
improve performance get_UserName in LoggingEvent.cs


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/8a82ed76
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/8a82ed76
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/8a82ed76

Branch: refs/heads/pr/old/45
Commit: 8a82ed76474c48343eda7f769e1989f43ce42f7e
Parents: 87e8a49
Author: zyrainovdv <zy...@skbkontur.ru>
Authored: Thu Mar 16 17:09:45 2017 +0500
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:42:32 2017 +0200

----------------------------------------------------------------------
 src/Core/LoggingEvent.cs            |  53 +------------
 src/Core/WindowsIdentityProvider.cs | 123 +++++++++++++++++++++++++++++++
 src/log4net.vs2008.csproj           |   1 +
 src/log4net.vs2010.csproj           |   1 +
 src/log4net.vs2012.csproj           |   1 +
 5 files changed, 128 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/8a82ed76/src/Core/LoggingEvent.cs
----------------------------------------------------------------------
diff --git a/src/Core/LoggingEvent.cs b/src/Core/LoggingEvent.cs
index eb54a60..751d521 100644
--- a/src/Core/LoggingEvent.cs
+++ b/src/Core/LoggingEvent.cs
@@ -22,9 +22,6 @@ using System.Collections;
 using System.IO;
 #if (!NETCF)
 using System.Runtime.Serialization;
-#if !NETSTANDARD1_3
-using System.Security.Principal;
-#endif
 #endif
 
 using log4net.Util;
@@ -852,45 +849,6 @@ namespace log4net.Core
 		/// underlying runtime has no support for retrieving the name of the 
 		/// current user.
 		/// </value>
-		/// <remarks>
-		/// <para>
-		/// Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of
-		/// the current windows user.
-		/// </para>
-		/// <para>
-		/// To improve performance, we could cache the string representation of 
-		/// the name, and reuse that as long as the identity stayed constant.  
-		/// Once the identity changed, we would need to re-assign and re-render 
-		/// the string.
-		/// </para>
-		/// <para>
-		/// However, the <c>WindowsIdentity.GetCurrent()</c> call seems to 
-		/// return different objects every time, so the current implementation 
-		/// doesn't do this type of caching.
-		/// </para>
-		/// <para>
-		/// Timing for these operations:
-		/// </para>
-		/// <list type="table">
-		///   <listheader>
-		///     <term>Method</term>
-		///     <description>Results</description>
-		///   </listheader>
-		///   <item>
-		///	    <term><c>WindowsIdentity.GetCurrent()</c></term>
-		///	    <description>10000 loops, 00:00:00.2031250 seconds</description>
-		///   </item>
-		///   <item>
-		///	    <term><c>WindowsIdentity.GetCurrent().Name</c></term>
-		///	    <description>10000 loops, 00:00:08.0468750 seconds</description>
-		///   </item>
-		/// </list>
-		/// <para>
-		/// This means we could speed things up almost 40 times by caching the 
-		/// value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since 
-		/// this takes (8.04-0.20) = 7.84375 seconds.
-		/// </para>
-		/// </remarks>
 		public string UserName
 		{
 			get
@@ -903,15 +861,8 @@ namespace log4net.Core
 #else
 					try
 					{
-						WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
-						if (windowsIdentity != null && windowsIdentity.Name != null)
-						{
-							m_data.UserName = windowsIdentity.Name;
-						}
-						else
-						{
-							m_data.UserName = "";
-						}
+						var currentIdentityName = WindowsIdentityProvider.CurrentIdentityName;
+						m_data.UserName = currentIdentityName ?? "";
 					}
 					catch(System.Security.SecurityException)
 					{

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/8a82ed76/src/Core/WindowsIdentityProvider.cs
----------------------------------------------------------------------
diff --git a/src/Core/WindowsIdentityProvider.cs b/src/Core/WindowsIdentityProvider.cs
new file mode 100644
index 0000000..9f6427d
--- /dev/null
+++ b/src/Core/WindowsIdentityProvider.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Security;
+using System.Security.Principal;
+using System.Threading;
+using log4net.Util;
+
+namespace log4net.Core
+{
+	/// <summary>
+	/// Provide methods for interactions with WindowsIdentity.
+	/// </summary>
+	public class WindowsIdentityProvider
+	{
+		private readonly static Type declaringType = typeof(WindowsIdentityProvider);
+
+		#region Public Static Properties
+
+		/// <summary>
+		/// Gets the cached name of the current WindowsIdentity.
+		/// </summary>
+		/// <value>
+		/// The cached name of the current WindowsIdentity.
+		/// </value>
+		/// <exception cref="SecurityException"/>
+		/// <remarks>
+		/// <para>
+		/// Gets the cached name of the current WindowsIdentity.
+		/// </para>
+		/// <para>
+		/// Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of
+		/// the current windows user and cache it.
+		/// </para>
+		/// </remarks>
+		public static string CurrentIdentityName
+		{
+			get
+			{
+				if (s_currentIdentityName != null)
+					return s_currentIdentityName;
+				lock (s_syncRoot)
+				{
+					if (s_currentIdentityName != null)
+						return s_currentIdentityName;
+					s_currentIdentityName = GetCurrentIdentityName();
+					s_updateCurrentIdentityNameTimer = new Timer(UpdateCurrentIdentityName, null, s_updateCurrentIdentityNameInterval, s_updateCurrentIdentityNameInterval);
+				}
+				return s_currentIdentityName;
+			}
+		}
+
+		private static void UpdateCurrentIdentityName(object state)
+		{
+			try
+			{
+				var identityName = GetCurrentIdentityName();
+				if (!string.IsNullOrEmpty(identityName))
+				{
+					s_currentIdentityName = identityName;
+				}
+			}
+			catch (SecurityException)
+			{
+				// This security exception will occur if the caller does not have 
+				// some undefined set of SecurityPermission flags.
+				LogLog.Debug(declaringType, "Security exception while trying to get current windows identity. Error Ignored. Empty user name.");
+			}
+		}
+
+		/// <para>
+		/// Timing for these operations:
+		/// </para>
+		/// <list type="table">
+		///   <listheader>
+		///     <term>Method</term>
+		///     <description>Results</description>
+		///   </listheader>
+		///   <item>
+		///	    <term><c>WindowsIdentity.GetCurrent()</c></term>
+		///	    <description>10000 loops, 00:00:00.2031250 seconds</description>
+		///   </item>
+		///   <item>
+		///	    <term><c>WindowsIdentity.GetCurrent().Name</c></term>
+		///	    <description>10000 loops, 00:00:08.0468750 seconds</description>
+		///   </item>
+		/// </list>
+		/// <para>
+		/// This means we could speed things up almost 40 times by caching the 
+		/// value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since 
+		/// this takes (8.04-0.20) = 7.84375 seconds.
+		/// </para>
+		private static string GetCurrentIdentityName()
+		{
+			WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
+			return windowsIdentity.Name ?? "";
+		}
+
+		#endregion
+
+		#region Private Static Fields
+
+		/// <summary>
+		/// Lock object used to synchronize updates within this instance.
+		/// </summary>
+		private readonly static object s_syncRoot = new object();
+
+		/// <summary>
+		/// Interval for current Identity Name updates.
+		/// </summary>
+		private readonly static TimeSpan s_updateCurrentIdentityNameInterval = TimeSpan.FromSeconds(1);
+
+		/// <summary>
+		/// Timer for current Identity Name updates.
+		/// </summary>
+		private static Timer s_updateCurrentIdentityNameTimer;
+
+		/// <value>
+		/// The cached name of the current WindowsIdentity.
+		/// </value>
+		private static volatile string s_currentIdentityName;
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/8a82ed76/src/log4net.vs2008.csproj
----------------------------------------------------------------------
diff --git a/src/log4net.vs2008.csproj b/src/log4net.vs2008.csproj
index 1166930..1500778 100644
--- a/src/log4net.vs2008.csproj
+++ b/src/log4net.vs2008.csproj
@@ -317,6 +317,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Core\TimeEvaluator.cs" />
+    <Compile Include="Core\WindowsIdentityProvider.cs" />
     <Compile Include="Core\WrapperMap.cs">
       <SubType>Code</SubType>
     </Compile>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/8a82ed76/src/log4net.vs2010.csproj
----------------------------------------------------------------------
diff --git a/src/log4net.vs2010.csproj b/src/log4net.vs2010.csproj
index 7865f1e..5661830 100644
--- a/src/log4net.vs2010.csproj
+++ b/src/log4net.vs2010.csproj
@@ -333,6 +333,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Core\TimeEvaluator.cs" />
+    <Compile Include="Core\WindowsIdentityProvider.cs" />
     <Compile Include="Core\WrapperMap.cs">
       <SubType>Code</SubType>
     </Compile>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/8a82ed76/src/log4net.vs2012.csproj
----------------------------------------------------------------------
diff --git a/src/log4net.vs2012.csproj b/src/log4net.vs2012.csproj
index 05a7062..b221434 100644
--- a/src/log4net.vs2012.csproj
+++ b/src/log4net.vs2012.csproj
@@ -333,6 +333,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Core\TimeEvaluator.cs" />
+    <Compile Include="Core\WindowsIdentityProvider.cs" />
     <Compile Include="Core\WrapperMap.cs">
       <SubType>Code</SubType>
     </Compile>


[10/10] logging-log4net git commit: increase update Identity Name interval

Posted by dp...@apache.org.
increase update Identity Name interval


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/4ee46ecf
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/4ee46ecf
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/4ee46ecf

Branch: refs/heads/pr/old/45
Commit: 4ee46ecff04ed9abc55055be8e6c88ae670c10d6
Parents: 8a82ed7
Author: zyrainovdv <zy...@skbkontur.ru>
Authored: Tue Mar 21 21:52:34 2017 +0500
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:42:41 2017 +0200

----------------------------------------------------------------------
 src/Core/WindowsIdentityProvider.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/4ee46ecf/src/Core/WindowsIdentityProvider.cs
----------------------------------------------------------------------
diff --git a/src/Core/WindowsIdentityProvider.cs b/src/Core/WindowsIdentityProvider.cs
index 9f6427d..55853f3 100644
--- a/src/Core/WindowsIdentityProvider.cs
+++ b/src/Core/WindowsIdentityProvider.cs
@@ -106,7 +106,7 @@ namespace log4net.Core
 		/// <summary>
 		/// Interval for current Identity Name updates.
 		/// </summary>
-		private readonly static TimeSpan s_updateCurrentIdentityNameInterval = TimeSpan.FromSeconds(1);
+		private readonly static TimeSpan s_updateCurrentIdentityNameInterval = TimeSpan.FromSeconds(15);
 
 		/// <summary>
 		/// Timer for current Identity Name updates.


[02/10] logging-log4net git commit: Add test web app for asp extension

Posted by dp...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner1.svg
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner1.svg b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner1.svg
new file mode 100644
index 0000000..1ab32b6
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner1.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1140 360" enable-background="new 0 0 1140 360"><path fill="#56B4D9" d="M0 0h1140v360h-1140v-360z"/><path fill="#fff" d="M163.29 114.514h-3.996l-3.266-8.637h-13.063l-3.072 8.637h-4.018l11.816-30.809h3.738l11.861 30.809zm-8.443-11.881l-4.834-13.127c-.158-.43-.315-1.117-.473-2.063h-.086c-.144.874-.308 1.562-.494 2.063l-4.791 13.127h10.678zm10.921 10.635v-4.254c.487.43 1.07.816 1.751 1.16.68.344 1.396.634 2.148.87s1.507.419 2.267.548c.759.129 1.461.193 2.105.193 2.22 0 3.878-.412 4.974-1.235s1.644-2.009 1.644-3.556c0-.831-.183-1.554-.548-2.17s-.87-1.178-1.515-1.687-1.407-.995-2.288-1.461-1.83-.956-2.847-1.472c-1.074-.544-2.077-1.096-3.008-1.654-.931-.559-1.74-1.175-2.428-1.848s-1.229-1.436-1.622-2.288c-.394-.853-.591-1.852-.591-2.997 0-1.403.308-2.625.924-3.663.616-1.038 1.425-1.895 2.428-2.567 1.002-.673 2.145-1.175 3.427-1.504 1.282-.329 2.589-.494 3.921-.494 3.036 0 5.249.365 6.639 1.096v4.061c-1.819-1.261-4.154-1.891-7.004-1.891-.
 788 0-1.576.082-2.363.247-.788.165-1.49.434-2.105.806-.616.372-1.117.853-1.504 1.439s-.58 1.304-.58 2.148c0 .788.146 1.468.44 2.041.293.573.727 1.096 1.3 1.568.573.473 1.271.931 2.095 1.375.823.444 1.772.931 2.847 1.461 1.103.544 2.148 1.117 3.137 1.719s1.854 1.268 2.6 1.998c.745.73 1.335 1.54 1.772 2.428.437.888.655 1.905.655 3.051 0 1.519-.297 2.804-.892 3.856-.595 1.053-1.396 1.908-2.406 2.567s-2.174 1.135-3.491 1.429c-1.318.293-2.707.44-4.168.44-.487 0-1.089-.04-1.805-.118-.716-.079-1.447-.193-2.191-.344-.745-.15-1.45-.337-2.116-.559s-1.202-.467-1.602-.739zm27.808-10.399v11.645h-3.609v-30.809h8.465c3.294 0 5.847.802 7.659 2.406 1.812 1.604 2.718 3.867 2.718 6.789s-1.006 5.313-3.019 7.176c-2.013 1.862-4.73 2.793-8.153 2.793h-4.061zm0-15.898v12.633h3.781c2.492 0 4.394-.569 5.704-1.708s1.966-2.746 1.966-4.823c0-4.067-2.406-6.102-7.219-6.102h-4.232zm21.169 28.015c-.659 0-1.221-.236-1.687-.709-.466-.473-.698-1.038-.698-1.697s.232-1.229.698-1.708c.465-.479 1.027-.72 1.687-.72.673 0 1.
 246.24 1.719.72s.709 1.049.709 1.708-.236 1.225-.709 1.697-1.047.709-1.719.709zm33.007-.472h-4.426l-15.855-24.557c-.401-.616-.73-1.261-.988-1.934h-.129c.114.659.172 2.069.172 4.232v22.258h-3.609v-30.808h4.684l15.426 24.17c.645 1.003 1.06 1.69 1.246 2.063h.086c-.144-.888-.215-2.399-.215-4.533v-21.7h3.609v30.809zm23.79 0h-16.328v-30.809h15.641v3.266h-12.031v10.248h11.129v3.244h-11.129v10.785h12.719v3.266zm23.533-27.543h-8.895v27.543h-3.609v-27.543h-8.873v-3.266h21.377v3.266zm36.623 26.254c-2.277 1.203-5.113 1.805-8.508 1.805-4.383 0-7.892-1.411-10.527-4.232-2.636-2.821-3.953-6.524-3.953-11.107 0-4.927 1.482-8.909 4.447-11.945s6.725-4.555 11.279-4.555c2.922 0 5.342.423 7.262 1.268v3.846c-2.206-1.231-4.641-1.848-7.305-1.848-3.538 0-6.406 1.182-8.604 3.545-2.199 2.363-3.298 5.521-3.298 9.475 0 3.753 1.027 6.742 3.083 8.97 2.055 2.228 4.751 3.341 8.089 3.341 3.094 0 5.772-.688 8.035-2.063v3.5zm14.38 1.804c-3.251 0-5.848-1.027-7.788-3.083-1.941-2.056-2.911-4.78-2.911-8.175 0-3.695 1.01-6.5
 81 3.029-8.658s4.748-3.115 8.186-3.115c3.28 0 5.84 1.01 7.681 3.029 1.84 2.02 2.761 4.819 2.761 8.4 0 3.509-.992 6.32-2.976 8.433-1.984 2.113-4.645 3.169-7.982 3.169zm.258-20.066c-2.263 0-4.054.77-5.371 2.31-1.318 1.54-1.977 3.663-1.977 6.37 0 2.606.666 4.662 1.998 6.166s3.115 2.256 5.35 2.256c2.277 0 4.028-.737 5.253-2.213s1.837-3.573 1.837-6.295c0-2.75-.612-4.87-1.837-6.359s-2.976-2.235-5.253-2.235zm27.185 1.117c-.616-.473-1.504-.709-2.664-.709-1.504 0-2.761.709-3.771 2.127s-1.515 3.352-1.515 5.801v11.215h-3.523v-22h3.523v4.533h.086c.501-1.547 1.268-2.754 2.299-3.62s2.184-1.3 3.459-1.3c.917 0 1.618.101 2.105.301v3.652zm20.89 8.315h-15.533c.057 2.449.716 4.34 1.977 5.672 1.26 1.332 2.993 1.998 5.199 1.998 2.478 0 4.755-.816 6.832-2.449v3.309c-1.934 1.403-4.49 2.105-7.67 2.105-3.108 0-5.55-.999-7.326-2.997-1.776-1.998-2.664-4.809-2.664-8.433 0-3.423.97-6.213 2.911-8.368 1.94-2.155 4.351-3.233 7.229-3.233s5.106.931 6.682 2.793c1.575 1.862 2.363 4.447 2.363 7.756v1.847zm-3.61-2.987c-.
 015-2.034-.505-3.616-1.472-4.748s-2.31-1.697-4.028-1.697c-1.662 0-3.072.595-4.232 1.783s-1.876 2.743-2.148 4.662h11.88zm40.699-39.408h-1v74h1v-74zm83.592 54.095h-1.842l-7.165-24.235c-.359-1.243-.562-2.253-.606-3.032h-.09c-.045.659-.277 1.655-.696 2.987l-7.637 24.28h-1.842l-9.568-32.209h2.493l7.345 25.808c.329 1.168.562 2.119.696 2.853h.09c.09-.554.352-1.505.786-2.853l7.951-25.808h1.123l7.3 25.808c.344 1.198.576 2.149.696 2.853h.09c.075-.419.194-.898.359-1.438l7.547-27.223h2.403l-9.433 32.209zm14.445-28.795c-.449 0-.846-.165-1.19-.494-.345-.329-.517-.749-.517-1.258 0-.494.176-.895.528-1.202.352-.307.745-.46 1.179-.46.464 0 .872.15 1.224.449.352.3.528.704.528 1.213 0 .479-.172.891-.517 1.235-.344.345-.756.517-1.235.517zm-1.011 28.795v-23h2.066v23h-2.066zm24.239 0v-13.387c0-5.525-1.992-8.288-5.975-8.288-2.216 0-4.036.813-5.458 2.437-1.423 1.625-2.134 3.635-2.134 6.031v13.207h-2.066v-23h2.066v4.178h.09c1.677-3.159 4.297-4.739 7.861-4.739 2.485 0 4.387.828 5.705 2.482 1.317 1.655 1.977 4
 .017 1.977 7.086v13.993h-2.066zm24.485 0v-4.178h-.09c-.748 1.453-1.855 2.605-3.324 3.459-1.467.854-3.122 1.28-4.963 1.28-2.83 0-5.14-1.033-6.929-3.1-1.79-2.066-2.684-4.919-2.684-8.558 0-3.713.977-6.719 2.931-9.018 1.954-2.298 4.488-3.448 7.603-3.448 3.445 0 5.9 1.415 7.367 4.245h.09v-14.733h2.066v34.051h-2.067zm0-13.993c0-2.141-.678-3.957-2.031-5.447-1.355-1.49-3.18-2.235-5.47-2.235-2.411 0-4.402.925-5.975 2.774-1.572 1.85-2.358 4.391-2.358 7.625 0 3.175.708 5.626 2.123 7.356s3.238 2.594 5.469 2.594c2.62 0 4.649-.812 6.086-2.437 1.438-1.625 2.156-3.605 2.156-5.941v-4.289zm17.838 14.554c-3.354 0-6.009-1.104-7.962-3.313-1.955-2.208-2.932-5.08-2.932-8.614 0-3.818 1.021-6.806 3.066-8.962 2.043-2.156 4.735-3.234 8.074-3.234 3.279 0 5.87 1.071 7.771 3.212 1.901 2.142 2.853 5.106 2.853 8.895 0 3.579-.97 6.477-2.909 8.692-1.938 2.216-4.592 3.324-7.961 3.324zm.157-22.236c-2.71 0-4.87.914-6.48 2.74-1.609 1.827-2.414 4.365-2.414 7.614 0 3.01.786 5.428 2.358 7.255s3.721 2.74 6.446 2.74c2.771 0 
 4.904-.898 6.401-2.695s2.246-4.29 2.246-7.479c0-3.279-.745-5.795-2.235-7.547-1.489-1.752-3.596-2.628-6.322-2.628zm35.087 21.675h-1.932l-5.009-17.34c-.135-.479-.255-1.123-.359-1.932h-.112c-.03.345-.18.974-.449 1.887l-5.615 17.385h-1.932l-6.94-23h2.291l5.346 18.351c.135.479.239 1.123.314 1.932h.18c.03-.434.172-1.078.427-1.932l5.84-18.351h1.415l5.211 18.351c.12.435.225 1.078.314 1.932h.18c0-.434.127-1.078.382-1.932l5.458-18.351h2.134l-7.144 23zm9.616-1.011v-2.493c.778.674 1.722 1.206 2.83 1.595 1.108.39 2.066.584 2.875.584 3.608 0 5.413-1.475 5.413-4.425 0-1.018-.396-1.887-1.19-2.605s-2.081-1.46-3.863-2.224c-2.201-.958-3.747-1.95-4.638-2.976-.892-1.025-1.337-2.272-1.337-3.74 0-1.872.715-3.384 2.146-4.537 1.43-1.153 3.192-1.729 5.289-1.729 1.977 0 3.669.404 5.076 1.213v2.336c-1.707-1.108-3.474-1.662-5.301-1.662-1.513 0-2.732.393-3.661 1.179s-1.393 1.808-1.393 3.066c0 1.093.292 1.98.876 2.662.584.682 1.872 1.464 3.863 2.347 2.396 1.078 4.043 2.078 4.941 2.999s1.348 2.145 1.348 3.672c0 1.
 827-.686 3.335-2.055 4.526-1.371 1.19-3.261 1.786-5.672 1.786-2.215-.002-4.064-.526-5.547-1.574zm80.185 1.011v-32.209h2.224v30.188h12.915v2.021h-15.139zm20.802-28.795c-.449 0-.846-.165-1.19-.494-.345-.329-.517-.749-.517-1.258 0-.494.176-.895.528-1.202.352-.307.744-.46 1.179-.46.464 0 .872.15 1.224.449.353.3.528.704.528 1.213 0 .479-.172.891-.517 1.235-.345.345-.756.517-1.235.517zm-1.011 28.795v-23h2.066v23h-2.066zm24.238 0v-13.387c0-5.525-1.991-8.288-5.975-8.288-2.216 0-4.035.813-5.458 2.437-1.423 1.625-2.134 3.635-2.134 6.031v13.207h-2.066v-23h2.066v4.178h.09c1.677-3.159 4.298-4.739 7.861-4.739 2.485 0 4.388.828 5.705 2.482 1.317 1.655 1.977 4.017 1.977 7.086v13.993h-2.066zm23.34 0v-4.178h-.09c-1.603 3.16-4.073 4.739-7.412 4.739-5.436 0-8.153-3.421-8.153-10.265v-13.296h2.089v12.78c0 3.115.513 5.376 1.539 6.783 1.025 1.408 2.639 2.111 4.84 2.111 2.142 0 3.875-.786 5.199-2.358 1.326-1.572 1.988-3.668 1.988-6.289v-13.027h2.066v23h-2.066zm15.727-11.276l7.502 11.275h-2.628l-6.064-9.703h
 -.09l-.809 1.28c-.104.18-.232.382-.382.606l-5.076 7.816h-2.516l7.682-11.23-7.547-11.77h2.426l5.121 8.243c.659 1.063 1.056 1.722 1.19 1.977h.09l1.146-1.887 5.346-8.333h2.426l-7.817 11.726zm85.656 11.837c-4.552 0-8.18-1.512-10.883-4.537-2.702-3.024-4.054-6.955-4.054-11.792 0-5.136 1.389-9.25 4.167-12.342 2.777-3.092 6.569-4.638 11.376-4.638 4.343 0 7.857 1.486 10.546 4.458 2.688 2.973 4.031 6.87 4.031 11.691 0 5.331-1.378 9.523-4.133 12.578s-6.438 4.582-11.05 4.582zm.224-31.288c-3.743 0-6.824 1.355-9.242 4.065-2.419 2.71-3.628 6.259-3.628 10.646 0 4.433 1.146 7.962 3.437 10.59s5.346 3.942 9.164 3.942c3.983 0 7.135-1.299 9.456-3.897 2.321-2.598 3.481-6.218 3.481-10.86 0-4.552-1.135-8.104-3.402-10.658-2.27-2.551-5.357-3.828-9.266-3.828zm19.702 29.581v-2.538c2.306 1.468 4.642 2.201 7.008 2.201 2.516 0 4.425-.52 5.728-1.561s1.954-2.497 1.954-4.369c0-1.647-.438-2.961-1.313-3.942-.877-.98-2.774-2.317-5.694-4.009-3.265-1.901-5.331-3.493-6.199-4.773s-1.303-2.759-1.303-4.436c0-2.276.884-4.208 
 2.65-5.795 1.767-1.587 4.125-2.381 7.075-2.381 1.917 0 3.833.322 5.75.966v2.336c-1.887-.854-3.9-1.28-6.042-1.28-2.187 0-3.919.554-5.2 1.662-1.279 1.108-1.92 2.516-1.92 4.223 0 1.647.438 2.958 1.314 3.931.875.974 2.766 2.299 5.671 3.976 3.01 1.707 5.013 3.223 6.009 4.548.995 1.325 1.493 2.849 1.493 4.571 0 2.471-.857 4.485-2.571 6.042-1.715 1.558-4.137 2.336-7.267 2.336-1.108 0-2.385-.172-3.829-.517-1.446-.345-2.551-.742-3.314-1.191zm40.5 1.146l-7.412-12.286c-.464-.764-.861-1.512-1.19-2.246h-.112c-.404.824-.831 1.572-1.28 2.246l-7.547 12.286h-2.673l10.175-16.239-9.568-15.97h2.673l7.21 12.106c.374.629.764 1.348 1.168 2.156h.09l1.19-2.156 7.165-12.106h2.583l-9.658 15.925 9.883 16.284h-2.697z"/></svg>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner2.svg
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner2.svg b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner2.svg
new file mode 100644
index 0000000..9679c60
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner2.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1140 360" enable-background="new 0 0 1140 360"><path fill="#68217A" d="M0 0h1140v360h-1140v-360z"/><polygon fill="#E44D26" points="625.457,132.801 619.654,67.717 683.416,67.717 677.607,132.791 651.496,140.03"/><polygon fill="#F16529" points="651.535,134.497 672.634,128.648 677.598,73.039 651.535,73.039"/><polygon fill="#EBEBEB" points="651.535,97.178 640.973,97.178 640.243,89.004 651.535,89.004 651.535,81.021 651.508,81.021 631.519,81.021 631.71,83.163 633.672,105.16 651.535,105.16"/><polygon fill="#EBEBEB" points="651.535,117.909 651.5,117.918 642.61,115.517 642.042,109.151 637.722,109.151 634.029,109.151 635.147,121.685 651.499,126.224 651.535,126.214"/><path d="M625.587 50.03h4.057v4.008h3.711v-4.008h4.057v12.137h-4.057v-4.064h-3.711v4.064h-4.057v-12.137zm17.158 4.025h-3.571v-4.025h11.201v4.025h-3.573v8.112h-4.057v-8.112zm9.407-4.025h4.23l2.602 4.264 2.599-4.264h4.231v12.137h-4.04v-6.016l-2.791 4.315h-.07l-2.793-4.315v6.016h-3.
 969v-12.137zm15.682 0h4.058v8.125h5.705v4.012h-9.762v-12.137z"/><polygon fill="#fff" points="651.508,97.178 651.508,105.16 661.337,105.16 660.41,115.512 651.508,117.915 651.508,126.22 667.872,121.685 667.992,120.336 669.868,99.321 670.062,97.178 667.911,97.178"/><polygon fill="#fff" points="651.508,81.021 651.508,85.979 651.508,88.984 651.508,89.004 670.763,89.004 670.763,89.004 670.789,89.004 670.949,87.209 671.313,83.163 671.503,81.021"/><polygon points="777.75,55.803 777.75,51.656 767.862,51.656 767.862,63.777 777.75,63.777 777.75,59.631 772.008,59.631 772.008,55.803"/><polygon points="791.785,51.656 781.896,51.656 781.896,55.913 786.023,59.631 781.896,59.631 781.896,63.777 791.785,63.777 791.785,59.74 788.034,55.803 791.785,55.803"/><polygon points="806.138,51.656 796.25,51.656 796.25,55.913 800.217,59.631 796.25,59.631 796.25,63.777 806.138,63.777 806.138,59.74 802.228,55.803 806.138,55.803"/><polygon fill="#0071BC" points="760.908,134.424 755.103,69.309 818.897,69.309 813.085,
 134.413 786.961,141.656"/><polygon fill="#29ABE2" points="787.054,136.117 808.137,130.316 813.077,74.732 787.054,74.732"/><polygon fill="#B3B3B3" points="768.392,98.655 769.091,106.629 787.054,98.655 787.054,90.668"/><polygon fill="#E6E6E6" points="806.948,82.142 787.054,90.668 787.054,98.655 806.262,90.116"/><polygon fill="#E6E6E6" points="787.054,119.519 786.992,119.529 778.084,117.136 777.502,110.776 769.485,110.776 770.603,123.307 786.99,127.844 787.054,127.829"/><polygon fill="#fff" points="787.054,98.655 787.054,106.629 796.807,106.629 795.92,117.055 787.054,119.526 787.054,127.835 803.386,123.298 805.536,98.655"/><polygon fill="#E6E6E6" points="787.054,98.655 768.392,98.655 769.091,106.629 787.054,106.629"/><polygon fill="#E6E6E6" points="787.054,90.116 787.054,82.142 786.973,82.142 766.974,82.142 767.682,90.116"/><polygon fill="#fff" points="787.054,82.142 787.054,90.016 787.054,90.116 806.262,90.116 806.948,82.142"/><rect x="882.25" y="64.25" fill="#F0DB4F" width="70" heigh
 t="70"/><path fill="#353630" d="M929.272 118.938c1.41 2.302 3.244 3.994 6.489 3.994 2.726 0 4.467-1.362 4.467-3.244 0-2.256-1.789-3.054-4.789-4.367l-1.644-.706c-4.747-2.022-7.9-4.556-7.9-9.911 0-4.933 3.759-8.689 9.633-8.689 4.182 0 7.189 1.456 9.356 5.267l-5.122 3.289c-1.128-2.022-2.344-2.819-4.233-2.819-1.927 0-3.148 1.222-3.148 2.819 0 1.973 1.222 2.772 4.044 3.994l1.644.704c5.589 2.397 8.744 4.84 8.744 10.333 0 5.922-4.652 9.167-10.9 9.167-6.109 0-10.056-2.911-11.987-6.727l5.346-3.104zm-23.236.57c1.033 1.833 1.973 3.383 4.233 3.383 2.161 0 3.524-.846 3.524-4.133v-22.367h6.578v22.456c0 6.811-3.993 9.911-9.822 9.911-5.267 0-8.317-2.726-9.868-6.008l5.355-3.242z"/><path d="M296.374 83.453c0 .708-.246 1.296-.737 1.763-.494.47-1.076.704-1.752.704-.693 0-1.277-.227-1.752-.681-.477-.452-.715-1.048-.715-1.786 0-.66.234-1.234.703-1.717.468-.484 1.057-.727 1.765-.727.706 0 1.299.239 1.775.715.475.477.713 1.054.713 1.729zm177.29 0c0 .708-.245 1.296-.737 1.763-.494.47-1.076.704-1.752.704-.69
 3 0-1.277-.227-1.752-.681-.477-.452-.715-1.048-.715-1.786 0-.66.234-1.234.703-1.717.468-.484 1.057-.727 1.765-.727.706 0 1.299.239 1.775.715.475.477.713 1.054.713 1.729zm-184.79-1.697l-12.216 33.052h-4.241l-12.008-33.052h4.31l9.842 28.212h.092l10.072-28.212h4.149zm6.822 33.052h-3.78v-23.602h3.78v23.602zm19.173-6.316c0 2.044-.788 3.703-2.362 4.978-1.575 1.276-3.669 1.913-6.281 1.913-2.228 0-4.18-.476-5.854-1.429v-4.056c1.859 1.506 3.903 2.258 6.131 2.258 2.996 0 4.494-1.098 4.494-3.296 0-.891-.292-1.617-.876-2.178-.584-.561-1.913-1.317-3.988-2.27-2.09-.891-3.565-1.848-4.425-2.87-.861-1.022-1.291-2.378-1.291-4.068 0-1.951.784-3.58 2.351-4.886s3.557-1.959 5.97-1.959c1.859 0 3.542.369 5.048 1.106v3.803c-1.537-1.121-3.319-1.682-5.347-1.682-1.244 0-2.247.308-3.008.922-.761.614-1.141 1.406-1.141 2.374 0 1.045.292 1.848.876 2.408.584.561 1.79 1.226 3.619 1.994 2.243.953 3.818 1.951 4.725 2.996.906 1.046 1.359 2.36 1.359 3.942zm23.041 6.316h-3.78v-3.734h-.092c-1.567 2.873-3.987 4.31-7.26 4.3
 1-5.639 0-8.459-3.357-8.459-10.072v-14.106h3.78v13.507c0 4.964 1.905 7.444 5.716 7.444 1.875 0 3.396-.68 4.564-2.04 1.168-1.36 1.752-3.13 1.752-5.313v-13.598h3.78v23.602zm22.716 0h-3.78v-3.688h-.092c-1.644 2.843-4.064 4.264-7.26 4.264-2.274 0-4.095-.618-5.462-1.855-1.368-1.237-2.051-2.9-2.051-4.99 0-4.394 2.597-6.961 7.791-7.698l7.076-.991c0-3.995-1.621-5.993-4.863-5.993-2.843 0-5.409.96-7.698 2.881v-3.872c.692-.522 1.875-1.026 3.549-1.51 1.675-.484 3.165-.726 4.472-.726 5.547 0 8.321 2.943 8.321 8.828v15.35zm-3.78-11.94l-5.716.807c-1.952.276-3.319.741-4.103 1.394-.784.653-1.176 1.71-1.176 3.17 0 1.183.422 2.132 1.268 2.846.845.714 1.928 1.071 3.25 1.071 1.875 0 3.423-.66 4.644-1.982 1.222-1.321 1.832-2.973 1.832-4.956v-2.35zm13.13 11.94h-3.78v-34.942h3.78v34.942zm29.875-8.344c0 2.781-.983 4.964-2.95 6.546-1.967 1.583-4.641 2.374-8.021 2.374-1.23 0-2.616-.204-4.16-.611-1.544-.407-2.639-.833-3.284-1.279v-4.587c.937.845 2.17 1.552 3.699 2.121s2.954.853 4.276.853c4.241 0 6.361-1.652 6.
 361-4.956 0-1.383-.453-2.57-1.36-3.561-.907-.991-2.766-2.294-5.578-3.907-2.719-1.536-4.625-2.996-5.716-4.379-1.091-1.383-1.637-3.065-1.637-5.048 0-2.612.976-4.736 2.927-6.373 1.951-1.637 4.472-2.455 7.56-2.455 2.965 0 5.132.392 6.5 1.176v4.333c-1.721-1.352-3.957-2.028-6.707-2.028-1.829 0-3.323.457-4.483 1.371-1.16.914-1.74 2.124-1.74 3.63 0 1.091.173 1.967.519 2.627.346.661.93 1.314 1.752 1.959.822.646 2.209 1.514 4.16 2.604 2.919 1.629 4.963 3.166 6.131 4.61 1.167 1.446 1.751 3.105 1.751 4.98zm15.151 8.113c-.907.507-2.09.761-3.549.761-4.118 0-6.177-2.32-6.177-6.961v-13.967h-4.057v-3.204h4.057v-5.762l3.78-1.221v6.983h5.946v3.204h-5.946v13.322c0 1.583.269 2.709.807 3.377.538.668 1.437 1.003 2.697 1.003.937 0 1.752-.254 2.443-.761v3.226zm22.793.231h-3.78v-3.734h-.092c-1.567 2.873-3.987 4.31-7.26 4.31-5.639 0-8.459-3.357-8.459-10.072v-14.106h3.78v13.507c0 4.964 1.905 7.444 5.716 7.444 1.874 0 3.396-.68 4.563-2.04 1.168-1.36 1.752-3.13 1.752-5.313v-13.598h3.78v23.602zm25.871 0h-3.78v-4.
 011h-.092c-1.752 3.058-4.456 4.587-8.113 4.587-2.981 0-5.355-1.071-7.122-3.215-1.767-2.143-2.651-5.005-2.651-8.586 0-3.902.98-7.037 2.939-9.404 1.959-2.366 4.583-3.549 7.871-3.549 3.227 0 5.585 1.276 7.076 3.826h.092v-14.59h3.78v34.942zm-3.78-10.672v-3.48c0-1.951-.65-3.572-1.948-4.863-1.299-1.291-2.878-1.936-4.737-1.936-2.274 0-4.079.841-5.416 2.524s-2.005 4.015-2.005 6.995c0 2.705.63 4.844 1.89 6.419 1.26 1.575 2.958 2.363 5.094 2.363 2.074 0 3.78-.752 5.117-2.258 1.337-1.508 2.005-3.428 2.005-5.764zm13.282 10.672h-3.78v-23.602h3.78v23.602zm27.536-11.893c0 3.749-1.064 6.765-3.192 9.047-2.128 2.282-4.982 3.423-8.563 3.423-3.488 0-6.273-1.11-8.355-3.33-2.082-2.22-3.123-5.143-3.123-8.77 0-3.903 1.068-6.987 3.204-9.254 2.135-2.266 5.078-3.4 8.828-3.4 3.503 0 6.246 1.095 8.228 3.285 1.982 2.188 2.973 5.188 2.973 8.999zm-3.872.138c0-2.965-.657-5.24-1.971-6.823-1.314-1.582-3.192-2.374-5.635-2.374-2.428 0-4.349.811-5.762 2.432-1.414 1.621-2.12 3.906-2.12 6.857 0 2.828.71 5.036 2.132 6.626 
 1.421 1.59 3.338 2.385 5.751 2.385 2.458 0 4.341-.784 5.647-2.351 1.304-1.566 1.958-3.817 1.958-6.752zm-266.807-32.32l-21.866 21.866-13.946-10.847-5.509 2.754v27.547l5.509 2.755 13.946-10.848 21.866 21.866 13.774-5.509v-44.075l-13.774-5.509zm-35.812 35.811v-16.528l8.265 8.265-8.265 8.263zm21.251-8.263l14.561-11.326v22.651l-14.561-11.325z" fill="#fff"/><rect x="548.5" y="61" fill="#fff" width="1" height="74"/></svg>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner3.svg
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner3.svg b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner3.svg
new file mode 100644
index 0000000..9be2c25
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner3.svg
@@ -0,0 +1 @@
+<svg id="bg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1140 360"><defs><style>.cls-1{fill:#7fba00;}.cls-2{fill:#fff;}</style></defs><title>banner3b</title><path class="cls-1" d="M0,0H1140V360H0V0Z"/><path class="cls-2" d="M160.65,102.95v11.64H157V83.78h8.46q4.94,0,7.66,2.41A8.59,8.59,0,0,1,175.88,93a9.34,9.34,0,0,1-3,7.18,11.53,11.53,0,0,1-8.15,2.79h-4.06Zm0-15.9V99.68h3.78a8.45,8.45,0,0,0,5.7-1.71,6,6,0,0,0,2-4.82q0-6.1-7.22-6.1h-4.23Zm34.19,27.54h-3.52v-3.44h-0.09a7.38,7.38,0,0,1-6.77,4,7.23,7.23,0,0,1-5.15-1.74,6,6,0,0,1-1.86-4.62q0-6.17,7.26-7.18l6.6-.92q0-5.61-4.53-5.61a10.83,10.83,0,0,0-7.18,2.71V94.14a13.63,13.63,0,0,1,7.48-2.06q7.76,0,7.76,8.21v14.31Zm-3.52-11.13-5.31.73a8.62,8.62,0,0,0-3.7,1.21,3.5,3.5,0,0,0-1.25,3.08,3.36,3.36,0,0,0,1.15,2.63,4.44,4.44,0,0,0,3.06,1,5.66,5.66,0,0,0,4.33-1.84,6.56,6.56,0,0,0,1.71-4.65v-2.19Zm24.54,10.12a11.45,11.45,0,0,1-6,1.53,10,10,0,0,1-7.59-3.06,11.09,11.09,0,0,1-2.89-7.94,12.2,12.2,0,0,1,3.12-8.73,10.9,10.9,0,0,1,8.31-3.3,11.58,11
 .58,0,0,1,5.11,1.07v3.61A9,9,0,0,0,210.66,95a7.08,7.08,0,0,0-5.53,2.42,9.17,9.17,0,0,0-2.16,6.35,8.73,8.73,0,0,0,2,6.1,7,7,0,0,0,5.45,2.23,8.83,8.83,0,0,0,5.41-1.91v3.35Zm23,1h-4.94L224.18,104h-0.09v10.57h-3.52V82h3.52v20.65h0.09l9.24-10.08H238l-10.21,10.61Zm18.74,0H254v-3.44H254a7.38,7.38,0,0,1-6.77,4,7.23,7.23,0,0,1-5.15-1.74,6,6,0,0,1-1.86-4.62q0-6.17,7.26-7.18l6.6-.92Q254,95,249.51,95a10.83,10.83,0,0,0-7.18,2.71V94.14a13.63,13.63,0,0,1,7.48-2.06q7.76,0,7.76,8.21v14.31ZM254,103.46l-5.31.73a8.62,8.62,0,0,0-3.7,1.21,3.5,3.5,0,0,0-1.25,3.08,3.36,3.36,0,0,0,1.15,2.63,4.44,4.44,0,0,0,3.06,1,5.66,5.66,0,0,0,4.33-1.84,6.56,6.56,0,0,0,1.71-4.65v-2.19Zm28.32,9.37q0,12.12-11.6,12.12a15.58,15.58,0,0,1-7.13-1.55v-3.52a14.65,14.65,0,0,0,7.09,2.06q8.12,0,8.12-8.64V110.9h-0.09a8.9,8.9,0,0,1-14.17,1.28,11.72,11.72,0,0,1-2.5-7.87q0-5.61,2.7-8.92a9,9,0,0,1,7.38-3.31,7.17,7.17,0,0,1,6.6,3.57h0.09V92.59h3.52v20.24Zm-3.52-8.19V101.4a6.29,6.29,0,0,0-1.77-4.49A5.84,5.84,0,0,0,272.66,95a6.12,6.12,0,0,0-
 5.11,2.37,10.6,10.6,0,0,0-1.85,6.65,9.1,9.1,0,0,0,1.77,5.88,5.73,5.73,0,0,0,4.69,2.2A6.13,6.13,0,0,0,277,110,7.85,7.85,0,0,0,278.85,104.64Zm27.72-.17H291a8.23,8.23,0,0,0,2,5.67,6.81,6.81,0,0,0,5.2,2,10.81,10.81,0,0,0,6.83-2.45V113a12.77,12.77,0,0,1-7.67,2.11,9.3,9.3,0,0,1-7.33-3q-2.66-3-2.66-8.43a12,12,0,0,1,2.91-8.37,9.34,9.34,0,0,1,7.23-3.23,8.27,8.27,0,0,1,6.68,2.79q2.36,2.79,2.36,7.76v1.85Zm-3.61-3a7.18,7.18,0,0,0-1.47-4.75,5,5,0,0,0-4-1.7,5.69,5.69,0,0,0-4.23,1.78,8.09,8.09,0,0,0-2.15,4.66H303Zm7,12.31V110a10.42,10.42,0,0,0,6.34,2.13q4.64,0,4.64-3.09a2.69,2.69,0,0,0-.4-1.49,4,4,0,0,0-1.07-1.09,8.3,8.3,0,0,0-1.59-.85l-2-.78a25.19,25.19,0,0,1-2.57-1.17,7.74,7.74,0,0,1-1.85-1.33,5,5,0,0,1-1.12-1.69,6,6,0,0,1-.38-2.21,5.26,5.26,0,0,1,.71-2.74,6.29,6.29,0,0,1,1.89-2,8.82,8.82,0,0,1,2.7-1.21,12,12,0,0,1,3.13-.41,12.63,12.63,0,0,1,5.11,1v3.57A10,10,0,0,0,317.94,95a6.52,6.52,0,0,0-1.78.23,4.36,4.36,0,0,0-1.36.63,2.92,2.92,0,0,0-.88,1,2.57,2.57,0,0,0-.31,1.26,3,3,0,0,0,.31,1.44,3.16,3.1
 6,0,0,0,.91,1,6.94,6.94,0,0,0,1.46.82q0.86,0.37,2,.79a27.4,27.4,0,0,1,2.62,1.15,9,9,0,0,1,2,1.33,5.21,5.21,0,0,1,1.26,1.71,5.52,5.52,0,0,1,.44,2.3,5.42,5.42,0,0,1-.72,2.84,6.17,6.17,0,0,1-1.92,2,8.81,8.81,0,0,1-2.77,1.18,13.69,13.69,0,0,1-3.29.39A12.48,12.48,0,0,1,310,113.8ZM439.09,115L422,90.27q-0.32-.47-0.63-1a6.22,6.22,0,0,1-.5-1h-0.11q0,0.39.08,1.07t0,1.72V115H418V84.19h3.16L438,108.62q0.39,0.58.7,1.08l0.57,0.93h0.11q-0.09-.71-0.13-1.59t0-2V84.19h2.88V115h-3Zm24.28,0v-3.74h-0.09a7.35,7.35,0,0,1-6.94,4.25q-7.84,0-7.84-9.58V93h2.75v12.42q0,4,1.41,5.84a5,5,0,0,0,4.31,1.89,6,6,0,0,0,2.59-.55,5.91,5.91,0,0,0,2-1.55,7.25,7.25,0,0,0,1.32-2.4,9.61,9.61,0,0,0,.47-3.09V93h2.75v22h-2.75Zm32.32-2.13a20.24,20.24,0,0,1-10.05,2.66,15,15,0,0,1-6-1.15,13,13,0,0,1-4.53-3.2,14.11,14.11,0,0,1-2.87-4.9,18.8,18.8,0,0,1-1-6.26,19.15,19.15,0,0,1,.48-4.34,17,17,0,0,1,1.42-3.91,15.06,15.06,0,0,1,2.29-3.31,14.31,14.31,0,0,1,3.1-2.56,14.9,14.9,0,0,1,3.86-1.65,17,17,0,0,1,4.53-.58,19.51,19.51,0,0,1,8.16,1.6
 3v3.16a17.27,17.27,0,0,0-8.51-2.19,12.2,12.2,0,0,0-5.09,1,11.39,11.39,0,0,0-3.88,2.84,12.9,12.9,0,0,0-2.48,4.26,16.08,16.08,0,0,0-.9,5.34A17,17,0,0,0,475,105a11.83,11.83,0,0,0,2.27,4.18,10.36,10.36,0,0,0,3.72,2.75,12.42,12.42,0,0,0,5.11,1,13.53,13.53,0,0,0,6.79-1.63v-9.39h-7v-2.6h9.86v13.56Zm7.38-8.38a12.32,12.32,0,0,0,.54,3.63,7.69,7.69,0,0,0,1.48,2.73,6.36,6.36,0,0,0,2.35,1.71,7.89,7.89,0,0,0,3.13.59,11.19,11.19,0,0,0,7-2.6v2.71a12.81,12.81,0,0,1-7.65,2.26,10.1,10.1,0,0,1-4-.77,8.32,8.32,0,0,1-3.07-2.25,10.25,10.25,0,0,1-2-3.62,16.05,16.05,0,0,1-.69-4.9A13.51,13.51,0,0,1,501,99.4a11.29,11.29,0,0,1,2.08-3.64,9.61,9.61,0,0,1,3.16-2.41,9.17,9.17,0,0,1,4-.87,9,9,0,0,1,3.76.74,7.38,7.38,0,0,1,2.74,2.12,9.59,9.59,0,0,1,1.69,3.35,15.7,15.7,0,0,1,.58,4.43v1.38h-15.9Zm13.06-2.41a8.38,8.38,0,0,0-1.63-5.33,5.36,5.36,0,0,0-4.36-1.89,6.7,6.7,0,0,0-2.59.49,6.16,6.16,0,0,0-2.09,1.43A7.7,7.7,0,0,0,504,99.07a11.42,11.42,0,0,0-.83,3h13Zm17.07,12.65a6.82,6.82,0,0,1-3.09.71q-5.33,0-5.33-6.14V95.41h-3
 .87V93h3.87V87.46l2.75-.9V93h5.67v2.41h-5.67v13.47a5.51,5.51,0,0,0,.73,3.22,2.87,2.87,0,0,0,2.47,1,4.45,4.45,0,0,0,2.47-.77v2.43ZM598.39,115V102.32q0-7.45-5.41-7.46a6.24,6.24,0,0,0-2.66.57A6.39,6.39,0,0,0,588.2,97a7.41,7.41,0,0,0-1.4,2.4,8.68,8.68,0,0,0-.5,3V115h-2.75V93h2.75v3.82h0.09a8,8,0,0,1,7.37-4.34,6.65,6.65,0,0,1,5.5,2.34q1.89,2.34,1.89,6.77V115h-2.75Zm11.5-3.54v13.66h-2.75V93h2.75v4.21H610a8.74,8.74,0,0,1,3.28-3.51,9.55,9.55,0,0,1,8.4-.45,7.82,7.82,0,0,1,2.81,2.16,9.79,9.79,0,0,1,1.76,3.39,15.3,15.3,0,0,1,.61,4.49,17,17,0,0,1-.69,5,11.47,11.47,0,0,1-2,3.86,9,9,0,0,1-3.13,2.5,9.35,9.35,0,0,1-4.14.89,7.48,7.48,0,0,1-6.94-4.06h-0.09Zm0-5.61a7.84,7.84,0,0,0,.5,2.83A7.31,7.31,0,0,0,611.8,111a6.54,6.54,0,0,0,2.18,1.58,6.76,6.76,0,0,0,2.83.58,6.33,6.33,0,0,0,3-.7,6.52,6.52,0,0,0,2.27-2,9.63,9.63,0,0,0,1.44-3.12,15.34,15.34,0,0,0,.5-4.08,12,12,0,0,0-.47-3.49,7.92,7.92,0,0,0-1.34-2.65,5.82,5.82,0,0,0-2.11-1.68,6.42,6.42,0,0,0-2.76-.58,7.31,7.31,0,0,0-3.09.63,7,7,0,0,0-2.34,1.73,7.67
 ,7.67,0,0,0-1.48,2.57,9.39,9.39,0,0,0-.52,3.13v2.92ZM659.42,115V102.07a15.75,15.75,0,0,0-.3-3.34,5.83,5.83,0,0,0-.93-2.22,3.64,3.64,0,0,0-1.61-1.25,6.34,6.34,0,0,0-2.33-.39,4.8,4.8,0,0,0-2.28.57A6,6,0,0,0,650.09,97a7.61,7.61,0,0,0-1.27,2.35,9,9,0,0,0-.46,2.92V115h-2.75V101.79q0-6.92-5.31-6.92a4.86,4.86,0,0,0-2.28.55A5.67,5.67,0,0,0,636.19,97,7.35,7.35,0,0,0,635,99.33a10,10,0,0,0-.44,3.06V115h-2.75V93h2.75v3.57h0.09a7.37,7.37,0,0,1,6.77-4.08,6.69,6.69,0,0,1,2.19.35,6.36,6.36,0,0,1,1.85,1,6.47,6.47,0,0,1,1.41,1.51,6.83,6.83,0,0,1,.89,1.93,8.83,8.83,0,0,1,3-3.57,7.46,7.46,0,0,1,4.2-1.22q7.24,0,7.24,8.94V115h-2.75ZM717,115V84.19h8.42a10.8,10.8,0,0,1,3.45.52,7.74,7.74,0,0,1,2.62,1.45,6.28,6.28,0,0,1,1.66,2.25,7,7,0,0,1,.58,2.88,8.26,8.26,0,0,1-.37,2.49,7.43,7.43,0,0,1-1.05,2.12,7,7,0,0,1-1.69,1.65,8.44,8.44,0,0,1-2.27,1.11v0.09a8.43,8.43,0,0,1,2.81.75,7.1,7.1,0,0,1,2.17,1.57,6.86,6.86,0,0,1,1.4,2.27,8,8,0,0,1,.49,2.85,8.83,8.83,0,0,1-.71,3.58,8.18,8.18,0,0,1-2,2.79,9,9,0,0,1-3,1.82,11.25
 ,11.25,0,0,1-3.89.64H717Zm2.86-28.19V97.75h4a9.22,9.22,0,0,0,2.84-.41,6.22,6.22,0,0,0,2.17-1.18,5.19,5.19,0,0,0,1.39-1.87,6.06,6.06,0,0,0,.48-2.47q0-5-6.23-5h-4.64Zm0,13.51V112.4h5.31a7.75,7.75,0,0,0,5.25-1.6,5.7,5.7,0,0,0,1.84-4.54q0-5.93-8.06-5.93h-4.34Zm29.66,15.19a11.26,11.26,0,0,1-4.39-.82,9.38,9.38,0,0,1-3.32-2.31,10.17,10.17,0,0,1-2.11-3.58,13.88,13.88,0,0,1-.73-4.62,14.6,14.6,0,0,1,.77-4.92,10.35,10.35,0,0,1,2.2-3.68,9.41,9.41,0,0,1,3.45-2.31,12.23,12.23,0,0,1,4.51-.79,11.24,11.24,0,0,1,4.3.78,8.77,8.77,0,0,1,3.24,2.27,10.1,10.1,0,0,1,2,3.61,15.25,15.25,0,0,1,.71,4.83,14.12,14.12,0,0,1-.74,4.69,10.59,10.59,0,0,1-2.12,3.64,9.37,9.37,0,0,1-3.35,2.36A11.35,11.35,0,0,1,749.51,115.52Zm0.21-20.65a8.25,8.25,0,0,0-3.27.62,6.85,6.85,0,0,0-2.5,1.82,8.2,8.2,0,0,0-1.6,2.92,12.75,12.75,0,0,0-.56,3.92,11.58,11.58,0,0,0,.56,3.72,8.37,8.37,0,0,0,1.58,2.84,6.81,6.81,0,0,0,2.48,1.82,8.87,8.87,0,0,0,6.53,0,6.45,6.45,0,0,0,2.41-1.78,7.85,7.85,0,0,0,1.49-2.87,13.59,13.59,0,0,0,.5-3.87q0-4.45-2-6
 .8A7,7,0,0,0,749.72,94.87ZM785,115h-2.75l-4.66-16.16a12,12,0,0,1-.34-2h-0.09q0,0.32-.14.79a9.84,9.84,0,0,1-.31,1.12L771.56,115h-2.69l-6.66-22h2.94L770,110.06a9.67,9.67,0,0,1,.3,1.91h0.17q0-.39.14-0.88a10.47,10.47,0,0,1,.27-1.05l5.33-17h2.28l4.77,17.08a13.44,13.44,0,0,1,.32,1.91h0.17a3.17,3.17,0,0,1,.09-0.85q0.11-.48.28-1.06L788.94,93h2.77Zm11.39-10.51a12.3,12.3,0,0,0,.54,3.63,7.69,7.69,0,0,0,1.48,2.73,6.36,6.36,0,0,0,2.35,1.71,7.9,7.9,0,0,0,3.13.59,11.19,11.19,0,0,0,7-2.6v2.71a12.82,12.82,0,0,1-7.65,2.26,10.09,10.09,0,0,1-4-.77,8.32,8.32,0,0,1-3.07-2.25,10.23,10.23,0,0,1-2-3.62,16,16,0,0,1-.69-4.9,13.5,13.5,0,0,1,.75-4.58,11.26,11.26,0,0,1,2.08-3.64,9.58,9.58,0,0,1,3.16-2.41,9.17,9.17,0,0,1,4-.87,9,9,0,0,1,3.76.74A7.38,7.38,0,0,1,810,95.34a9.58,9.58,0,0,1,1.69,3.35,15.7,15.7,0,0,1,.58,4.43v1.38h-15.9Zm13.06-2.41a8.38,8.38,0,0,0-1.63-5.33,5.36,5.36,0,0,0-4.36-1.89,6.7,6.7,0,0,0-2.59.49,6.16,6.16,0,0,0-2.09,1.43,7.73,7.73,0,0,0-1.49,2.28,11.4,11.4,0,0,0-.83,3h13ZM828,95.81a4.11,4.11,0
 ,0,0-2.49-.71,4.27,4.27,0,0,0-1.93.42,4.89,4.89,0,0,0-1.47,1.13A6.76,6.76,0,0,0,821,98.3a11.42,11.42,0,0,0-.71,1.94,14.07,14.07,0,0,0-.39,2,17.13,17.13,0,0,0-.12,2V115h-2.73V93h2.73v4.71h0.09a9.77,9.77,0,0,1,1-2.16,6.71,6.71,0,0,1,1.36-1.61,5.71,5.71,0,0,1,1.69-1,5.42,5.42,0,0,1,1.92-.34,7.48,7.48,0,0,1,1.19.09,4.59,4.59,0,0,1,1,.26v2.88Zm73.67,17.06a20.24,20.24,0,0,1-10.05,2.66,15,15,0,0,1-6-1.15,13,13,0,0,1-4.53-3.2,14.12,14.12,0,0,1-2.87-4.9,18.8,18.8,0,0,1-1-6.26,19.15,19.15,0,0,1,.48-4.34,17,17,0,0,1,1.42-3.91,15,15,0,0,1,2.29-3.31,14.32,14.32,0,0,1,3.1-2.56,14.89,14.89,0,0,1,3.86-1.65,17,17,0,0,1,4.53-.58A19.51,19.51,0,0,1,901,85.31v3.16a17.27,17.27,0,0,0-8.51-2.19,12.2,12.2,0,0,0-5.09,1,11.4,11.4,0,0,0-3.88,2.84,12.9,12.9,0,0,0-2.48,4.26,16.05,16.05,0,0,0-.9,5.34,17,17,0,0,0,.74,5.27,11.83,11.83,0,0,0,2.27,4.18,10.36,10.36,0,0,0,3.72,2.75,12.42,12.42,0,0,0,5.11,1,13.53,13.53,0,0,0,6.79-1.63v-9.39h-7v-2.6h9.86v13.56ZM922.1,115v-3.74H922a7.35,7.35,0,0,1-6.94,4.25q-7.84,0-7.84-9
 .58V93H910v12.42q0,4,1.41,5.84a5,5,0,0,0,4.31,1.89,6,6,0,0,0,2.59-.55,5.92,5.92,0,0,0,2-1.55,7.25,7.25,0,0,0,1.32-2.4,9.59,9.59,0,0,0,.47-3.09V93h2.75v22H922.1Zm9.22,0V82.43h2.75V115h-2.75Zm12-3.54v13.66h-2.75V93h2.75v4.21h0.09a8.75,8.75,0,0,1,3.28-3.51,9.55,9.55,0,0,1,8.4-.45,7.8,7.8,0,0,1,2.81,2.16,9.78,9.78,0,0,1,1.76,3.39,15.3,15.3,0,0,1,.61,4.49,17,17,0,0,1-.69,5,11.49,11.49,0,0,1-2,3.86,9,9,0,0,1-3.13,2.5,9.35,9.35,0,0,1-4.13.89,7.48,7.48,0,0,1-6.94-4.06H943.3Zm0-5.61a7.86,7.86,0,0,0,.5,2.83,7.34,7.34,0,0,0,1.41,2.32,6.55,6.55,0,0,0,2.18,1.58,6.76,6.76,0,0,0,2.83.58,6.33,6.33,0,0,0,3-.7,6.53,6.53,0,0,0,2.27-2,9.61,9.61,0,0,0,1.44-3.12,15.3,15.3,0,0,0,.51-4.08,12,12,0,0,0-.47-3.49,7.94,7.94,0,0,0-1.34-2.65,5.81,5.81,0,0,0-2.11-1.68,6.42,6.42,0,0,0-2.76-.58,7.31,7.31,0,0,0-3.09.63,7,7,0,0,0-2.34,1.73,7.66,7.66,0,0,0-1.48,2.57,9.39,9.39,0,0,0-.52,3.13v2.92ZM358.5,55h-1v90h1V55Z"/></svg>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner4.svg
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner4.svg b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner4.svg
new file mode 100644
index 0000000..38b3d7c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/images/banner4.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1140 360" enable-background="new 0 0 1140 360"><path fill="#1D4380" d="M0 0h1140v360h-1140v-360z"/><path fill="#fff" d="M191.061 117h-3.751v-21.607c0-1.707.104-3.796.314-6.267h-.09c-.359 1.453-.682 2.493-.966 3.122l-11.005 24.752h-1.842l-10.983-24.572c-.314-.719-.637-1.819-.966-3.302h-.09c.12 1.288.18 3.392.18 6.312v21.562h-3.639v-32.209h4.986l9.883 22.461c.764 1.722 1.258 3.01 1.482 3.863h.135c.644-1.767 1.16-3.084 1.55-3.953l10.085-22.371h4.717v32.209zm9.032-28.84c-.659 0-1.221-.225-1.685-.674-.464-.449-.696-1.018-.696-1.707 0-.688.232-1.261.696-1.718.464-.457 1.025-.685 1.685-.685.674 0 1.247.229 1.718.685.472.457.708 1.03.708 1.718 0 .659-.236 1.221-.708 1.685-.472.464-1.044.696-1.718.696zm1.797 28.84h-3.684v-23h3.684v23zm22.307-1.056c-1.767 1.063-3.863 1.595-6.289 1.595-3.279 0-5.926-1.067-7.94-3.201-2.014-2.134-3.021-4.9-3.021-8.299 0-3.788 1.085-6.832 3.257-9.13 2.171-2.298 5.068-3.448 8.692-3.448 2.021 0 3.803.375 5.346 1.
 123v3.773c-1.707-1.198-3.534-1.797-5.48-1.797-2.351 0-4.279.842-5.784 2.527s-2.257 3.897-2.257 6.637c0 2.695.708 4.822 2.123 6.379 1.415 1.558 3.313 2.336 5.694 2.336 2.006 0 3.893-.666 5.66-1.999v3.504zm16.736-18.215c-.644-.494-1.572-.741-2.785-.741-1.572 0-2.886.741-3.942 2.224s-1.583 3.504-1.583 6.064v11.724h-3.684v-23h3.684v4.739h.09c.524-1.617 1.325-2.878 2.403-3.785 1.078-.906 2.283-1.359 3.616-1.359.958 0 1.692.105 2.201.314v3.82zm12.783 19.81c-3.399 0-6.113-1.074-8.142-3.223-2.029-2.148-3.043-4.998-3.043-8.546 0-3.863 1.056-6.88 3.167-9.052 2.111-2.171 4.964-3.257 8.558-3.257 3.429 0 6.105 1.056 8.03 3.167 1.924 2.111 2.886 5.039 2.886 8.782 0 3.669-1.037 6.607-3.111 8.816-2.075 2.209-4.856 3.313-8.345 3.313zm.27-20.978c-2.366 0-4.238.805-5.615 2.415-1.378 1.61-2.066 3.83-2.066 6.66 0 2.726.696 4.874 2.089 6.446s3.257 2.358 5.593 2.358c2.381 0 4.211-.771 5.492-2.313 1.28-1.542 1.92-3.736 1.92-6.581 0-2.875-.64-5.091-1.92-6.648-1.282-1.559-3.112-2.337-5.493-2.337zm14.849 19.6
 08v-3.953c2.006 1.482 4.215 2.224 6.626 2.224 3.234 0 4.852-1.078 4.852-3.234 0-.614-.139-1.134-.416-1.561-.277-.427-.651-.805-1.123-1.134-.472-.329-1.026-.625-1.662-.887-.637-.262-1.322-.535-2.055-.82-1.019-.404-1.913-.812-2.684-1.224-.771-.412-1.415-.876-1.932-1.393s-.906-1.104-1.168-1.763c-.262-.659-.393-1.43-.393-2.313 0-1.078.247-2.033.741-2.864s1.153-1.527 1.977-2.089c.823-.562 1.763-.984 2.819-1.269 1.056-.284 2.145-.427 3.268-.427 1.991 0 3.773.345 5.346 1.033v3.729c-1.692-1.108-3.639-1.662-5.84-1.662-.689 0-1.311.079-1.864.236-.554.157-1.03.378-1.426.663-.397.285-.704.625-.921 1.022-.217.397-.326.835-.326 1.314 0 .599.108 1.101.326 1.505.217.404.535.764.955 1.078.419.314.928.599 1.527.854.599.255 1.28.532 2.044.831 1.018.39 1.932.79 2.74 1.202.809.412 1.497.876 2.066 1.393.569.517 1.007 1.112 1.314 1.786.307.674.46 1.475.46 2.403 0 1.138-.251 2.126-.752 2.965-.502.839-1.172 1.535-2.01 2.089-.839.554-1.805.966-2.897 1.235-1.093.27-2.239.404-3.437.404-2.366-.003-4.418-.46-6.1
 55-1.373zm29.697 1.37c-3.399 0-6.113-1.074-8.142-3.223-2.029-2.148-3.043-4.998-3.043-8.546 0-3.863 1.056-6.88 3.167-9.052 2.111-2.171 4.964-3.257 8.558-3.257 3.429 0 6.105 1.056 8.03 3.167 1.924 2.111 2.886 5.039 2.886 8.782 0 3.669-1.037 6.607-3.111 8.816-2.075 2.209-4.856 3.313-8.345 3.313zm.27-20.978c-2.366 0-4.238.805-5.615 2.415-1.378 1.61-2.066 3.83-2.066 6.66 0 2.726.696 4.874 2.089 6.446s3.257 2.358 5.593 2.358c2.381 0 4.211-.771 5.492-2.313 1.28-1.542 1.92-3.736 1.92-6.581 0-2.875-.64-5.091-1.92-6.648-1.282-1.559-3.112-2.337-5.493-2.337zm27.607-10.377c-.719-.404-1.535-.606-2.448-.606-2.576 0-3.863 1.625-3.863 4.874v3.548h5.391v3.145h-5.391v19.855h-3.661v-19.855h-3.931v-3.145h3.931v-3.729c0-2.411.696-4.316 2.089-5.716 1.393-1.4 3.129-2.1 5.211-2.1 1.123 0 2.014.135 2.673.404v3.325zm12.873 30.591c-.869.479-2.014.719-3.437.719-4.028 0-6.042-2.246-6.042-6.738v-13.611h-3.953v-3.145h3.953v-5.615l3.684-1.19v6.805h5.795v3.145h-5.795v12.96c0 1.542.262 2.643.786 3.302.524.659 1.393.9
 88 2.605.988.928 0 1.729-.254 2.403-.764v3.144zm41.29.225h-4.178l-3.414-9.029h-13.656l-3.212 9.029h-4.2l12.354-32.209h3.908l12.398 32.209zm-8.827-12.421l-5.054-13.724c-.165-.449-.33-1.168-.494-2.156h-.09c-.15.914-.322 1.632-.517 2.156l-5.009 13.724h11.164zm28.281-9.523l-13.611 18.8h13.477v3.144h-18.89v-1.146l13.611-18.71h-12.331v-3.144h17.744v1.056zm22.531 21.944h-3.684v-3.639h-.09c-1.527 2.785-3.894 4.178-7.098 4.178-5.48 0-8.221-3.264-8.221-9.793v-13.746h3.661v13.162c0 4.852 1.856 7.277 5.57 7.277 1.797 0 3.275-.663 4.436-1.988 1.16-1.325 1.741-3.058 1.741-5.2v-13.251h3.684v23zm18.601-19.271c-.644-.494-1.572-.741-2.785-.741-1.572 0-2.886.741-3.942 2.224s-1.583 3.504-1.583 6.064v11.724h-3.684v-23h3.684v4.739h.09c.524-1.617 1.325-2.878 2.403-3.785 1.078-.906 2.283-1.359 3.616-1.359.958 0 1.692.105 2.201.314v3.82zm21.655 8.692h-16.239c.06 2.561.749 4.537 2.066 5.93 1.317 1.393 3.129 2.089 5.436 2.089 2.59 0 4.971-.854 7.143-2.561v3.459c-2.021 1.468-4.694 2.201-8.019 2.201-3.25 0-5.80
 3-1.044-7.659-3.133-1.857-2.089-2.785-5.027-2.785-8.816 0-3.579 1.014-6.495 3.043-8.749 2.029-2.253 4.548-3.38 7.558-3.38s5.338.974 6.985 2.92c1.647 1.947 2.471 4.649 2.471 8.108v1.932zm-3.773-3.122c-.015-2.126-.528-3.781-1.539-4.964-1.011-1.183-2.415-1.774-4.211-1.774-1.737 0-3.212.622-4.425 1.864-1.213 1.243-1.962 2.868-2.246 4.874h12.421zm34.46-48.299h-1v90h1v-90z"/><path fill="#59B4D9" d="M597.026 128.479c-6.343 4.851-13.817 7.213-21.238 7.213-10.53 0-20.943-4.727-27.824-13.727-11.757-15.35-8.855-37.302 6.522-49.064 6.342-4.88 13.824-7.209 21.235-7.209 10.53 0 20.945 4.727 27.824 13.735 11.76 15.345 8.83 37.302-6.519 49.052"/><path fill="#fff" d="M590.595 106.829c2.543 3.316 7.262 3.915 10.56 1.406.172-.132.305-.291.462-.433 3.373 2.376 5.716 3.945 7.036 4.844.391-1.012.661-1.984.938-2.999-1.395-1.038-3.281-2.49-6.007-4.699.895-2.352.612-5.097-1.022-7.241-2.337-3.025-6.478-3.793-9.712-1.928-3.565-3.198-7.482-6.864-11.613-10.968 12.834-6.902 21.951-5.891 21.951-5.891-1.522-1.941-
 3.228-3.641-5.049-5.177-5.412-.836-13.819-.742-23.425 4.367l-.003-.004h-.001c-3.201-3.351-6.459-6.943-9.778-10.799-1.588.508-3.139 1.137-4.638 1.886 2.449 4.008 5.744 8.05 9.457 11.993l.024.024c-3.096 2.165-6.544 5.059-9.724 8.423-.406.433-.797.868-1.179 1.304-1.9-.398-3.898-.281-5.765.395-3.17-6.84-2.915-12.335-2.414-15.168-1.376 1.442-2.662 2.959-3.77 4.575-.828 3.382-1.063 8.259 1.379 14.136-2.827 3.7-2.96 8.946-.007 12.817.246.321.51.619.783.903-1.29 4.393-1.867 8.63-2.044 12.268l.661 1.255c1.679 2.154 3.788 3.968 5.825 5.612-.252-3.851.02-9.53 2.4-15.924 1.643.125 3.313-.134 4.877-.793.896.788 1.834 1.585 2.836 2.396 3.435 2.719 6.861 4.835 10.201 6.502-.174 1.699.252 3.464 1.355 4.926 2.359 3.047 6.728 3.616 9.778 1.287.634-.486 1.136-1.073 1.552-1.703 5.446 1.213 10.204 1.427 13.731 1.427.541 0 3.048-3.411 4.485-5.526-2.148.449-8.518 1.325-17.223-1.176-.21-.977-.612-1.927-1.257-2.773-2.211-2.899-6.254-3.526-9.267-1.587-3.026-1.641-6.195-3.698-9.463-6.287-.66-.522-1.292-1.043-
 1.903-1.566 1.997-3.146 2.21-7.179.445-10.572.401-.4.794-.802 1.22-1.2 3.236-3.023 6.28-5.443 9.128-7.385l-.33-.326.335.318-.003.001c4.37 4.041 9.004 7.871 13.392 11.293-1.162 2.461-.98 5.459.786 7.767z"/><path fill="#55ADD3" d="M702.836 135.691c-1.725 0-3.349-.672-4.565-1.893l-28.544-28.543c-1.203-1.203-1.891-2.864-1.891-4.565 0-1.7.689-3.363 1.891-4.564l28.544-28.543c1.219-1.221 2.841-1.893 4.565-1.893 1.723 0 3.346.672 4.565 1.893l28.54 28.543c1.222 1.215 1.893 2.838 1.893 4.564s-.671 3.349-1.894 4.568l-28.538 28.54c-1.219 1.221-2.843 1.893-4.566 1.893"/><path fill="#fff" d="M721.894 95.221c-3.024 0-5.474 2.45-5.474 5.472 0 1.109.335 2.138.903 3l-10.841 10.841c-.288-.202-.598-.37-.918-.522v-27.658c1.634-.946 2.745-2.694 2.745-4.718 0-3.023-2.45-5.472-5.474-5.472-3.021 0-5.471 2.45-5.471 5.472 0 2.024 1.112 3.772 2.744 4.718v27.658c-.307.146-.608.302-.885.494l-10.854-10.854c.552-.854.879-1.866.879-2.958 0-3.023-2.45-5.472-5.471-5.472-3.024 0-5.474 2.45-5.474 5.472 0 3.023 2.45 5.4
 72 5.474 5.472.627 0 1.221-.127 1.784-.322l11.41 11.41c-.328.767-.51 1.61-.51 2.496 0 3.518 2.853 6.371 6.371 6.371 3.52 0 6.371-2.853 6.371-6.371 0-.869-.176-1.697-.491-2.451l11.442-11.441c.549.185 1.126.308 1.737.308 3.021 0 5.471-2.45 5.471-5.472 0-3.023-2.448-5.473-5.468-5.473z"/><rect x="711.244" y="77.211" transform="matrix(.707 -.707 .707 .707 144.067 531.108)" opacity=".5" fill="#fff" enable-background="new" width="3.532" height="28.946"/><rect x="678.208" y="89.936" transform="matrix(.707 -.707 .707 .707 138.038 516.659)" opacity=".5" fill="#fff" enable-background="new" width="28.947" height="3.533"/><path fill="#B8D432" d="M706.566 119.75c0 2.094-1.7 3.793-3.794 3.793-2.096 0-3.793-1.698-3.793-3.793s1.697-3.793 3.793-3.793c2.093 0 3.794 1.699 3.794 3.793"/><path fill="#B8D432" d="M705.878 81.636c0 1.681-1.362 3.044-3.044 3.044-1.681 0-3.044-1.362-3.044-3.044s1.362-3.044 3.044-3.044 3.044 1.362 3.044 3.044"/><path fill="#B8D432" d="M686.823 100.692c0 1.681-1.365 3.044-3.044
  3.044-1.681 0-3.044-1.362-3.044-3.044s1.362-3.044 3.044-3.044c1.679.001 3.044 1.363 3.044 3.044"/><path fill="#B8D432" d="M724.937 100.692c0 1.681-1.365 3.044-3.045 3.044s-3.044-1.362-3.044-3.044 1.364-3.044 3.044-3.044c1.68.001 3.045 1.363 3.045 3.044"/><path opacity=".1" fill="#69c" enable-background="new" d="M707.401 67.584c-1.219-1.221-2.841-1.893-4.565-1.893-1.723 0-3.345.672-4.564 1.893l-28.544 28.543c-1.204 1.201-1.893 2.864-1.893 4.564 0 1.701.689 3.364 1.893 4.565l16.16 16.161 30.4-44.948-8.887-8.885z"/><path fill="#3999C6" d="M803.512 75.254v50.873c0 5.282 11.823 9.564 26.405 9.564v-60.437h-26.405z"/><path fill="#59B4D9" d="M829.555 135.69h.362c14.582 0 26.405-4.28 26.405-9.563v-50.873h-26.767v60.436z"/><path fill="#fff" d="M856.322 75.254c0 5.282-11.823 9.563-26.405 9.563s-26.405-4.281-26.405-9.563 11.823-9.563 26.405-9.563 26.405 4.282 26.405 9.563"/><path fill="#7FBA00" d="M850.924 74.703c0 3.487-9.405 6.31-21.006 6.31s-21.008-2.823-21.008-6.31c0-3.485 9.406-6.31 21.00
 8-6.31 11.601 0 21.006 2.825 21.006 6.31"/><path fill="#B8D432" d="M846.523 78.559c2.75-1.066 4.402-2.402 4.402-3.853 0-3.487-9.405-6.311-21.008-6.311-11.601 0-21.007 2.825-21.007 6.311 0 1.451 1.653 2.787 4.402 3.853 3.84-1.491 9.842-2.453 16.604-2.453 6.765.001 12.764.963 16.607 2.453"/><path fill="#fff" d="M846.983 116.504c-1.413 1.178-3.328 1.769-5.815 1.769h-8.298v-21.643h7.871c2.478 0 4.377.452 5.683 1.389 1.223.879 1.836 2.109 1.836 3.68 0 1.252-.447 2.317-1.358 3.254-.776.775-1.709 1.31-2.858 1.624v.051c1.543.19 2.802.778 3.74 1.765.878.937 1.33 2.086 1.33 3.415.005 1.979-.716 3.529-2.131 4.696m-20.223-1.275c-2.077 2.031-4.88 3.044-8.378 3.044h-7.661v-21.643h7.661c7.685 0 11.528 3.498 11.528 10.538 0 3.365-1.039 6.059-3.15 8.061"/><path fill="#3999C6" d="M817.982 100.58h-2.401v13.741h2.429c2.134 0 3.788-.668 5.012-1.948 1.172-1.281 1.765-2.988 1.765-5.148 0-2.027-.593-3.625-1.738-4.808-1.201-1.223-2.882-1.837-5.067-1.837"/><path fill="#59B4D9" d="M842.233 104.613c.586-.51.87
 9-1.178.879-2.006 0-1.605-1.172-2.403-3.55-2.403h-1.834v5.128h2.16c.987 0 1.787-.247 2.345-.719"/><path fill="#59B4D9" d="M843.035 109.703c-.642-.478-1.516-.747-2.644-.747h-2.667v5.708h2.641c1.123 0 2.027-.266 2.695-.8.613-.535.931-1.224.931-2.134.006-.854-.314-1.548-.956-2.027"/><path fill="#A0A1A2" d="M922 127.851c0 1.4.98 2.66 2.66 2.66h64.68c1.4 0 2.66-.98 2.66-2.66v-46.34h-70v46.34z"/><path fill="#7A7A7A" d="M989.34 70.871h-64.68c-1.68 0-2.66 1.26-2.66 2.66v7.98h70v-7.98c0-1.4-.98-2.66-2.66-2.66"/><rect x="948.32" y="86.131" fill="#fff" width="17.64" height="10.64"/><rect x="948.32" y="100.551" fill="#FCD116" width="17.64" height="10.64"/><rect x="969.32" y="100.551" fill="#FCD116" width="17.64" height="10.64"/><rect x="969.32" y="86.131" fill="#fff" width="17.64" height="10.64"/><rect x="927.32" y="86.131" fill="#fff" width="17.64" height="10.64"/><rect x="927.32" y="100.551" fill="#fff" width="17.64" height="10.64"/><rect x="927.32" y="114.831" fill="#FCD116" width="17.64" he
 ight="10.64"/><rect x="948.32" y="114.831" fill="#FCD116" width="17.64" height="10.64"/><rect x="969.32" y="114.831" fill="#FCD116" width="17.64" height="10.64"/><path opacity=".2" fill="#fff" enable-background="new" d="M924.66 70.871c-1.26 0-2.66 1.26-2.66 2.66v54.32c0 1.4 1.4 2.66 2.66 2.66h2.94l55.44-59.64h-58.38z"/></svg>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.js
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.js b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.js
new file mode 100644
index 0000000..e069226
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.js
@@ -0,0 +1 @@
+// Write your Javascript code.

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.min.js
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.min.js b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/js/site.min.js
new file mode 100644
index 0000000..e69de29


[07/10] logging-log4net git commit: Fixed worker thread logic and optimized code.

Posted by dp...@apache.org.
Fixed worker thread logic and optimized code.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/a847990c
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/a847990c
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/a847990c

Branch: refs/heads/pr/old/40
Commit: a847990ce9a71a4168cddaca8a47b23f5e7c77d2
Parents: 897ef68
Author: Harry Martyrossian <HM...@users.noreply.github.com>
Authored: Sun Mar 26 22:25:56 2017 -0700
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:37:28 2017 +0200

----------------------------------------------------------------------
 src/Util/ParallelIAppender.cs | 78 +++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/a847990c/src/Util/ParallelIAppender.cs
----------------------------------------------------------------------
diff --git a/src/Util/ParallelIAppender.cs b/src/Util/ParallelIAppender.cs
index 81b3860..e43ef4f 100644
--- a/src/Util/ParallelIAppender.cs
+++ b/src/Util/ParallelIAppender.cs
@@ -1,4 +1,4 @@
-#region Apache License
+#region Apache License
 //
 // Licensed to the Apache Software Foundation (ASF) under one or more 
 // contributor license agreements. See the NOTICE file distributed with
@@ -19,15 +19,15 @@
 
 #if (NET_4_5 && PARALLEL_APPENDERS)
 
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using log4net.Appender;
-using log4net.Core;
-
 namespace log4net.Util
 {
+	using System;
+	using System.Collections.Generic;
+	using System.Threading;
+
+	using log4net.Appender;
+	using log4net.Core;
+
 	/// <summary>
 	/// This class allows AppenderAttachedImpl class to call appenders in "parallel".
 	/// </summary>
@@ -43,14 +43,20 @@ namespace log4net.Util
 	public class ParallelIAppender : IAppender
 	{
 		private static readonly Type declaringType = typeof(ParallelIAppender);
+
 		private IAppender appender;
+
 		private object synchObject = new object();
+		private AutoResetEvent synchEvent = new AutoResetEvent(false);
 		private PulseCode pulseCode = PulseCode.NotSignaled;
+
 		private Queue<LoggingEvent> events = new Queue<LoggingEvent>();
 		private LoggingEvent[] arrayOfEvents;
-		private Task appenderTask;
+
+		private Thread appenderThread;
 
 		#region Public Instance Constructors
+
 		/// <summary>
 		/// Constructor
 		/// </summary>
@@ -59,22 +65,29 @@ namespace log4net.Util
 		/// Initializes a new instance of the <see cref="ParallelIAppender"/> class.
 		/// </para>
 		/// </remarks>
+
 		public ParallelIAppender(IAppender appender)
 		{
 			this.appender = appender;
-			this.appenderTask = Task.Run(() => this.Append());
+
+			this.appenderThread = new Thread(this.Append);
+			this.appenderThread.IsBackground = false;
+			this.appenderThread.Name = string.Format("{0}-{1}", appender.Name, Guid.NewGuid().ToString("N"));
+
+			this.appenderThread.Start();
 		}
+
 		#endregion Public Instance Constructors
 
 		[Flags]
 		internal enum PulseCode : int
 		{
-			NotSignaled,
-			QueueIsNotEmpty,
+			NotSignaled = 0,
 			ExitThread
 		}
 
 		#region Override implementation of Object
+
 		/// <summary>
 		/// Determines whether two <see cref="ParallelIAppender" /> instances 
 		/// are equal.
@@ -111,6 +124,7 @@ namespace log4net.Util
 			{
 				return false;
 			}
+
 			return this.appender.Equals(obj);
 		}
 
@@ -131,15 +145,18 @@ namespace log4net.Util
 		{
 			return this.appender.GetHashCode();
 		}
+
 		#endregion Override implementation of Object
 
 		#region Implementation of IAppender
+
 		string IAppender.Name
 		{
 			get
 			{
 				return this.appender.Name;
 			}
+
 			set
 			{
 				this.appender.Name = value;
@@ -151,9 +168,13 @@ namespace log4net.Util
 			lock (this.synchObject)
 			{
 				this.pulseCode |= PulseCode.ExitThread;
-				Monitor.Pulse(this.synchObject);
+
+				// This call will put Append() thread to the scheduling state:
+				this.synchEvent.Set();
 			}
-			this.appenderTask.Wait();
+
+			this.appenderThread.Join();
+
 			this.appender.Close();
 		}
 
@@ -162,34 +183,38 @@ namespace log4net.Util
 			lock (this.synchObject)
 			{
 				this.events.Enqueue(loggingEvent);
-				this.pulseCode |= PulseCode.QueueIsNotEmpty;
-				Monitor.Pulse(this.synchObject);
+
+				// This call will put Append() thread to the scheduling state:
+				this.synchEvent.Set();
 			}
 		}
+
 		#endregion Implementation of IAppender
 
 		private void Append()
 		{
+			// Have to keep this thread running till log4net shutdown:
 			bool keepRunning = true;
+
 			do
 			{
+				// Have to wait for the data to be queued by log4net:
+				this.synchEvent.WaitOne();
+
 				lock (this.synchObject)
 				{
-					if (this.pulseCode == PulseCode.NotSignaled)
-					{
-						Monitor.Wait(this.synchObject);
-					}
-					if ((this.pulseCode & PulseCode.QueueIsNotEmpty) == PulseCode.QueueIsNotEmpty)
-					{
-						this.pulseCode ^= PulseCode.QueueIsNotEmpty;
-					}
+					this.CopyEvents();
+
 					if ((this.pulseCode & PulseCode.ExitThread) == PulseCode.ExitThread)
 					{
-						this.pulseCode ^= PulseCode.ExitThread;
+						// Setting keepRunning to <false> will exit the thread function:
 						keepRunning = false;
+
+						// Clean up:
+						this.pulseCode ^= PulseCode.ExitThread;
 					}
-					this.CopyEvents();
 				}
+
 				this.CallDoAppend();
 			}
 			while (keepRunning);
@@ -211,4 +236,5 @@ namespace log4net.Util
 		}
 	}
 }
+
 #endif


[03/10] logging-log4net git commit: Add test web app for asp extension

Posted by dp...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/RemoveLoginViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/RemoveLoginViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/RemoveLoginViewModel.cs
new file mode 100644
index 0000000..394df34
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/RemoveLoginViewModel.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class RemoveLoginViewModel
+    {
+        public string LoginProvider { get; set; }
+        public string ProviderKey { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/SetPasswordViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/SetPasswordViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/SetPasswordViewModel.cs
new file mode 100644
index 0000000..76c1b4b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/SetPasswordViewModel.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class SetPasswordViewModel
+    {
+        [Required]
+        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+        [DataType(DataType.Password)]
+        [Display(Name = "New password")]
+        public string NewPassword { get; set; }
+
+        [DataType(DataType.Password)]
+        [Display(Name = "Confirm new password")]
+        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
+        public string ConfirmPassword { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
new file mode 100644
index 0000000..3c8c08c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class VerifyPhoneNumberViewModel
+    {
+        [Required]
+        public string Code { get; set; }
+
+        [Required]
+        [Phone]
+        [Display(Name = "Phone number")]
+        public string PhoneNumber { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Program.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Program.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Program.cs
new file mode 100644
index 0000000..74e9753
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Program.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+
+namespace WebApplication
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            var host = new WebHostBuilder()
+                .UseKestrel()
+                .UseContentRoot(Directory.GetCurrentDirectory())
+                .UseIISIntegration()
+                .UseStartup<Startup>()
+                .Build();
+
+            host.Run();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/README.md
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/README.md b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/README.md
new file mode 100644
index 0000000..d8ba0b3
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/README.md
@@ -0,0 +1,39 @@
+# Welcome to ASP.NET Core
+
+We've made some big updates in this release, so it’s **important** that you spend a few minutes to learn what’s new.
+
+You've created a new ASP.NET Core project. [Learn what's new](https://go.microsoft.com/fwlink/?LinkId=518016)
+
+## This application consists of:
+
+*   Sample pages using ASP.NET Core MVC
+*   [Gulp](https://go.microsoft.com/fwlink/?LinkId=518007) and [Bower](https://go.microsoft.com/fwlink/?LinkId=518004) for managing client-side libraries
+*   Theming using [Bootstrap](https://go.microsoft.com/fwlink/?LinkID=398939)
+
+## How to
+
+*   [Add a Controller and View](https://go.microsoft.com/fwlink/?LinkID=398600)
+*   [Add an appsetting in config and access it in app.](https://go.microsoft.com/fwlink/?LinkID=699562)
+*   [Manage User Secrets using Secret Manager.](https://go.microsoft.com/fwlink/?LinkId=699315)
+*   [Use logging to log a message.](https://go.microsoft.com/fwlink/?LinkId=699316)
+*   [Add packages using NuGet.](https://go.microsoft.com/fwlink/?LinkId=699317)
+*   [Add client packages using Bower.](https://go.microsoft.com/fwlink/?LinkId=699318)
+*   [Target development, staging or production environment.](https://go.microsoft.com/fwlink/?LinkId=699319)
+
+## Overview
+
+*   [Conceptual overview of what is ASP.NET Core](https://go.microsoft.com/fwlink/?LinkId=518008)
+*   [Fundamentals of ASP.NET Core such as Startup and middleware.](https://go.microsoft.com/fwlink/?LinkId=699320)
+*   [Working with Data](https://go.microsoft.com/fwlink/?LinkId=398602)
+*   [Security](https://go.microsoft.com/fwlink/?LinkId=398603)
+*   [Client side development](https://go.microsoft.com/fwlink/?LinkID=699321)
+*   [Develop on different platforms](https://go.microsoft.com/fwlink/?LinkID=699322)
+*   [Read more on the documentation site](https://go.microsoft.com/fwlink/?LinkID=699323)
+
+## Run & Deploy
+
+*   [Run your app](https://go.microsoft.com/fwlink/?LinkID=517851)
+*   [Run tools such as EF migrations and more](https://go.microsoft.com/fwlink/?LinkID=517853)
+*   [Publish to Microsoft Azure Web Apps](https://go.microsoft.com/fwlink/?LinkID=398609)
+
+We would love to hear your [feedback](https://go.microsoft.com/fwlink/?LinkId=518015)

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/IEmailSender.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/IEmailSender.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/IEmailSender.cs
new file mode 100644
index 0000000..08fb35b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/IEmailSender.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Services
+{
+    public interface IEmailSender
+    {
+        Task SendEmailAsync(string email, string subject, string message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/ISmsSender.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/ISmsSender.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/ISmsSender.cs
new file mode 100644
index 0000000..8e57a23
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/ISmsSender.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Services
+{
+    public interface ISmsSender
+    {
+        Task SendSmsAsync(string number, string message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/MessageServices.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/MessageServices.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/MessageServices.cs
new file mode 100644
index 0000000..de54bfc
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Services/MessageServices.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Services
+{
+    // This class is used by the application to send Email and SMS
+    // when you turn on two-factor authentication in ASP.NET Identity.
+    // For more details see this link https://go.microsoft.com/fwlink/?LinkID=532713
+    public class AuthMessageSender : IEmailSender, ISmsSender
+    {
+        public Task SendEmailAsync(string email, string subject, string message)
+        {
+            // Plug in your email service here to send an email.
+            return Task.FromResult(0);
+        }
+
+        public Task SendSmsAsync(string number, string message)
+        {
+            // Plug in your SMS service here to send a text message.
+            return Task.FromResult(0);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Settings/logconfig.xml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Settings/logconfig.xml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Settings/logconfig.xml
new file mode 100644
index 0000000..cc1a4b6
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Settings/logconfig.xml
@@ -0,0 +1,6 @@
+<log4net>
+    <!-- Set root logger level to DEBUG and its only appender to A1 -->
+    <root>
+        <level value="DEBUG" />
+    </root>
+</log4net>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Startup.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Startup.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Startup.cs
new file mode 100644
index 0000000..10bdb86
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Startup.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using log4net.Extensions.Logging;
+using WebApplication.Data;
+using WebApplication.Models;
+using WebApplication.Services;
+
+namespace WebApplication
+{
+    public class Startup
+    {
+        public Startup(IHostingEnvironment env)
+        {
+            var builder = new ConfigurationBuilder()
+                .SetBasePath(env.ContentRootPath)
+                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
+                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
+
+            if (env.IsDevelopment())
+            {
+                // For more details on using the user secret store see https://go.microsoft.com/fwlink/?LinkID=532709
+                builder.AddUserSecrets();
+            }
+
+            builder.AddEnvironmentVariables();
+            Configuration = builder.Build();
+        }
+
+        public IConfigurationRoot Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            // Add framework services.
+            services.AddDbContext<ApplicationDbContext>(options =>
+                options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
+
+            services.AddIdentity<ApplicationUser, IdentityRole>()
+                .AddEntityFrameworkStores<ApplicationDbContext>()
+                .AddDefaultTokenProviders();
+
+            services.AddMvc();
+
+            // Add application services.
+            services.AddTransient<IEmailSender, AuthMessageSender>();
+            services.AddTransient<ISmsSender, AuthMessageSender>();
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+        {
+            env.ConfigureLog4Net("Settings/logconfig.xml", this.GetType());
+            loggerFactory.AddLog4Net(this.GetType());
+
+            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
+            loggerFactory.AddDebug();
+
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+                app.UseDatabaseErrorPage();
+                app.UseBrowserLink();
+            }
+            else
+            {
+                app.UseExceptionHandler("/Home/Error");
+            }
+
+            app.UseStaticFiles();
+
+            app.UseIdentity();
+
+            // Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
+
+            app.UseMvc(routes =>
+            {
+                routes.MapRoute(
+                    name: "default",
+                    template: "{controller=Home}/{action=Index}/{id?}");
+            });
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ConfirmEmail.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ConfirmEmail.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ConfirmEmail.cshtml
new file mode 100644
index 0000000..8e8088d
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ConfirmEmail.cshtml
@@ -0,0 +1,10 @@
+@{
+    ViewData["Title"] = "Confirm Email";
+}
+
+<h2>@ViewData["Title"].</h2>
+<div>
+    <p>
+        Thank you for confirming your email. Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
+    </p>
+</div>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginConfirmation.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginConfirmation.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginConfirmation.cshtml
new file mode 100644
index 0000000..eb3612b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginConfirmation.cshtml
@@ -0,0 +1,35 @@
+@model ExternalLoginConfirmationViewModel
+@{
+    ViewData["Title"] = "Register";
+}
+
+<h2>@ViewData["Title"].</h2>
+<h3>Associate your @ViewData["LoginProvider"] account.</h3>
+
+<form asp-controller="Account" asp-action="ExternalLoginConfirmation" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+    <h4>Association Form</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+
+    <p class="text-info">
+        You've successfully authenticated with <strong>@ViewData["LoginProvider"]</strong>.
+        Please enter an email address for this site below and click the Register button to finish
+        logging in.
+    </p>
+    <div class="form-group">
+        <label asp-for="Email" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Email" class="form-control" />
+            <span asp-validation-for="Email" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Register</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginFailure.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginFailure.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginFailure.cshtml
new file mode 100644
index 0000000..2509746
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ExternalLoginFailure.cshtml
@@ -0,0 +1,8 @@
+@{
+    ViewData["Title"] = "Login Failure";
+}
+
+<header>
+    <h2>@ViewData["Title"].</h2>
+    <p class="text-danger">Unsuccessful login with service.</p>
+</header>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPassword.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPassword.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPassword.cshtml
new file mode 100644
index 0000000..9d74802
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPassword.cshtml
@@ -0,0 +1,31 @@
+@model ForgotPasswordViewModel
+@{
+    ViewData["Title"] = "Forgot your password?";
+}
+
+<h2>@ViewData["Title"]</h2>
+<p>
+    For more information on how to enable reset password please see this <a href="https://go.microsoft.com/fwlink/?LinkID=532713">article</a>.
+</p>
+
+@*<form asp-controller="Account" asp-action="ForgotPassword" method="post" class="form-horizontal">
+    <h4>Enter your email.</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="Email" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Email" class="form-control" />
+            <span asp-validation-for="Email" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Submit</button>
+        </div>
+    </div>
+</form>*@
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPasswordConfirmation.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPasswordConfirmation.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPasswordConfirmation.cshtml
new file mode 100644
index 0000000..4877fc8
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ForgotPasswordConfirmation.cshtml
@@ -0,0 +1,8 @@
+@{
+    ViewData["Title"] = "Forgot Password Confirmation";
+}
+
+<h2>@ViewData["Title"].</h2>
+<p>
+    Please check your email to reset your password.
+</p>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Lockout.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Lockout.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Lockout.cshtml
new file mode 100644
index 0000000..34ac56f
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Lockout.cshtml
@@ -0,0 +1,8 @@
+@{
+    ViewData["Title"] = "Locked out";
+}
+
+<header>
+    <h1 class="text-danger">Locked out.</h1>
+    <p class="text-danger">This account has been locked out, please try again later.</p>
+</header>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Login.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Login.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Login.cshtml
new file mode 100644
index 0000000..95430a1
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Login.cshtml
@@ -0,0 +1,92 @@
+@using System.Collections.Generic
+@using Microsoft.AspNetCore.Http
+@using Microsoft.AspNetCore.Http.Authentication
+@model LoginViewModel
+@inject SignInManager<ApplicationUser> SignInManager
+
+@{
+    ViewData["Title"] = "Log in";
+}
+
+<h2>@ViewData["Title"].</h2>
+<div class="row">
+    <div class="col-md-8">
+        <section>
+            <form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+                <h4>Use a local account to log in.</h4>
+                <hr />
+                <div asp-validation-summary="All" class="text-danger"></div>
+                <div class="form-group">
+                    <label asp-for="Email" class="col-md-2 control-label"></label>
+                    <div class="col-md-10">
+                        <input asp-for="Email" class="form-control" />
+                        <span asp-validation-for="Email" class="text-danger"></span>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label asp-for="Password" class="col-md-2 control-label"></label>
+                    <div class="col-md-10">
+                        <input asp-for="Password" class="form-control" />
+                        <span asp-validation-for="Password" class="text-danger"></span>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="col-md-offset-2 col-md-10">
+                        <div class="checkbox">
+                            <label asp-for="RememberMe">
+                                <input asp-for="RememberMe" />
+                                @Html.DisplayNameFor(m => m.RememberMe)
+                            </label>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="col-md-offset-2 col-md-10">
+                        <button type="submit" class="btn btn-default">Log in</button>
+                    </div>
+                </div>
+                <p>
+                    <a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">Register as a new user?</a>
+                </p>
+                <p>
+                    <a asp-action="ForgotPassword">Forgot your password?</a>
+                </p>
+            </form>
+        </section>
+    </div>
+    <div class="col-md-4">
+        <section>
+            <h4>Use another service to log in.</h4>
+            <hr />
+            @{
+                var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
+                if (loginProviders.Count == 0)
+                {
+                    <div>
+                        <p>
+                            There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
+                            for details on setting up this ASP.NET application to support logging in via external services.
+                        </p>
+                    </div>
+                }
+                else
+                {
+                    <form asp-controller="Account" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+                        <div>
+                            <p>
+                                @foreach (var provider in loginProviders)
+                                {
+                                    <button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
+                                }
+                            </p>
+                        </div>
+                    </form>
+                }
+            }
+        </section>
+    </div>
+</div>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Register.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Register.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Register.cshtml
new file mode 100644
index 0000000..2090f90
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/Register.cshtml
@@ -0,0 +1,42 @@
+@model RegisterViewModel
+@{
+    ViewData["Title"] = "Register";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Account" asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+    <h4>Create a new account.</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="Email" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Email" class="form-control" />
+            <span asp-validation-for="Email" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="Password" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Password" class="form-control" />
+            <span asp-validation-for="Password" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="ConfirmPassword" class="form-control" />
+            <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Register</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPassword.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPassword.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPassword.cshtml
new file mode 100644
index 0000000..dd716d7
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPassword.cshtml
@@ -0,0 +1,43 @@
+@model ResetPasswordViewModel
+@{
+    ViewData["Title"] = "Reset password";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Account" asp-action="ResetPassword" method="post" class="form-horizontal">
+    <h4>Reset your password.</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <input asp-for="Code" type="hidden" />
+    <div class="form-group">
+        <label asp-for="Email" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Email" class="form-control" />
+            <span asp-validation-for="Email" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="Password" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Password" class="form-control" />
+            <span asp-validation-for="Password" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="ConfirmPassword" class="form-control" />
+            <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Reset</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPasswordConfirmation.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPasswordConfirmation.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPasswordConfirmation.cshtml
new file mode 100644
index 0000000..6321d85
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/ResetPasswordConfirmation.cshtml
@@ -0,0 +1,8 @@
+@{
+    ViewData["Title"] = "Reset password confirmation";
+}
+
+<h1>@ViewData["Title"].</h1>
+<p>
+    Your password has been reset. Please <a asp-controller="Account" asp-action="Login">Click here to log in</a>.
+</p>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/SendCode.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/SendCode.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/SendCode.cshtml
new file mode 100644
index 0000000..e85ca3c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/SendCode.cshtml
@@ -0,0 +1,21 @@
+@model SendCodeViewModel
+@{
+    ViewData["Title"] = "Send Verification Code";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Account" asp-action="SendCode" asp-route-returnurl="@Model.ReturnUrl" method="post" class="form-horizontal">
+    <input asp-for="RememberMe" type="hidden" />
+    <div class="row">
+        <div class="col-md-8">
+            Select Two-Factor Authentication Provider:
+            <select asp-for="SelectedProvider" asp-items="Model.Providers"></select>
+            <button type="submit" class="btn btn-default">Submit</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/VerifyCode.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/VerifyCode.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/VerifyCode.cshtml
new file mode 100644
index 0000000..60afb36
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Account/VerifyCode.cshtml
@@ -0,0 +1,38 @@
+@model VerifyCodeViewModel
+@{
+    ViewData["Title"] = "Verify";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Account" asp-action="VerifyCode" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <input asp-for="Provider" type="hidden" />
+    <input asp-for="RememberMe" type="hidden" />
+    <h4>@ViewData["Status"]</h4>
+    <hr />
+    <div class="form-group">
+        <label asp-for="Code" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Code" class="form-control" />
+            <span asp-validation-for="Code" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <div class="checkbox">
+                <input asp-for="RememberBrowser" />
+                <label asp-for="RememberBrowser"></label>
+            </div>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Submit</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/About.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/About.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/About.cshtml
new file mode 100644
index 0000000..b653a26
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/About.cshtml
@@ -0,0 +1,7 @@
+@{
+    ViewData["Title"] = "About";
+}
+<h2>@ViewData["Title"].</h2>
+<h3>@ViewData["Message"]</h3>
+
+<p>Use this area to provide additional information.</p>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Contact.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Contact.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Contact.cshtml
new file mode 100644
index 0000000..f953aa6
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Contact.cshtml
@@ -0,0 +1,17 @@
+@{
+    ViewData["Title"] = "Contact";
+}
+<h2>@ViewData["Title"].</h2>
+<h3>@ViewData["Message"]</h3>
+
+<address>
+    One Microsoft Way<br />
+    Redmond, WA 98052-6399<br />
+    <abbr title="Phone">P:</abbr>
+    425.555.0100
+</address>
+
+<address>
+    <strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
+    <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
+</address>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Index.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Index.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Index.cshtml
new file mode 100644
index 0000000..957b8c1
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Home/Index.cshtml
@@ -0,0 +1,109 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+
+<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
+    <ol class="carousel-indicators">
+        <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
+        <li data-target="#myCarousel" data-slide-to="1"></li>
+        <li data-target="#myCarousel" data-slide-to="2"></li>
+        <li data-target="#myCarousel" data-slide-to="3"></li>
+    </ol>
+    <div class="carousel-inner" role="listbox">
+        <div class="item active">
+            <img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
+            <div class="carousel-caption" role="option">
+                <p>
+                    Learn how to build ASP.NET apps that can run anywhere.
+                    <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
+                        Learn More
+                    </a>
+                </p>
+            </div>
+        </div>
+        <div class="item">
+            <img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
+            <div class="carousel-caption" role="option">
+                <p>
+                    There are powerful new features in Visual Studio for building modern web apps.
+                    <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
+                        Learn More
+                    </a>
+                </p>
+            </div>
+        </div>
+        <div class="item">
+            <img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" />
+            <div class="carousel-caption" role="option">
+                <p>
+                    Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
+                    <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
+                        Learn More
+                    </a>
+                </p>
+            </div>
+        </div>
+        <div class="item">
+            <img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
+            <div class="carousel-caption" role="option">
+                <p>
+                    Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
+                    <a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
+                        Learn More
+                    </a>
+                </p>
+            </div>
+        </div>
+    </div>
+    <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
+        <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
+        <span class="sr-only">Previous</span>
+    </a>
+    <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
+        <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
+        <span class="sr-only">Next</span>
+    </a>
+</div>
+
+<div class="row">
+    <div class="col-md-3">
+        <h2>Application uses</h2>
+        <ul>
+            <li>Sample pages using ASP.NET Core MVC</li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> and <a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
+            <li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
+        </ul>
+    </div>
+    <div class="col-md-3">
+        <h2>How to</h2>
+        <ul>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=699562">Add an appsetting in config and access it in app.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
+        </ul>
+    </div>
+    <div class="col-md-3">
+        <h2>Overview</h2>
+        <ul>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
+        </ul>
+    </div>
+    <div class="col-md-3">
+        <h2>Run & Deploy</h2>
+        <ul>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
+            <li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
+        </ul>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/AddPhoneNumber.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/AddPhoneNumber.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/AddPhoneNumber.cshtml
new file mode 100644
index 0000000..2feb93b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/AddPhoneNumber.cshtml
@@ -0,0 +1,27 @@
+@model AddPhoneNumberViewModel
+@{
+    ViewData["Title"] = "Add Phone Number";
+}
+
+<h2>@ViewData["Title"].</h2>
+<form asp-controller="Manage" asp-action="AddPhoneNumber" method="post" class="form-horizontal">
+    <h4>Add a phone number.</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="PhoneNumber" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="PhoneNumber" class="form-control" />
+            <span asp-validation-for="PhoneNumber" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Send verification code</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ChangePassword.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ChangePassword.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ChangePassword.cshtml
new file mode 100644
index 0000000..41c7960
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ChangePassword.cshtml
@@ -0,0 +1,42 @@
+@model ChangePasswordViewModel
+@{
+    ViewData["Title"] = "Change Password";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Manage" asp-action="ChangePassword" method="post" class="form-horizontal">
+    <h4>Change Password Form</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="OldPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="OldPassword" class="form-control" />
+            <span asp-validation-for="OldPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="NewPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="NewPassword" class="form-control" />
+            <span asp-validation-for="NewPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="ConfirmPassword" class="form-control" />
+            <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Change password</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/Index.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/Index.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/Index.cshtml
new file mode 100644
index 0000000..8419b24
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/Index.cshtml
@@ -0,0 +1,71 @@
+@model IndexViewModel
+@{
+    ViewData["Title"] = "Manage your account";
+}
+
+<h2>@ViewData["Title"].</h2>
+<p class="text-success">@ViewData["StatusMessage"]</p>
+
+<div>
+    <h4>Change your account settings</h4>
+    <hr />
+    <dl class="dl-horizontal">
+        <dt>Password:</dt>
+        <dd>
+            @if (Model.HasPassword)
+            {
+                <a asp-controller="Manage" asp-action="ChangePassword" class="btn-bracketed">Change</a>
+            }
+            else
+            {
+                <a asp-controller="Manage" asp-action="SetPassword" class="btn-bracketed">Create</a>
+            }
+        </dd>
+        <dt>External Logins:</dt>
+        <dd>
+
+            @Model.Logins.Count <a asp-controller="Manage" asp-action="ManageLogins" class="btn-bracketed">Manage</a>
+        </dd>
+        <dt>Phone Number:</dt>
+        <dd>
+            <p>
+                Phone Numbers can used as a second factor of verification in two-factor authentication.
+                See <a href="https://go.microsoft.com/fwlink/?LinkID=532713">this article</a>
+                for details on setting up this ASP.NET application to support two-factor authentication using SMS.
+            </p>
+            @*@(Model.PhoneNumber ?? "None")
+                @if (Model.PhoneNumber != null)
+                {
+                    <br />
+                    <a asp-controller="Manage" asp-action="AddPhoneNumber" class="btn-bracketed">Change</a>
+                    <form asp-controller="Manage" asp-action="RemovePhoneNumber" method="post">
+                        [<button type="submit" class="btn-link">Remove</button>]
+                    </form>
+                }
+                else
+                {
+                    <a asp-controller="Manage" asp-action="AddPhoneNumber" class="btn-bracketed">Add</a>
+                }*@
+        </dd>
+
+        <dt>Two-Factor Authentication:</dt>
+        <dd>
+            <p>
+                There are no two-factor authentication providers configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532713">this article</a>
+                for setting up this application to support two-factor authentication.
+            </p>
+            @*@if (Model.TwoFactor)
+                {
+                    <form asp-controller="Manage" asp-action="DisableTwoFactorAuthentication" method="post" class="form-horizontal">
+                        Enabled <button type="submit" class="btn-link btn-bracketed">Disable</button>
+                    </form>
+                }
+                else
+                {
+                    <form asp-controller="Manage" asp-action="EnableTwoFactorAuthentication" method="post" class="form-horizontal">
+                        <button type="submit" class="btn-link btn-bracketed">Enable</button> Disabled
+                    </form>
+                }*@
+        </dd>
+    </dl>
+</div>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ManageLogins.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ManageLogins.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ManageLogins.cshtml
new file mode 100644
index 0000000..35e12da
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/ManageLogins.cshtml
@@ -0,0 +1,54 @@
+@model ManageLoginsViewModel
+@using Microsoft.AspNetCore.Http.Authentication
+@{
+    ViewData["Title"] = "Manage your external logins";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<p class="text-success">@ViewData["StatusMessage"]</p>
+@if (Model.CurrentLogins.Count > 0)
+{
+    <h4>Registered Logins</h4>
+    <table class="table">
+        <tbody>
+            @for (var index = 0; index < Model.CurrentLogins.Count; index++)
+            {
+                <tr>
+                    <td>@Model.CurrentLogins[index].LoginProvider</td>
+                    <td>
+                        @if ((bool)ViewData["ShowRemoveButton"])
+                        {
+                            <form asp-controller="Manage" asp-action="RemoveLogin" method="post" class="form-horizontal">
+                                <div>
+                                    <input asp-for="@Model.CurrentLogins[index].LoginProvider" name="LoginProvider" type="hidden" />
+                                    <input asp-for="@Model.CurrentLogins[index].ProviderKey" name="ProviderKey" type="hidden" />
+                                    <input type="submit" class="btn btn-default" value="Remove" title="Remove this @Model.CurrentLogins[index].LoginProvider login from your account" />
+                                </div>
+                            </form>
+                        }
+                        else
+                        {
+                            @: &nbsp;
+                        }
+                    </td>
+                </tr>
+            }
+        </tbody>
+    </table>
+}
+@if (Model.OtherLogins.Count > 0)
+{
+    <h4>Add another service to log in.</h4>
+    <hr />
+    <form asp-controller="Manage" asp-action="LinkLogin" method="post" class="form-horizontal">
+        <div id="socialLoginList">
+            <p>
+                @foreach (var provider in Model.OtherLogins)
+                {
+                    <button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
+                }
+            </p>
+        </div>
+    </form>
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/SetPassword.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/SetPassword.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/SetPassword.cshtml
new file mode 100644
index 0000000..cfa7791
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/SetPassword.cshtml
@@ -0,0 +1,38 @@
+@model SetPasswordViewModel
+@{
+    ViewData["Title"] = "Set Password";
+}
+
+<p class="text-info">
+    You do not have a local username/password for this site. Add a local
+    account so you can log in without an external login.
+</p>
+
+<form asp-controller="Manage" asp-action="SetPassword" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+    <h4>Set your password</h4>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="NewPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="NewPassword" class="form-control" />
+            <span asp-validation-for="NewPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="ConfirmPassword" class="form-control" />
+            <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Set password</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/VerifyPhoneNumber.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/VerifyPhoneNumber.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/VerifyPhoneNumber.cshtml
new file mode 100644
index 0000000..af7cd0b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Manage/VerifyPhoneNumber.cshtml
@@ -0,0 +1,30 @@
+@model VerifyPhoneNumberViewModel
+@{
+    ViewData["Title"] = "Verify Phone Number";
+}
+
+<h2>@ViewData["Title"].</h2>
+
+<form asp-controller="Manage" asp-action="VerifyPhoneNumber" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
+    <input asp-for="PhoneNumber" type="hidden" />
+    <h4>Add a phone number.</h4>
+    <h5>@ViewData["Status"]</h5>
+    <hr />
+    <div asp-validation-summary="All" class="text-danger"></div>
+    <div class="form-group">
+        <label asp-for="Code" class="col-md-2 control-label"></label>
+        <div class="col-md-10">
+            <input asp-for="Code" class="form-control" />
+            <span asp-validation-for="Code" class="text-danger"></span>
+        </div>
+    </div>
+    <div class="form-group">
+        <div class="col-md-offset-2 col-md-10">
+            <button type="submit" class="btn btn-default">Submit</button>
+        </div>
+    </div>
+</form>
+
+@section Scripts {
+    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/Error.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/Error.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/Error.cshtml
new file mode 100644
index 0000000..229c2de
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/Error.cshtml
@@ -0,0 +1,14 @@
+@{
+    ViewData["Title"] = "Error";
+}
+
+<h1 class="text-danger">Error.</h1>
+<h2 class="text-danger">An error occurred while processing your request.</h2>
+
+<h3>Development Mode</h3>
+<p>
+    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
+</p>
+<p>
+    <strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
+</p>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_Layout.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_Layout.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000..56827ca
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_Layout.cshtml
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>@ViewData["Title"] - WebApplication</title>
+
+    <environment names="Development">
+        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
+        <link rel="stylesheet" href="~/css/site.css" />
+    </environment>
+    <environment names="Staging,Production">
+        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
+              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
+              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
+        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
+    </environment>
+</head>
+<body>
+    <div class="navbar navbar-inverse navbar-fixed-top">
+        <div class="container">
+            <div class="navbar-header">
+                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+                    <span class="sr-only">Toggle navigation</span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                </button>
+                <a asp-controller="Home" asp-action="Index" class="navbar-brand">WebApplication</a>
+            </div>
+            <div class="navbar-collapse collapse">
+                <ul class="nav navbar-nav">
+                    <li><a asp-controller="Home" asp-action="Index">Home</a></li>
+                    <li><a asp-controller="Home" asp-action="About">About</a></li>
+                    <li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
+                </ul>
+                @await Html.PartialAsync("_LoginPartial")
+            </div>
+        </div>
+    </div>
+    <div class="container body-content">
+        @RenderBody()
+        <hr />
+        <footer>
+            <p>&copy; 2016 - WebApplication</p>
+        </footer>
+    </div>
+
+    <environment names="Development">
+        <script src="~/lib/jquery/dist/jquery.js"></script>
+        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
+        <script src="~/js/site.js" asp-append-version="true"></script>
+    </environment>
+    <environment names="Staging,Production">
+        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.3.min.js"
+                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
+                asp-fallback-test="window.jQuery">
+        </script>
+        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
+                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
+                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
+        </script>
+        <script src="~/js/site.min.js" asp-append-version="true"></script>
+    </environment>
+
+    @RenderSection("scripts", required: false)
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_LoginPartial.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_LoginPartial.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_LoginPartial.cshtml
new file mode 100644
index 0000000..f50d5e8
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_LoginPartial.cshtml
@@ -0,0 +1,26 @@
+@using Microsoft.AspNetCore.Identity
+@using WebApplication.Models
+
+@inject SignInManager<ApplicationUser> SignInManager
+@inject UserManager<ApplicationUser> UserManager
+
+@if (SignInManager.IsSignedIn(User))
+{
+    <form asp-controller="Account" asp-action="LogOff" method="post" id="logoutForm" class="navbar-right">
+        <ul class="nav navbar-nav navbar-right">
+            <li>
+                <a asp-controller="Manage" asp-action="Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
+            </li>
+            <li>
+                <button type="submit" class="btn btn-link navbar-btn navbar-link">Log off</button>
+            </li>
+        </ul>
+    </form>
+}
+else
+{
+    <ul class="nav navbar-nav navbar-right">
+        <li><a asp-controller="Account" asp-action="Register">Register</a></li>
+        <li><a asp-controller="Account" asp-action="Login">Log in</a></li>
+    </ul>
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_ValidationScriptsPartial.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_ValidationScriptsPartial.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_ValidationScriptsPartial.cshtml
new file mode 100644
index 0000000..289b220
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/Shared/_ValidationScriptsPartial.cshtml
@@ -0,0 +1,14 @@
+<environment names="Development">
+    <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
+    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
+</environment>
+<environment names="Staging,Production">
+    <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/jquery.validate.min.js"
+            asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
+            asp-fallback-test="window.jQuery && window.jQuery.validator">
+    </script>
+    <script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"
+            asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
+            asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive">
+    </script>
+</environment>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewImports.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewImports.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewImports.cshtml
new file mode 100644
index 0000000..dcca16c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewImports.cshtml
@@ -0,0 +1,6 @@
+@using WebApplication
+@using WebApplication.Models
+@using WebApplication.Models.AccountViewModels
+@using WebApplication.Models.ManageViewModels
+@using Microsoft.AspNetCore.Identity
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewStart.cshtml
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewStart.cshtml b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewStart.cshtml
new file mode 100644
index 0000000..820a2f6
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+    Layout = "_Layout";
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/appsettings.json
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/appsettings.json b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/appsettings.json
new file mode 100644
index 0000000..53b17ae
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/appsettings.json
@@ -0,0 +1,13 @@
+{
+  "ConnectionStrings": {
+    "DefaultConnection": "Data Source=WebApplication.db"
+  },
+  "Logging": {
+    "IncludeScopes": false,
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/bower.json
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/bower.json b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/bower.json
new file mode 100644
index 0000000..3891fce
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/bower.json
@@ -0,0 +1,10 @@
+{
+  "name": "webapplication",
+  "private": true,
+  "dependencies": {
+    "bootstrap": "3.3.6",
+    "jquery": "2.2.3",
+    "jquery-validation": "1.15.0",
+    "jquery-validation-unobtrusive": "3.2.6"
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/gulpfile.js
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/gulpfile.js b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/gulpfile.js
new file mode 100644
index 0000000..faf2955
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/gulpfile.js
@@ -0,0 +1,45 @@
+/// <binding Clean='clean' />
+"use strict";
+
+var gulp = require("gulp"),
+    rimraf = require("rimraf"),
+    concat = require("gulp-concat"),
+    cssmin = require("gulp-cssmin"),
+    uglify = require("gulp-uglify");
+
+var webroot = "./wwwroot/";
+
+var paths = {
+    js: webroot + "js/**/*.js",
+    minJs: webroot + "js/**/*.min.js",
+    css: webroot + "css/**/*.css",
+    minCss: webroot + "css/**/*.min.css",
+    concatJsDest: webroot + "js/site.min.js",
+    concatCssDest: webroot + "css/site.min.css"
+};
+
+gulp.task("clean:js", function (cb) {
+    rimraf(paths.concatJsDest, cb);
+});
+
+gulp.task("clean:css", function (cb) {
+    rimraf(paths.concatCssDest, cb);
+});
+
+gulp.task("clean", ["clean:js", "clean:css"]);
+
+gulp.task("min:js", function () {
+    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
+        .pipe(concat(paths.concatJsDest))
+        .pipe(uglify())
+        .pipe(gulp.dest("."));
+});
+
+gulp.task("min:css", function () {
+    return gulp.src([paths.css, "!" + paths.minCss])
+        .pipe(concat(paths.concatCssDest))
+        .pipe(cssmin())
+        .pipe(gulp.dest("."));
+});
+
+gulp.task("min", ["min:js", "min:css"]);

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/package.json
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/package.json b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/package.json
new file mode 100644
index 0000000..4bb6c88
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "webapplication",
+  "version": "0.0.0",
+  "private": true,
+  "devDependencies": {
+    "gulp": "3.9.1",
+    "gulp-concat": "2.6.0",
+    "gulp-cssmin": "0.1.7",
+    "gulp-uglify": "1.5.3",
+    "rimraf": "2.5.2"
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/project.json
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/project.json b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/project.json
new file mode 100644
index 0000000..97b3f06
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/project.json
@@ -0,0 +1,108 @@
+{
+  "userSecretsId": "aspnet-WebApplication-0799fe3e-6eaf-4c5f-b40e-7c6bfd5dfa9a",
+
+  "dependencies": {
+    "Microsoft.NETCore.App": {
+      "version": "1.0.0",
+      "type": "platform"
+    },
+    "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",
+    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
+    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
+    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
+    "Microsoft.AspNetCore.Mvc": "1.0.0",
+    "Microsoft.AspNetCore.Razor.Tools": {
+      "version": "1.0.0-preview2-final",
+      "type": "build"
+    },
+    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
+    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
+    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
+    "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0",
+    "Microsoft.EntityFrameworkCore.Tools": {
+      "version": "1.0.0-preview2-final",
+      "type": "build"
+    },
+    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
+    "Microsoft.Extensions.Configuration.Json": "1.0.0",
+    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
+    "Microsoft.Extensions.Logging": "1.0.0",
+    "Microsoft.Extensions.Logging.Console": "1.0.0",
+    "Microsoft.Extensions.Logging.Debug": "1.0.0",
+    "log4net.Extensions.Logging": { "target": "project" },
+    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
+    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
+      "version": "1.0.0-preview2-final",
+      "type": "build"
+    },
+    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
+      "version": "1.0.0-preview2-final",
+      "type": "build"
+    }
+  },
+
+  "tools": {
+    "Microsoft.AspNetCore.Razor.Tools": {
+      "version": "1.0.0-preview2-final",
+      "imports": "portable-net45+win8+dnxcore50"
+    },
+    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
+      "version": "1.0.0-preview2-final",
+      "imports": "portable-net45+win8+dnxcore50"
+    },
+    "Microsoft.EntityFrameworkCore.Tools": {
+      "version": "1.0.0-preview2-final",
+      "imports": [
+        "portable-net45+win8+dnxcore50",
+        "portable-net45+win8"
+      ]
+    },
+    "Microsoft.Extensions.SecretManager.Tools": {
+      "version": "1.0.0-preview2-final",
+      "imports": "portable-net45+win8+dnxcore50"
+    },
+    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
+      "version": "1.0.0-preview2-final",
+      "imports": [
+        "portable-net45+win8+dnxcore50",
+        "portable-net45+win8"
+      ]
+    }
+  },
+
+  "frameworks": {
+    "netcoreapp1.0": {
+      "imports": "portable-net45+win8"
+    }
+  },
+
+  "buildOptions": {
+    "debugType": "portable",
+    "emitEntryPoint": true,
+    "preserveCompilationContext": true
+  },
+
+  "runtimeOptions": {
+    "configProperties": {
+      "System.GC.Server": true
+    }
+  },
+
+  "publishOptions": {
+    "include": [
+      "wwwroot",
+      "Views",
+      "appsettings.json",
+      "web.config"
+    ]
+  },
+
+  "scripts": {
+    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
+    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
+  },
+
+  "tooling": {
+    "defaultNamespace": "WebApplication"
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/web.config
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/web.config b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/web.config
new file mode 100644
index 0000000..a8d6672
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/web.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+
+  <!--
+    Configure your application settings in appsettings.json. Learn more at https://go.microsoft.com/fwlink/?LinkId=786380
+  -->
+
+  <system.webServer>
+    <handlers>
+      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
+    </handlers>
+    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
+  </system.webServer>
+</configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.css
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.css b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.css
new file mode 100644
index 0000000..6baa84d
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.css
@@ -0,0 +1,44 @@
+body {
+    padding-top: 50px;
+    padding-bottom: 20px;
+}
+
+/* Wrapping element */
+/* Set some basic padding to keep content from hitting the edges */
+.body-content {
+    padding-left: 15px;
+    padding-right: 15px;
+}
+
+/* Set widths on the form inputs since otherwise they're 100% wide */
+input,
+select,
+textarea {
+    max-width: 280px;
+}
+
+/* Carousel */
+.carousel-caption p {
+    font-size: 20px;
+    line-height: 1.4;
+}
+
+/* buttons and links extension to use brackets: [ click me ] */
+.btn-bracketed::before {
+    display:inline-block;
+    content: "[";
+    padding-right: 0.5em;
+}
+.btn-bracketed::after {
+    display:inline-block;
+    content: "]";
+    padding-left: 0.5em;
+}
+
+/* Hide/rearrange for smaller screens */
+@media screen and (max-width: 767px) {
+  /* Hide captions */
+  .carousel-caption {
+    display: none
+  }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.min.css
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.min.css b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.min.css
new file mode 100644
index 0000000..c8f600a
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/css/site.min.css
@@ -0,0 +1 @@
+body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.carousel-caption p{font-size:20px;line-height:1.4}.btn-bracketed::before{display:inline-block;content:"[";padding-right:.5em}.btn-bracketed::after{display:inline-block;content:"]";padding-left:.5em}@media screen and (max-width:767px){.carousel-caption{display:none}}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/favicon.ico
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/favicon.ico b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/favicon.ico
new file mode 100644
index 0000000..a3a7999
Binary files /dev/null and b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/wwwroot/favicon.ico differ


[04/10] logging-log4net git commit: Add test web app for asp extension

Posted by dp...@apache.org.
Add test web app for asp extension


Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/5e667994
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/5e667994
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/5e667994

Branch: refs/heads/pr/old/32
Commit: 5e667994dd8bed50087b1948d4550d5f6e95aaac
Parents: 85d581e
Author: Peter Jas <ne...@yahoo.com>
Authored: Sun Aug 21 00:51:56 2016 +0000
Committer: Dominik Psenner <dp...@apache.org>
Committed: Thu Jun 22 22:11:35 2017 +0200

----------------------------------------------------------------------
 .../log4net.Extensions.Logging.Test/.bowerrc    |   3 +
 .../log4net.Extensions.Logging.Test/.gitignore  | 234 ++++++++++
 .../Controllers/AccountController.cs            | 468 +++++++++++++++++++
 .../Controllers/HomeController.cs               |  35 ++
 .../Controllers/ManageController.cs             | 347 ++++++++++++++
 .../Data/ApplicationDbContext.cs                |  26 ++
 ...00000000000_CreateIdentitySchema.Designer.cs | 212 +++++++++
 .../00000000000000_CreateIdentitySchema.cs      | 215 +++++++++
 .../ApplicationDbContextModelSnapshot.cs        | 211 +++++++++
 .../ExternalLoginConfirmationViewModel.cs       |  15 +
 .../ForgotPasswordViewModel.cs                  |  15 +
 .../Models/AccountViewModels/LoginViewModel.cs  |  22 +
 .../AccountViewModels/RegisterViewModel.cs      |  27 ++
 .../AccountViewModels/ResetPasswordViewModel.cs |  27 ++
 .../AccountViewModels/SendCodeViewModel.cs      |  19 +
 .../AccountViewModels/VerifyCodeViewModel.cs    |  25 +
 .../Models/ApplicationUser.cs                   |  13 +
 .../ManageViewModels/AddPhoneNumberViewModel.cs |  16 +
 .../ManageViewModels/ChangePasswordViewModel.cs |  27 ++
 .../ConfigureTwoFactorViewModel.cs              |  15 +
 .../Models/ManageViewModels/FactorViewModel.cs  |  12 +
 .../Models/ManageViewModels/IndexViewModel.cs   |  21 +
 .../ManageViewModels/ManageLoginsViewModel.cs   |  16 +
 .../ManageViewModels/RemoveLoginViewModel.cs    |  14 +
 .../ManageViewModels/SetPasswordViewModel.cs    |  22 +
 .../VerifyPhoneNumberViewModel.cs               |  19 +
 .../log4net.Extensions.Logging.Test/Program.cs  |  24 +
 .../log4net.Extensions.Logging.Test/README.md   |  39 ++
 .../Services/IEmailSender.cs                    |  12 +
 .../Services/ISmsSender.cs                      |  12 +
 .../Services/MessageServices.cs                 |  25 +
 .../Settings/logconfig.xml                      |   6 +
 .../log4net.Extensions.Logging.Test/Startup.cs  |  92 ++++
 .../Views/Account/ConfirmEmail.cshtml           |  10 +
 .../Account/ExternalLoginConfirmation.cshtml    |  35 ++
 .../Views/Account/ExternalLoginFailure.cshtml   |   8 +
 .../Views/Account/ForgotPassword.cshtml         |  31 ++
 .../Account/ForgotPasswordConfirmation.cshtml   |   8 +
 .../Views/Account/Lockout.cshtml                |   8 +
 .../Views/Account/Login.cshtml                  |  92 ++++
 .../Views/Account/Register.cshtml               |  42 ++
 .../Views/Account/ResetPassword.cshtml          |  43 ++
 .../Account/ResetPasswordConfirmation.cshtml    |   8 +
 .../Views/Account/SendCode.cshtml               |  21 +
 .../Views/Account/VerifyCode.cshtml             |  38 ++
 .../Views/Home/About.cshtml                     |   7 +
 .../Views/Home/Contact.cshtml                   |  17 +
 .../Views/Home/Index.cshtml                     | 109 +++++
 .../Views/Manage/AddPhoneNumber.cshtml          |  27 ++
 .../Views/Manage/ChangePassword.cshtml          |  42 ++
 .../Views/Manage/Index.cshtml                   |  71 +++
 .../Views/Manage/ManageLogins.cshtml            |  54 +++
 .../Views/Manage/SetPassword.cshtml             |  38 ++
 .../Views/Manage/VerifyPhoneNumber.cshtml       |  30 ++
 .../Views/Shared/Error.cshtml                   |  14 +
 .../Views/Shared/_Layout.cshtml                 |  68 +++
 .../Views/Shared/_LoginPartial.cshtml           |  26 ++
 .../Shared/_ValidationScriptsPartial.cshtml     |  14 +
 .../Views/_ViewImports.cshtml                   |   6 +
 .../Views/_ViewStart.cshtml                     |   3 +
 .../appsettings.json                            |  13 +
 .../log4net.Extensions.Logging.Test/bower.json  |  10 +
 .../log4net.Extensions.Logging.Test/gulpfile.js |  45 ++
 .../package.json                                |  12 +
 .../project.json                                | 108 +++++
 .../log4net.Extensions.Logging.Test/web.config  |  14 +
 .../wwwroot/css/site.css                        |  44 ++
 .../wwwroot/css/site.min.css                    |   1 +
 .../wwwroot/favicon.ico                         | Bin 0 -> 32038 bytes
 .../wwwroot/images/banner1.svg                  |   1 +
 .../wwwroot/images/banner2.svg                  |   1 +
 .../wwwroot/images/banner3.svg                  |   1 +
 .../wwwroot/images/banner4.svg                  |   1 +
 .../wwwroot/js/site.js                          |   1 +
 .../wwwroot/js/site.min.js                      |   0
 75 files changed, 3408 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.bowerrc
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.bowerrc b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.bowerrc
new file mode 100644
index 0000000..6406626
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.bowerrc
@@ -0,0 +1,3 @@
+{
+  "directory": "wwwroot/lib"
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.gitignore
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.gitignore b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.gitignore
new file mode 100644
index 0000000..0ca27f0
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/.gitignore
@@ -0,0 +1,234 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Microsoft Azure ApplicationInsights config file
+ApplicationInsights.config
+
+# Windows Store app package directory
+AppPackages/
+BundleArtifacts/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+
+# FAKE - F# Make
+.fake/

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/AccountController.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/AccountController.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/AccountController.cs
new file mode 100644
index 0000000..035638a
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/AccountController.cs
@@ -0,0 +1,468 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.Extensions.Logging;
+using WebApplication.Models;
+using WebApplication.Models.AccountViewModels;
+using WebApplication.Services;
+
+namespace WebApplication.Controllers
+{
+    [Authorize]
+    public class AccountController : Controller
+    {
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly IEmailSender _emailSender;
+        private readonly ISmsSender _smsSender;
+        private readonly ILogger _logger;
+
+        public AccountController(
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
+            IEmailSender emailSender,
+            ISmsSender smsSender,
+            ILoggerFactory loggerFactory)
+        {
+            _userManager = userManager;
+            _signInManager = signInManager;
+            _emailSender = emailSender;
+            _smsSender = smsSender;
+            _logger = loggerFactory.CreateLogger<AccountController>();
+        }
+
+        //
+        // GET: /Account/Login
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult Login(string returnUrl = null)
+        {
+            ViewData["ReturnUrl"] = returnUrl;
+            return View();
+        }
+
+        //
+        // POST: /Account/Login
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
+        {
+            ViewData["ReturnUrl"] = returnUrl;
+            if (ModelState.IsValid)
+            {
+                // This doesn't count login failures towards account lockout
+                // To enable password failures to trigger account lockout, set lockoutOnFailure: true
+                var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
+                if (result.Succeeded)
+                {
+                    _logger.LogInformation(1, "User logged in.");
+                    return RedirectToLocal(returnUrl);
+                }
+                if (result.RequiresTwoFactor)
+                {
+                    return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
+                }
+                if (result.IsLockedOut)
+                {
+                    _logger.LogWarning(2, "User account locked out.");
+                    return View("Lockout");
+                }
+                else
+                {
+                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
+                    return View(model);
+                }
+            }
+
+            // If we got this far, something failed, redisplay form
+            return View(model);
+        }
+
+        //
+        // GET: /Account/Register
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult Register(string returnUrl = null)
+        {
+            ViewData["ReturnUrl"] = returnUrl;
+            return View();
+        }
+
+        //
+        // POST: /Account/Register
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
+        {
+            ViewData["ReturnUrl"] = returnUrl;
+            if (ModelState.IsValid)
+            {
+                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
+                var result = await _userManager.CreateAsync(user, model.Password);
+                if (result.Succeeded)
+                {
+                    // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
+                    // Send an email with this link
+                    //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+                    //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+                    //await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
+                    //    $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>");
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    _logger.LogInformation(3, "User created a new account with password.");
+                    return RedirectToLocal(returnUrl);
+                }
+                AddErrors(result);
+            }
+
+            // If we got this far, something failed, redisplay form
+            return View(model);
+        }
+
+        //
+        // POST: /Account/LogOff
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> LogOff()
+        {
+            await _signInManager.SignOutAsync();
+            _logger.LogInformation(4, "User logged out.");
+            return RedirectToAction(nameof(HomeController.Index), "Home");
+        }
+
+        //
+        // POST: /Account/ExternalLogin
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public IActionResult ExternalLogin(string provider, string returnUrl = null)
+        {
+            // Request a redirect to the external login provider.
+            var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
+            var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
+            return Challenge(properties, provider);
+        }
+
+        //
+        // GET: /Account/ExternalLoginCallback
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
+        {
+            if (remoteError != null)
+            {
+                ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
+                return View(nameof(Login));
+            }
+            var info = await _signInManager.GetExternalLoginInfoAsync();
+            if (info == null)
+            {
+                return RedirectToAction(nameof(Login));
+            }
+
+            // Sign in the user with this external login provider if the user already has a login.
+            var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
+            if (result.Succeeded)
+            {
+                _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider);
+                return RedirectToLocal(returnUrl);
+            }
+            if (result.RequiresTwoFactor)
+            {
+                return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl });
+            }
+            if (result.IsLockedOut)
+            {
+                return View("Lockout");
+            }
+            else
+            {
+                // If the user does not have an account, then ask the user to create an account.
+                ViewData["ReturnUrl"] = returnUrl;
+                ViewData["LoginProvider"] = info.LoginProvider;
+                var email = info.Principal.FindFirstValue(ClaimTypes.Email);
+                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email });
+            }
+        }
+
+        //
+        // POST: /Account/ExternalLoginConfirmation
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null)
+        {
+            if (ModelState.IsValid)
+            {
+                // Get the information about the user from the external login provider
+                var info = await _signInManager.GetExternalLoginInfoAsync();
+                if (info == null)
+                {
+                    return View("ExternalLoginFailure");
+                }
+                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
+                var result = await _userManager.CreateAsync(user);
+                if (result.Succeeded)
+                {
+                    result = await _userManager.AddLoginAsync(user, info);
+                    if (result.Succeeded)
+                    {
+                        await _signInManager.SignInAsync(user, isPersistent: false);
+                        _logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
+                        return RedirectToLocal(returnUrl);
+                    }
+                }
+                AddErrors(result);
+            }
+
+            ViewData["ReturnUrl"] = returnUrl;
+            return View(model);
+        }
+
+        // GET: /Account/ConfirmEmail
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<IActionResult> ConfirmEmail(string userId, string code)
+        {
+            if (userId == null || code == null)
+            {
+                return View("Error");
+            }
+            var user = await _userManager.FindByIdAsync(userId);
+            if (user == null)
+            {
+                return View("Error");
+            }
+            var result = await _userManager.ConfirmEmailAsync(user, code);
+            return View(result.Succeeded ? "ConfirmEmail" : "Error");
+        }
+
+        //
+        // GET: /Account/ForgotPassword
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult ForgotPassword()
+        {
+            return View();
+        }
+
+        //
+        // POST: /Account/ForgotPassword
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
+        {
+            if (ModelState.IsValid)
+            {
+                var user = await _userManager.FindByNameAsync(model.Email);
+                if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
+                {
+                    // Don't reveal that the user does not exist or is not confirmed
+                    return View("ForgotPasswordConfirmation");
+                }
+
+                // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=532713
+                // Send an email with this link
+                //var code = await _userManager.GeneratePasswordResetTokenAsync(user);
+                //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+                //await _emailSender.SendEmailAsync(model.Email, "Reset Password",
+                //   $"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
+                //return View("ForgotPasswordConfirmation");
+            }
+
+            // If we got this far, something failed, redisplay form
+            return View(model);
+        }
+
+        //
+        // GET: /Account/ForgotPasswordConfirmation
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult ForgotPasswordConfirmation()
+        {
+            return View();
+        }
+
+        //
+        // GET: /Account/ResetPassword
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult ResetPassword(string code = null)
+        {
+            return code == null ? View("Error") : View();
+        }
+
+        //
+        // POST: /Account/ResetPassword
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+            var user = await _userManager.FindByNameAsync(model.Email);
+            if (user == null)
+            {
+                // Don't reveal that the user does not exist
+                return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
+            }
+            var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
+            if (result.Succeeded)
+            {
+                return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
+            }
+            AddErrors(result);
+            return View();
+        }
+
+        //
+        // GET: /Account/ResetPasswordConfirmation
+        [HttpGet]
+        [AllowAnonymous]
+        public IActionResult ResetPasswordConfirmation()
+        {
+            return View();
+        }
+
+        //
+        // GET: /Account/SendCode
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<ActionResult> SendCode(string returnUrl = null, bool rememberMe = false)
+        {
+            var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+            if (user == null)
+            {
+                return View("Error");
+            }
+            var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
+            var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
+            return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
+        }
+
+        //
+        // POST: /Account/SendCode
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> SendCode(SendCodeViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View();
+            }
+
+            var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+            if (user == null)
+            {
+                return View("Error");
+            }
+
+            // Generate the token and send it
+            var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
+            if (string.IsNullOrWhiteSpace(code))
+            {
+                return View("Error");
+            }
+
+            var message = "Your security code is: " + code;
+            if (model.SelectedProvider == "Email")
+            {
+                await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message);
+            }
+            else if (model.SelectedProvider == "Phone")
+            {
+                await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
+            }
+
+            return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
+        }
+
+        //
+        // GET: /Account/VerifyCode
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<IActionResult> VerifyCode(string provider, bool rememberMe, string returnUrl = null)
+        {
+            // Require that the user has already logged in via username/password or external login
+            var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+            if (user == null)
+            {
+                return View("Error");
+            }
+            return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
+        }
+
+        //
+        // POST: /Account/VerifyCode
+        [HttpPost]
+        [AllowAnonymous]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> VerifyCode(VerifyCodeViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+
+            // The following code protects for brute force attacks against the two factor codes.
+            // If a user enters incorrect codes for a specified amount of time then the user account
+            // will be locked out for a specified amount of time.
+            var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser);
+            if (result.Succeeded)
+            {
+                return RedirectToLocal(model.ReturnUrl);
+            }
+            if (result.IsLockedOut)
+            {
+                _logger.LogWarning(7, "User account locked out.");
+                return View("Lockout");
+            }
+            else
+            {
+                ModelState.AddModelError(string.Empty, "Invalid code.");
+                return View(model);
+            }
+        }
+
+        #region Helpers
+
+        private void AddErrors(IdentityResult result)
+        {
+            foreach (var error in result.Errors)
+            {
+                ModelState.AddModelError(string.Empty, error.Description);
+            }
+        }
+
+        private Task<ApplicationUser> GetCurrentUserAsync()
+        {
+            return _userManager.GetUserAsync(HttpContext.User);
+        }
+
+        private IActionResult RedirectToLocal(string returnUrl)
+        {
+            if (Url.IsLocalUrl(returnUrl))
+            {
+                return Redirect(returnUrl);
+            }
+            else
+            {
+                return RedirectToAction(nameof(HomeController.Index), "Home");
+            }
+        }
+
+        #endregion
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/HomeController.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/HomeController.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/HomeController.cs
new file mode 100644
index 0000000..4b21d0c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/HomeController.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+
+namespace WebApplication.Controllers
+{
+    public class HomeController : Controller
+    {
+        public IActionResult Index()
+        {
+            return View();
+        }
+
+        public IActionResult About()
+        {
+            ViewData["Message"] = "Your application description page.";
+
+            return View();
+        }
+
+        public IActionResult Contact()
+        {
+            ViewData["Message"] = "Your contact page.";
+
+            return View();
+        }
+
+        public IActionResult Error()
+        {
+            return View();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/ManageController.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/ManageController.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/ManageController.cs
new file mode 100644
index 0000000..8d04fe5
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Controllers/ManageController.cs
@@ -0,0 +1,347 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using WebApplication.Models;
+using WebApplication.Models.ManageViewModels;
+using WebApplication.Services;
+
+namespace WebApplication.Controllers
+{
+    [Authorize]
+    public class ManageController : Controller
+    {
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly IEmailSender _emailSender;
+        private readonly ISmsSender _smsSender;
+        private readonly ILogger _logger;
+
+        public ManageController(
+        UserManager<ApplicationUser> userManager,
+        SignInManager<ApplicationUser> signInManager,
+        IEmailSender emailSender,
+        ISmsSender smsSender,
+        ILoggerFactory loggerFactory)
+        {
+            _userManager = userManager;
+            _signInManager = signInManager;
+            _emailSender = emailSender;
+            _smsSender = smsSender;
+            _logger = loggerFactory.CreateLogger<ManageController>();
+        }
+
+        //
+        // GET: /Manage/Index
+        [HttpGet]
+        public async Task<IActionResult> Index(ManageMessageId? message = null)
+        {
+            ViewData["StatusMessage"] =
+                message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
+                : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
+                : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
+                : message == ManageMessageId.Error ? "An error has occurred."
+                : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
+                : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
+                : "";
+
+            var user = await GetCurrentUserAsync();
+            var model = new IndexViewModel
+            {
+                HasPassword = await _userManager.HasPasswordAsync(user),
+                PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
+                TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
+                Logins = await _userManager.GetLoginsAsync(user),
+                BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user)
+            };
+            return View(model);
+        }
+
+        //
+        // POST: /Manage/RemoveLogin
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
+        {
+            ManageMessageId? message = ManageMessageId.Error;
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
+                if (result.Succeeded)
+                {
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    message = ManageMessageId.RemoveLoginSuccess;
+                }
+            }
+            return RedirectToAction(nameof(ManageLogins), new { Message = message });
+        }
+
+        //
+        // GET: /Manage/AddPhoneNumber
+        public IActionResult AddPhoneNumber()
+        {
+            return View();
+        }
+
+        //
+        // POST: /Manage/AddPhoneNumber
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+            // Generate the token and send it
+            var user = await GetCurrentUserAsync();
+            var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
+            await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
+            return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
+        }
+
+        //
+        // POST: /Manage/EnableTwoFactorAuthentication
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> EnableTwoFactorAuthentication()
+        {
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                await _userManager.SetTwoFactorEnabledAsync(user, true);
+                await _signInManager.SignInAsync(user, isPersistent: false);
+                _logger.LogInformation(1, "User enabled two-factor authentication.");
+            }
+            return RedirectToAction(nameof(Index), "Manage");
+        }
+
+        //
+        // POST: /Manage/DisableTwoFactorAuthentication
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> DisableTwoFactorAuthentication()
+        {
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                await _userManager.SetTwoFactorEnabledAsync(user, false);
+                await _signInManager.SignInAsync(user, isPersistent: false);
+                _logger.LogInformation(2, "User disabled two-factor authentication.");
+            }
+            return RedirectToAction(nameof(Index), "Manage");
+        }
+
+        //
+        // GET: /Manage/VerifyPhoneNumber
+        [HttpGet]
+        public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
+        {
+            var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
+            // Send an SMS to verify the phone number
+            return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
+        }
+
+        //
+        // POST: /Manage/VerifyPhoneNumber
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
+                if (result.Succeeded)
+                {
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
+                }
+            }
+            // If we got this far, something failed, redisplay the form
+            ModelState.AddModelError(string.Empty, "Failed to verify phone number");
+            return View(model);
+        }
+
+        //
+        // POST: /Manage/RemovePhoneNumber
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> RemovePhoneNumber()
+        {
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                var result = await _userManager.SetPhoneNumberAsync(user, null);
+                if (result.Succeeded)
+                {
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
+                }
+            }
+            return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+        }
+
+        //
+        // GET: /Manage/ChangePassword
+        [HttpGet]
+        public IActionResult ChangePassword()
+        {
+            return View();
+        }
+
+        //
+        // POST: /Manage/ChangePassword
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
+                if (result.Succeeded)
+                {
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    _logger.LogInformation(3, "User changed their password successfully.");
+                    return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
+                }
+                AddErrors(result);
+                return View(model);
+            }
+            return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+        }
+
+        //
+        // GET: /Manage/SetPassword
+        [HttpGet]
+        public IActionResult SetPassword()
+        {
+            return View();
+        }
+
+        //
+        // POST: /Manage/SetPassword
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return View(model);
+            }
+
+            var user = await GetCurrentUserAsync();
+            if (user != null)
+            {
+                var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
+                if (result.Succeeded)
+                {
+                    await _signInManager.SignInAsync(user, isPersistent: false);
+                    return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
+                }
+                AddErrors(result);
+                return View(model);
+            }
+            return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+        }
+
+        //GET: /Manage/ManageLogins
+        [HttpGet]
+        public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
+        {
+            ViewData["StatusMessage"] =
+                message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
+                : message == ManageMessageId.AddLoginSuccess ? "The external login was added."
+                : message == ManageMessageId.Error ? "An error has occurred."
+                : "";
+            var user = await GetCurrentUserAsync();
+            if (user == null)
+            {
+                return View("Error");
+            }
+            var userLogins = await _userManager.GetLoginsAsync(user);
+            var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
+            ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
+            return View(new ManageLoginsViewModel
+            {
+                CurrentLogins = userLogins,
+                OtherLogins = otherLogins
+            });
+        }
+
+        //
+        // POST: /Manage/LinkLogin
+        [HttpPost]
+        [ValidateAntiForgeryToken]
+        public IActionResult LinkLogin(string provider)
+        {
+            // Request a redirect to the external login provider to link a login for the current user
+            var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
+            var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
+            return Challenge(properties, provider);
+        }
+
+        //
+        // GET: /Manage/LinkLoginCallback
+        [HttpGet]
+        public async Task<ActionResult> LinkLoginCallback()
+        {
+            var user = await GetCurrentUserAsync();
+            if (user == null)
+            {
+                return View("Error");
+            }
+            var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
+            if (info == null)
+            {
+                return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
+            }
+            var result = await _userManager.AddLoginAsync(user, info);
+            var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
+            return RedirectToAction(nameof(ManageLogins), new { Message = message });
+        }
+
+        #region Helpers
+
+        private void AddErrors(IdentityResult result)
+        {
+            foreach (var error in result.Errors)
+            {
+                ModelState.AddModelError(string.Empty, error.Description);
+            }
+        }
+
+        public enum ManageMessageId
+        {
+            AddPhoneSuccess,
+            AddLoginSuccess,
+            ChangePasswordSuccess,
+            SetTwoFactorSuccess,
+            SetPasswordSuccess,
+            RemoveLoginSuccess,
+            RemovePhoneSuccess,
+            Error
+        }
+
+        private Task<ApplicationUser> GetCurrentUserAsync()
+        {
+            return _userManager.GetUserAsync(HttpContext.User);
+        }
+
+        #endregion
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/ApplicationDbContext.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/ApplicationDbContext.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/ApplicationDbContext.cs
new file mode 100644
index 0000000..336e6d4
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/ApplicationDbContext.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using WebApplication.Models;
+
+namespace WebApplication.Data
+{
+    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
+    {
+        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
+            : base(options)
+        {
+        }
+
+        protected override void OnModelCreating(ModelBuilder builder)
+        {
+            base.OnModelCreating(builder);
+            // Customize the ASP.NET Identity model and override the defaults if needed.
+            // For example, you can rename the ASP.NET Identity table names and more.
+            // Add your customizations after calling base.OnModelCreating(builder);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs
new file mode 100644
index 0000000..bb12d2b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs
@@ -0,0 +1,212 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using WebApplication.Data;
+
+namespace WebApplication.Data.Migrations
+{
+    [DbContext(typeof(ApplicationDbContext))]
+    [Migration("00000000000000_CreateIdentitySchema")]
+    partial class CreateIdentitySchema
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+            modelBuilder
+                 .HasAnnotation("ProductVersion", "1.0.0-rc2-20901");
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b =>
+                {
+                    b.Property<string>("Id");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Name")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("NormalizedName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedName")
+                        .HasName("RoleNameIndex");
+
+                    b.ToTable("AspNetRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("RoleId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetRoleClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("ProviderKey");
+
+                    b.Property<string>("ProviderDisplayName");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("LoginProvider", "ProviderKey");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserLogins");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("RoleId");
+
+                    b.HasKey("UserId", "RoleId");
+
+                    b.HasIndex("RoleId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("Name");
+
+                    b.Property<string>("Value");
+
+                    b.HasKey("UserId", "LoginProvider", "Name");
+
+                    b.ToTable("AspNetUserTokens");
+                });
+
+            modelBuilder.Entity("WebApplication.Models.ApplicationUser", b =>
+                {
+                    b.Property<string>("Id");
+
+                    b.Property<int>("AccessFailedCount");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Email")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<bool>("EmailConfirmed");
+
+                    b.Property<bool>("LockoutEnabled");
+
+                    b.Property<DateTimeOffset?>("LockoutEnd");
+
+                    b.Property<string>("NormalizedEmail")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("NormalizedUserName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("PasswordHash");
+
+                    b.Property<string>("PhoneNumber");
+
+                    b.Property<bool>("PhoneNumberConfirmed");
+
+                    b.Property<string>("SecurityStamp");
+
+                    b.Property<bool>("TwoFactorEnabled");
+
+                    b.Property<string>("UserName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedEmail")
+                        .HasName("EmailIndex");
+
+                    b.HasIndex("NormalizedUserName")
+                        .HasName("UserNameIndex");
+
+                    b.ToTable("AspNetUsers");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.cs
new file mode 100644
index 0000000..e6f038f
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/00000000000000_CreateIdentitySchema.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace WebApplication.Data.Migrations
+{
+    public partial class CreateIdentitySchema : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "AspNetRoles",
+                columns: table => new
+                {
+                    Id = table.Column<string>(nullable: false),
+                    ConcurrencyStamp = table.Column<string>(nullable: true),
+                    Name = table.Column<string>(nullable: true),
+                    NormalizedName = table.Column<string>(nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetUserTokens",
+                columns: table => new
+                {
+                    UserId = table.Column<string>(nullable: false),
+                    LoginProvider = table.Column<string>(nullable: false),
+                    Name = table.Column<string>(nullable: false),
+                    Value = table.Column<string>(nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetUsers",
+                columns: table => new
+                {
+                    Id = table.Column<string>(nullable: false),
+                    AccessFailedCount = table.Column<int>(nullable: false),
+                    ConcurrencyStamp = table.Column<string>(nullable: true),
+                    Email = table.Column<string>(nullable: true),
+                    EmailConfirmed = table.Column<bool>(nullable: false),
+                    LockoutEnabled = table.Column<bool>(nullable: false),
+                    LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
+                    NormalizedEmail = table.Column<string>(nullable: true),
+                    NormalizedUserName = table.Column<string>(nullable: true),
+                    PasswordHash = table.Column<string>(nullable: true),
+                    PhoneNumber = table.Column<string>(nullable: true),
+                    PhoneNumberConfirmed = table.Column<bool>(nullable: false),
+                    SecurityStamp = table.Column<string>(nullable: true),
+                    TwoFactorEnabled = table.Column<bool>(nullable: false),
+                    UserName = table.Column<string>(nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUsers", x => x.Id);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetRoleClaims",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Autoincrement", true),
+                    ClaimType = table.Column<string>(nullable: true),
+                    ClaimValue = table.Column<string>(nullable: true),
+                    RoleId = table.Column<string>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
+                        column: x => x.RoleId,
+                        principalTable: "AspNetRoles",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetUserClaims",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Autoincrement", true),
+                    ClaimType = table.Column<string>(nullable: true),
+                    ClaimValue = table.Column<string>(nullable: true),
+                    UserId = table.Column<string>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_AspNetUserClaims_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetUserLogins",
+                columns: table => new
+                {
+                    LoginProvider = table.Column<string>(nullable: false),
+                    ProviderKey = table.Column<string>(nullable: false),
+                    ProviderDisplayName = table.Column<string>(nullable: true),
+                    UserId = table.Column<string>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+                    table.ForeignKey(
+                        name: "FK_AspNetUserLogins_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "AspNetUserRoles",
+                columns: table => new
+                {
+                    UserId = table.Column<string>(nullable: false),
+                    RoleId = table.Column<string>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
+                    table.ForeignKey(
+                        name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
+                        column: x => x.RoleId,
+                        principalTable: "AspNetRoles",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                    table.ForeignKey(
+                        name: "FK_AspNetUserRoles_AspNetUsers_UserId",
+                        column: x => x.UserId,
+                        principalTable: "AspNetUsers",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "RoleNameIndex",
+                table: "AspNetRoles",
+                column: "NormalizedName");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetRoleClaims_RoleId",
+                table: "AspNetRoleClaims",
+                column: "RoleId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserClaims_UserId",
+                table: "AspNetUserClaims",
+                column: "UserId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserLogins_UserId",
+                table: "AspNetUserLogins",
+                column: "UserId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserRoles_RoleId",
+                table: "AspNetUserRoles",
+                column: "RoleId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_AspNetUserRoles_UserId",
+                table: "AspNetUserRoles",
+                column: "UserId");
+
+            migrationBuilder.CreateIndex(
+                name: "EmailIndex",
+                table: "AspNetUsers",
+                column: "NormalizedEmail");
+
+            migrationBuilder.CreateIndex(
+                name: "UserNameIndex",
+                table: "AspNetUsers",
+                column: "NormalizedUserName");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "AspNetRoleClaims");
+
+            migrationBuilder.DropTable(
+                name: "AspNetUserClaims");
+
+            migrationBuilder.DropTable(
+                name: "AspNetUserLogins");
+
+            migrationBuilder.DropTable(
+                name: "AspNetUserRoles");
+
+            migrationBuilder.DropTable(
+                name: "AspNetUserTokens");
+
+            migrationBuilder.DropTable(
+                name: "AspNetRoles");
+
+            migrationBuilder.DropTable(
+                name: "AspNetUsers");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/ApplicationDbContextModelSnapshot.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/ApplicationDbContextModelSnapshot.cs
new file mode 100644
index 0000000..cb45931
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Data/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -0,0 +1,211 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using WebApplication.Data;
+
+namespace WebApplication.Data.Migrations
+{
+    [DbContext(typeof(ApplicationDbContext))]
+    partial class ApplicationDbContextModelSnapshot : ModelSnapshot
+    {
+        protected override void BuildModel(ModelBuilder modelBuilder)
+        {
+            modelBuilder
+                .HasAnnotation("ProductVersion", "1.0.0-rc2-20901");
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b =>
+                {
+                    b.Property<string>("Id");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Name")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("NormalizedName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedName")
+                        .HasName("RoleNameIndex");
+
+                    b.ToTable("AspNetRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("RoleId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("RoleId");
+
+                    b.ToTable("AspNetRoleClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("ClaimType");
+
+                    b.Property<string>("ClaimValue");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserClaims");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
+                {
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("ProviderKey");
+
+                    b.Property<string>("ProviderDisplayName");
+
+                    b.Property<string>("UserId")
+                        .IsRequired();
+
+                    b.HasKey("LoginProvider", "ProviderKey");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserLogins");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("RoleId");
+
+                    b.HasKey("UserId", "RoleId");
+
+                    b.HasIndex("RoleId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("AspNetUserRoles");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken<string>", b =>
+                {
+                    b.Property<string>("UserId");
+
+                    b.Property<string>("LoginProvider");
+
+                    b.Property<string>("Name");
+
+                    b.Property<string>("Value");
+
+                    b.HasKey("UserId", "LoginProvider", "Name");
+
+                    b.ToTable("AspNetUserTokens");
+                });
+
+            modelBuilder.Entity("WebApplication.Models.ApplicationUser", b =>
+                {
+                    b.Property<string>("Id");
+
+                    b.Property<int>("AccessFailedCount");
+
+                    b.Property<string>("ConcurrencyStamp")
+                        .IsConcurrencyToken();
+
+                    b.Property<string>("Email")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<bool>("EmailConfirmed");
+
+                    b.Property<bool>("LockoutEnabled");
+
+                    b.Property<DateTimeOffset?>("LockoutEnd");
+
+                    b.Property<string>("NormalizedEmail")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("NormalizedUserName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.Property<string>("PasswordHash");
+
+                    b.Property<string>("PhoneNumber");
+
+                    b.Property<bool>("PhoneNumberConfirmed");
+
+                    b.Property<string>("SecurityStamp");
+
+                    b.Property<bool>("TwoFactorEnabled");
+
+                    b.Property<string>("UserName")
+                        .HasAnnotation("MaxLength", 256);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("NormalizedEmail")
+                        .HasName("EmailIndex");
+
+                    b.HasIndex("NormalizedUserName")
+                        .HasName("UserNameIndex");
+
+                    b.ToTable("AspNetUsers");
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim<string>", b =>
+                {
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin<string>", b =>
+                {
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole<string>", b =>
+                {
+                    b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+                        .WithMany()
+                        .HasForeignKey("RoleId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("WebApplication.Models.ApplicationUser")
+                        .WithMany()
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
new file mode 100644
index 0000000..a60894c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class ExternalLoginConfirmationViewModel
+    {
+        [Required]
+        [EmailAddress]
+        public string Email { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ForgotPasswordViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ForgotPasswordViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ForgotPasswordViewModel.cs
new file mode 100644
index 0000000..70fab0c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ForgotPasswordViewModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class ForgotPasswordViewModel
+    {
+        [Required]
+        [EmailAddress]
+        public string Email { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/LoginViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/LoginViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/LoginViewModel.cs
new file mode 100644
index 0000000..7dc974b
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/LoginViewModel.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class LoginViewModel
+    {
+        [Required]
+        [EmailAddress]
+        public string Email { get; set; }
+
+        [Required]
+        [DataType(DataType.Password)]
+        public string Password { get; set; }
+
+        [Display(Name = "Remember me?")]
+        public bool RememberMe { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/RegisterViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/RegisterViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/RegisterViewModel.cs
new file mode 100644
index 0000000..bc86f2a
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/RegisterViewModel.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class RegisterViewModel
+    {
+        [Required]
+        [EmailAddress]
+        [Display(Name = "Email")]
+        public string Email { get; set; }
+
+        [Required]
+        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+        [DataType(DataType.Password)]
+        [Display(Name = "Password")]
+        public string Password { get; set; }
+
+        [DataType(DataType.Password)]
+        [Display(Name = "Confirm password")]
+        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+        public string ConfirmPassword { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ResetPasswordViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ResetPasswordViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ResetPasswordViewModel.cs
new file mode 100644
index 0000000..43198b7
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/ResetPasswordViewModel.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class ResetPasswordViewModel
+    {
+        [Required]
+        [EmailAddress]
+        public string Email { get; set; }
+
+        [Required]
+        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+        [DataType(DataType.Password)]
+        public string Password { get; set; }
+
+        [DataType(DataType.Password)]
+        [Display(Name = "Confirm password")]
+        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+        public string ConfirmPassword { get; set; }
+
+        public string Code { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/SendCodeViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/SendCodeViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/SendCodeViewModel.cs
new file mode 100644
index 0000000..b8ed8f1
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/SendCodeViewModel.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Rendering;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class SendCodeViewModel
+    {
+        public string SelectedProvider { get; set; }
+
+        public ICollection<SelectListItem> Providers { get; set; }
+
+        public string ReturnUrl { get; set; }
+
+        public bool RememberMe { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/VerifyCodeViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/VerifyCodeViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/VerifyCodeViewModel.cs
new file mode 100644
index 0000000..394db8c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/AccountViewModels/VerifyCodeViewModel.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.AccountViewModels
+{
+    public class VerifyCodeViewModel
+    {
+        [Required]
+        public string Provider { get; set; }
+
+        [Required]
+        public string Code { get; set; }
+
+        public string ReturnUrl { get; set; }
+
+        [Display(Name = "Remember this browser?")]
+        public bool RememberBrowser { get; set; }
+
+        [Display(Name = "Remember me?")]
+        public bool RememberMe { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ApplicationUser.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ApplicationUser.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ApplicationUser.cs
new file mode 100644
index 0000000..4642ef2
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ApplicationUser.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+
+namespace WebApplication.Models
+{
+    // Add profile data for application users by adding properties to the ApplicationUser class
+    public class ApplicationUser : IdentityUser
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/AddPhoneNumberViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/AddPhoneNumberViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/AddPhoneNumberViewModel.cs
new file mode 100644
index 0000000..d2baaf7
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/AddPhoneNumberViewModel.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class AddPhoneNumberViewModel
+    {
+        [Required]
+        [Phone]
+        [Display(Name = "Phone number")]
+        public string PhoneNumber { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ChangePasswordViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ChangePasswordViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ChangePasswordViewModel.cs
new file mode 100644
index 0000000..421b91a
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ChangePasswordViewModel.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class ChangePasswordViewModel
+    {
+        [Required]
+        [DataType(DataType.Password)]
+        [Display(Name = "Current password")]
+        public string OldPassword { get; set; }
+
+        [Required]
+        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+        [DataType(DataType.Password)]
+        [Display(Name = "New password")]
+        public string NewPassword { get; set; }
+
+        [DataType(DataType.Password)]
+        [Display(Name = "Confirm new password")]
+        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
+        public string ConfirmPassword { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
new file mode 100644
index 0000000..beb1fd1
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Rendering;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class ConfigureTwoFactorViewModel
+    {
+        public string SelectedProvider { get; set; }
+
+        public ICollection<SelectListItem> Providers { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/FactorViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/FactorViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/FactorViewModel.cs
new file mode 100644
index 0000000..b2d4f9e
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/FactorViewModel.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class FactorViewModel
+    {
+        public string Purpose { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/IndexViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/IndexViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/IndexViewModel.cs
new file mode 100644
index 0000000..e0b69f2
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/IndexViewModel.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class IndexViewModel
+    {
+        public bool HasPassword { get; set; }
+
+        public IList<UserLoginInfo> Logins { get; set; }
+
+        public string PhoneNumber { get; set; }
+
+        public bool TwoFactor { get; set; }
+
+        public bool BrowserRemembered { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/5e667994/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ManageLoginsViewModel.cs
----------------------------------------------------------------------
diff --git a/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ManageLoginsViewModel.cs b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ManageLoginsViewModel.cs
new file mode 100644
index 0000000..fc03a0c
--- /dev/null
+++ b/extensions/log4net.Extensions.Logging/log4net.Extensions.Logging.Test/Models/ManageViewModels/ManageLoginsViewModel.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.AspNetCore.Identity;
+
+namespace WebApplication.Models.ManageViewModels
+{
+    public class ManageLoginsViewModel
+    {
+        public IList<UserLoginInfo> CurrentLogins { get; set; }
+
+        public IList<AuthenticationDescription> OtherLogins { get; set; }
+    }
+}