diff --git a/src/Appender/AdoNetAppender.cs b/src/Appender/AdoNetAppender.cs
index c9600f2..2f4f27e 100644
--- a/src/Appender/AdoNetAppender.cs
+++ b/src/Appender/AdoNetAppender.cs
@@ -17,9 +17,6 @@
 //
 #endregion
 
-// SSCLI 1.0 has no support for ADO.NET
-#if !SSCLI
-
 using System;
 using System.Collections;
 using System.Configuration;
@@ -1253,5 +1250,3 @@ virtual public void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
 		#endregion // Private Instance Fields
 	}
 }
-
-#endif // !SSCLI
\ No newline at end of file
diff --git a/src/Appender/AnsiColorTerminalAppender.cs b/src/Appender/AnsiColorTerminalAppender.cs
index 3ad375f..58013d8 100644
--- a/src/Appender/AnsiColorTerminalAppender.cs
+++ b/src/Appender/AnsiColorTerminalAppender.cs
@@ -339,10 +339,6 @@ override protected void Append(log4net.Core.LoggingEvent loggingEvent)
 				}
 			}
 
-#if NETCF_1_0
-			// Write to the output stream
-			Console.Write(loggingMessage);
-#else
 			if (m_writeToErrorStream)
 			{
 				// Write to the error stream
@@ -353,7 +349,6 @@ override protected void Append(log4net.Core.LoggingEvent loggingEvent)
 				// Write to the output stream
 				Console.Write(loggingMessage);
 			}
-#endif
 		
 		}
 
diff --git a/src/Appender/AppenderSkeleton.cs b/src/Appender/AppenderSkeleton.cs
index bc11683..c04a761 100644
--- a/src/Appender/AppenderSkeleton.cs
+++ b/src/Appender/AppenderSkeleton.cs
@@ -321,7 +321,7 @@ public void DoAppend(LoggingEvent loggingEvent)
 				{
 					ErrorHandler.Error("Failed in DoAppend", ex);
 				}
-#if !MONO && !NET_2_0
+#if NETCF
 				// on .NET 2.0 (and higher) and Mono (all profiles), 
 				// exceptions that do not derive from System.Exception will be
 				// wrapped in a RuntimeWrappedException by the runtime, and as
@@ -428,7 +428,7 @@ public void DoAppend(LoggingEvent[] loggingEvents)
 				{
 					ErrorHandler.Error("Failed in Bulk DoAppend", ex);
 				}
-#if !MONO && !NET_2_0
+#if NETCF
 				// on .NET 2.0 (and higher) and Mono (all profiles), 
 				// exceptions that do not derive from System.Exception will be
 				// wrapped in a RuntimeWrappedException by the runtime, and as
diff --git a/src/Appender/AspNetTraceAppender.cs b/src/Appender/AspNetTraceAppender.cs
index 82f9569..08a49a7 100644
--- a/src/Appender/AspNetTraceAppender.cs
+++ b/src/Appender/AspNetTraceAppender.cs
@@ -17,9 +17,7 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+#if !NETCF && !CLIENT_PROFILE
 
 using System.Web;
 
@@ -152,4 +150,4 @@ public PatternLayout Category
 	}
 }
 
-#endif // !NETCF && !SSCLI
+#endif // !NETCF
diff --git a/src/Appender/ColoredConsoleAppender.cs b/src/Appender/ColoredConsoleAppender.cs
index 0fe2d70..332d1c7 100644
--- a/src/Appender/ColoredConsoleAppender.cs
+++ b/src/Appender/ColoredConsoleAppender.cs
@@ -17,16 +17,8 @@
 //
 #endregion
 
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for Win32 Console API's
+// .NET Compact Framework has no support for Win32 Console API's
 #if !NETCF 
-// .Mono 1.0 has no support for Win32 Console API's
-#if !MONO 
-// SSCLI 1.0 has no support for Win32 Console API's
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
 
 using System;
 using System.Globalization;
@@ -660,7 +652,4 @@ internal ushort CombinedColor
 	}
 }
 
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
 #endif // !NETCF
diff --git a/src/Appender/ConsoleAppender.cs b/src/Appender/ConsoleAppender.cs
index 84ad172..5baf676 100644
--- a/src/Appender/ConsoleAppender.cs
+++ b/src/Appender/ConsoleAppender.cs
@@ -150,10 +150,6 @@ virtual public string Target
 		/// </remarks>
 		override protected void Append(LoggingEvent loggingEvent) 
 		{
-#if NETCF_1_0
-			// Write to the output stream
-			Console.Write(RenderLoggingEvent(loggingEvent));
-#else
 			if (m_writeToErrorStream)
 			{
 				// Write to the error stream
@@ -164,7 +160,6 @@ override protected void Append(LoggingEvent loggingEvent)
 				// Write to the output stream
 				Console.Write(RenderLoggingEvent(loggingEvent));
 			}
-#endif
 		}
 
 		/// <summary>
diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs
index 9cc031e..4ac3811 100644
--- a/src/Appender/EventLogAppender.cs
+++ b/src/Appender/EventLogAppender.cs
@@ -17,12 +17,7 @@
 //
 #endregion
 
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for EventLog
 #if !NETCF 
-// SSCLI 1.0 has no support for EventLog
-#if !SSCLI
 
 using System;
 using System.Diagnostics;
@@ -686,5 +681,4 @@ private static int GetMaxEventLogMessageSize()
 	}
 }
 
-#endif // !SSCLI
 #endif // !NETCF
diff --git a/src/Appender/LocalSyslogAppender.cs b/src/Appender/LocalSyslogAppender.cs
index 2a4ceb9..4ca4c21 100644
--- a/src/Appender/LocalSyslogAppender.cs
+++ b/src/Appender/LocalSyslogAppender.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for Marshal.StringToHGlobalAnsi
-// SSCLI 1.0 has no support for Marshal.StringToHGlobalAnsi
-#if !NETCF && !SSCLI
+// .NET Compact Framework has no support for Marshal.StringToHGlobalAnsi
+#if !NETCF
 
 using System;
 using System.Runtime.InteropServices;
diff --git a/src/Appender/ManagedColoredConsoleAppender.cs b/src/Appender/ManagedColoredConsoleAppender.cs
index a1a06ac..60b64b6 100644
--- a/src/Appender/ManagedColoredConsoleAppender.cs
+++ b/src/Appender/ManagedColoredConsoleAppender.cs
@@ -21,11 +21,6 @@
 //	http://msdn.microsoft.com/en-us/library/system.console.foregroundcolor.aspx
 // Disable for unsupported targets
 #if !NETCF 
-#if !SSCLI
-#if !CLI_1_0
-#if !MONO_1_0
-#if !NET_1_0
-#if !NET_1_1
 
 // The original ColoredConsoleAppender was written before the .NET framework
 // (and Mono) had built-in support for console colors so it was written using
@@ -340,9 +335,4 @@ public ConsoleColor BackColor
 	}
 }
 
-#endif
-#endif
-#endif // !MONO_1_0
-#endif // !CLI_1_0
-#endif // !SSCLI
 #endif // !NETCF
diff --git a/src/Appender/NetSendAppender.cs b/src/Appender/NetSendAppender.cs
index d221a6e..b4e0d8d 100644
--- a/src/Appender/NetSendAppender.cs
+++ b/src/Appender/NetSendAppender.cs
@@ -17,16 +17,8 @@
 //
 #endregion
 
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for Win32 NetMessageBufferSend API
+// .NET Compact Framework has no support for Win32 NetMessageBufferSend API
 #if !NETCF 
-// MONO 1.0 has no support for Win32 NetMessageBufferSend API
-#if !MONO 
-// SSCLI 1.0 has no support for Win32 NetMessageBufferSend API
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
 
 using System;
 using System.Globalization;
@@ -419,7 +411,4 @@ override protected bool RequiresLayout
 	}
 }
 
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
 #endif // !NETCF
\ No newline at end of file
diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs
index 326e5d3..64fb387 100644
--- a/src/Appender/OutputDebugStringAppender.cs
+++ b/src/Appender/OutputDebugStringAppender.cs
@@ -17,13 +17,6 @@
 //
 #endregion
 
-// MONO 1.0 has no support for Win32 OutputDebugString API
-#if !MONO
-// SSCLI 1.0 has no support for Win32 OutputDebugString API
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
-
 using System.Runtime.InteropServices;
 
 using log4net.Layout;
@@ -122,7 +115,3 @@ override protected bool RequiresLayout
 		#endregion // Protected Static Methods
 	}
 }
-
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs
index c1b7705..3044fc1 100644
--- a/src/Appender/RollingFileAppender.cs
+++ b/src/Appender/RollingFileAppender.cs
@@ -239,7 +239,7 @@ public RollingFileAppender()
 
 		#region Public Instance Properties
 
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
         /// <summary>
 		/// Gets or sets the strategy for determining the current date and time. The default
 		/// implementation is to use LocalDateTime which internally calls through to DateTime.Now. 
@@ -796,7 +796,7 @@ private void RollOverIfDateBoundaryCrossing()
 				{
 					DateTime last;
 					using(SecurityContext.Impersonate(this)) {
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
                         if (DateTimeStrategy is UniversalDateTime)
 						{
 							last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName);
@@ -805,7 +805,7 @@ private void RollOverIfDateBoundaryCrossing()
 						{
 #endif
 							last = System.IO.File.GetLastWriteTime(m_baseFileName);
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
                         }
 #endif
                     }
@@ -1699,7 +1699,7 @@ public DateTime Now
 			}
 		}
 
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
         /// <summary>
 		/// Implementation of <see cref="IDateTime"/> that returns the current time as the coordinated universal time (UTC).
 		/// </summary>
diff --git a/src/Appender/SmtpAppender.cs b/src/Appender/SmtpAppender.cs
index e1749a2..d29b7cc 100644
--- a/src/Appender/SmtpAppender.cs
+++ b/src/Appender/SmtpAppender.cs
@@ -17,19 +17,14 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for System.Web.Mail
-// SSCLI 1.0 has no support for System.Web.Mail
-#if !NETCF && !SSCLI
+// .NET Compact Framework has no support for System.Web.Mail
+#if !NETCF
 
 using System;
 using System.IO;
 using System.Text;
 
-#if NET_2_0
 using System.Net.Mail;
-#else
-using System.Web.Mail;
-#endif
 
 using log4net.Layout;
 using log4net.Core;
@@ -324,7 +319,6 @@ public MailPriority Priority
 			set { m_mailPriority = value; }
 		}
 
-#if NET_2_0
         /// <summary>
         /// Enable or disable use of SSL when sending e-mail message
         /// </summary>
@@ -348,7 +342,6 @@ public string ReplyTo
             get { return m_replyTo; }
             set { m_replyTo = value; }
         }
-#endif
 
 		/// <summary>
 		/// Gets or sets the subject encoding to be used.
@@ -444,7 +437,6 @@ override protected bool RequiresLayout
 		/// <param name="messageBody">the body text to include in the mail</param>
 		virtual protected void SendEmail(string messageBody)
 		{
-#if NET_2_0
 			// .NET 2.0 has a new API for SMTP email System.Net.Mail
 			// This API supports credentials and multiple hosts correctly.
 			// The old API is deprecated.
@@ -502,83 +494,6 @@ virtual protected void SendEmail(string messageBody)
                 // behaviour compared to .NET 1.x. We would need a SendCompletedCallback to log errors.
                 smtpClient.Send(mailMessage);
             }
-#else
-				// .NET 1.x uses the System.Web.Mail API for sending Mail
-
-				MailMessage mailMessage = new MailMessage();
-				mailMessage.Body = messageBody;
-				mailMessage.BodyEncoding = m_bodyEncoding;
-				mailMessage.From = m_from;
-				mailMessage.To = m_to;
-                if (m_cc != null && m_cc.Length > 0)
-                {
-                    mailMessage.Cc = m_cc;
-                }
-                if (m_bcc != null && m_bcc.Length > 0)
-                {
-                    mailMessage.Bcc = m_bcc;
-                }
-				mailMessage.Subject = m_subject;
-#if !MONO && !NET_1_0 && !NET_1_1 && !CLI_1_0
-				mailMessage.SubjectEncoding = m_subjectEncoding;
-#endif
-				mailMessage.Priority = m_mailPriority;
-
-#if NET_1_1
-				// The Fields property on the MailMessage allows the CDO properties to be set directly.
-				// This property is only available on .NET Framework 1.1 and the implementation must understand
-				// the CDO properties. For details of the fields available in CDO see:
-				//
-				// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_configuration_coclass.asp
-				// 
-
-				try
-				{
-					if (m_authentication == SmtpAuthentication.Basic)
-					{
-						// Perform basic authentication
-						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
-						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", m_username);
-						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", m_password);
-					}
-					else if (m_authentication == SmtpAuthentication.Ntlm)
-					{
-						// Perform integrated authentication (NTLM)
-						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 2);
-					}
-
-					// Set the port if not the default value
-					if (m_port != 25) 
-					{
-						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", m_port);
-					}
-				}
-				catch(MissingMethodException missingMethodException)
-				{
-					// If we were compiled against .NET 1.1 but are running against .NET 1.0 then
-					// we will get a MissingMethodException when accessing the MailMessage.Fields property.
-
-					ErrorHandler.Error("SmtpAppender: Authentication and server Port are only supported when running on the MS .NET 1.1 framework", missingMethodException);
-				}
-#else
-				if (m_authentication != SmtpAuthentication.None)
-				{
-					ErrorHandler.Error("SmtpAppender: Authentication is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
-				}
-
-				if (m_port != 25)
-				{
-					ErrorHandler.Error("SmtpAppender: Server Port is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
-				}
-#endif // if NET_1_1
-
-				if (m_smtpHost != null && m_smtpHost.Length > 0)
-				{
-					SmtpMail.SmtpServer = m_smtpHost;
-				}
-
-				SmtpMail.Send(mailMessage);
-#endif // if NET_2_0
 		}
 
 		#endregion // Protected Methods
@@ -604,10 +519,8 @@ virtual protected void SendEmail(string messageBody)
 
 		private MailPriority m_mailPriority = MailPriority.Normal;
 
-#if NET_2_0
         private bool m_enableSsl = false;
         private string m_replyTo;
-#endif
 
 		#endregion // Private Instance Fields
 
@@ -649,4 +562,4 @@ public enum SmtpAuthentication
 	}
 }
 
-#endif // !NETCF && !SSCLI
+#endif // !NETCF
diff --git a/src/Appender/UdpAppender.cs b/src/Appender/UdpAppender.cs
index ce5342b..158a9e1 100644
--- a/src/Appender/UdpAppender.cs
+++ b/src/Appender/UdpAppender.cs
@@ -474,7 +474,7 @@ protected virtual void InitializeClientConnection()
 			{
 				if (this.LocalPort == 0)
 				{
-#if NETCF || NET_1_0 || SSCLI_1_0 || CLI_1_0
+#if NETCF
 					this.Client = new UdpClient();
 #else
 					this.Client = new UdpClient(RemoteAddress.AddressFamily);
@@ -482,7 +482,7 @@ protected virtual void InitializeClientConnection()
 				}
 				else
 				{
-#if NETCF || NET_1_0 || SSCLI_1_0 || CLI_1_0
+#if NETCF
 					this.Client = new UdpClient(this.LocalPort);
 #else
 					this.Client = new UdpClient(this.LocalPort, RemoteAddress.AddressFamily);
diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs
index b387a84..6bd74e9 100644
--- a/src/AssemblyInfo.cs
+++ b/src/AssemblyInfo.cs
@@ -20,12 +20,7 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-#if (!SSCLI)
-//
-// log4net makes use of static methods which cannot be made com visible
-//
 [assembly: System.Runtime.InteropServices.ComVisible(false)]
-#endif
 
 //
 // log4net is CLS compliant
@@ -39,7 +34,7 @@
 [assembly: System.Security.AllowPartiallyTrustedCallers]
 #endif
 
-#if (NET_4_0)
+#if (FRAMEWORK_4_0_OR_ABOVE)
 //
 // Allows partial trust applications (e.g. ASP.NET shared hosting) on .NET 4.0 to work
 // given our implementation of ISerializable.
@@ -53,13 +48,9 @@
 // associated with an assembly.
 //
 
-#if (CLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for CLI 1.0 Compatible Frameworks")]
-#elif (NET_1_0)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.0")]
-#elif (NET_1_1)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.1")]
-#elif (NET_4_0)
+#if FRAMEWORK_4_5_OR_ABOVE
+[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.5")]
+#elif FRAMEWORK_4_0_OR_ABOVE
 #if CLIENT_PROFILE
 [assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0 Client Profile")]
 #else
@@ -71,26 +62,10 @@
 #else
 [assembly: AssemblyTitle("Apache log4net for .NET Framework 2.0")]
 #endif // Client Profile
-#elif (NETCF_1_0)
-[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 1.0")]
 #elif (NETCF_2_0)
 [assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 2.0")]
-#elif (MONO_1_0)
-[assembly: AssemblyTitle("Apache log4net for Mono 1.0")]
 #elif (MONO_2_0)
 [assembly: AssemblyTitle("Apache log4net for Mono 2.0")]
-#elif (SSCLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for Shared Source CLI 1.0")]
-#elif (CLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for CLI Compatible Frameworks")]
-#elif (NET)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework")]
-#elif (NETCF)
-[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework")]
-#elif (MONO)
-[assembly: AssemblyTitle("Apache log4net for Mono")]
-#elif (SSCLI)
-[assembly: AssemblyTitle("Apache log4net for Shared Source CLI")]
 #else
 [assembly: AssemblyTitle("Apache log4net")]
 #endif
@@ -105,35 +80,3 @@
 [assembly: AssemblyDefaultAlias("log4net")]
 [assembly: AssemblyCulture("")]		
 		
-//
-// In order to sign your assembly you must specify a key to use. Refer to the 
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing. 
-//
-// Notes: 
-//   (*) If no key is specified, the assembly is not signed.
-//   (*) KeyName refers to a key that has been installed in the Crypto Service
-//       Provider (CSP) on your machine. KeyFile refers to a file which contains
-//       a key.
-//   (*) If the KeyFile and the KeyName values are both specified, the 
-//       following processing occurs:
-//       (1) If the KeyName can be found in the CSP, that key is used.
-//       (2) If the KeyName does not exist and the KeyFile does exist, the key 
-//           in the KeyFile is installed into the CSP and used.
-//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-//       When specifying the KeyFile, the location of the KeyFile should be
-//       relative to the project output directory which is
-//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-//       located in the project directory, you would specify the AssemblyKeyFile 
-//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-//       documentation for more information on this.
-//
-#if STRONG && (CLI_1_0 || NET_1_0 || NET_1_1 || NETCF_1_0 || SSCLI)
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile(@"..\..\..\log4net.snk")]
-#endif
-// We do not use a CSP key for strong naming
-// [assembly: AssemblyKeyName("")]
-
diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs
index 56e0d06..906e645 100644
--- a/src/AssemblyVersionInfo.cs
+++ b/src/AssemblyVersionInfo.cs
@@ -28,13 +28,11 @@
 // You can specify all the values or you can default the Revision and Build Numbers 
 // by using the '*' as shown below:
 
-[assembly: System.Reflection.AssemblyVersion("1.2.13.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2")]
+[assembly: System.Reflection.AssemblyVersion("1.3.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.3")]
 
 #if !NETCF
-#if !SSCLI
-[assembly: System.Reflection.AssemblyFileVersion("1.2.13.0")]
-#endif
+[assembly: System.Reflection.AssemblyFileVersion("1.3.0.0")]
 #endif
 
 //
diff --git a/src/Config/DOMConfigurator.cs b/src/Config/DOMConfigurator.cs
index 54551af..72a5b68 100644
--- a/src/Config/DOMConfigurator.cs
+++ b/src/Config/DOMConfigurator.cs
@@ -287,7 +287,7 @@ static public void Configure(ILoggerRepository repository, Stream configStream)
 
 		#region ConfigureAndWatch static methods
 
-#if (!NETCF && !SSCLI)
+#if !NETCF
 
 		/// <summary>
 		/// Configures log4net using the file specified, monitors the file for changes 
diff --git a/src/Config/XmlConfigurator.cs b/src/Config/XmlConfigurator.cs
index 88621b0..084fdc2 100644
--- a/src/Config/XmlConfigurator.cs
+++ b/src/Config/XmlConfigurator.cs
@@ -639,7 +639,6 @@ static private void InternalConfigure(ILoggerRepository repository, Uri configUr
 
 					if (configRequest != null)
 					{
-#if !NETCF_1_0
 						// authentication may be required, set client to use default credentials
 						try
 						{
@@ -649,7 +648,7 @@ static private void InternalConfigure(ILoggerRepository repository, Uri configUr
 						{
 							// ignore security exception
 						}
-#endif
+
 						try
 						{
 							WebResponse response = configRequest.GetResponse();
@@ -785,7 +784,7 @@ static private void InternalConfigure(ILoggerRepository repository, Stream confi
 
 		#region ConfigureAndWatch static methods
 
-#if (!NETCF && !SSCLI)
+#if !NETCF
 
 		/// <summary>
 		/// Configures log4net using the file specified, monitors the file for changes 
@@ -906,7 +905,7 @@ static private void InternalConfigureAndWatch(ILoggerRepository repository, File
 
 		#region ConfigureAndWatchHandler
 
-#if (!NETCF && !SSCLI)
+#if !NETCF
 		/// <summary>
 		/// Class used to watch config files.
 		/// </summary>
diff --git a/src/Config/XmlConfiguratorAttribute.cs b/src/Config/XmlConfiguratorAttribute.cs
index 6c3ea3e..ec38967 100644
--- a/src/Config/XmlConfiguratorAttribute.cs
+++ b/src/Config/XmlConfiguratorAttribute.cs
@@ -168,9 +168,6 @@ public string ConfigFileExtension
 		/// from a web server the config file may not reside on the local disk
 		/// and therefore it may not be able to watch it.
 		/// </para>
-		/// <note>
-		/// Watching configuration is not supported on the SSCLI.
-		/// </note>
 		/// </remarks>
 		public bool Watch
 		{
@@ -313,13 +310,6 @@ private void ConfigureFromFile(Assembly sourceAssembly, ILoggerRepository target
 		/// <param name="configFile">the FileInfo pointing to the config file</param>
 		private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo configFile)
 		{
-#if (SSCLI)
-			if (m_configureAndWatch)
-			{
-				LogLog.Warn(declaringType, "XmlConfiguratorAttribute: Unable to watch config file not supported on SSCLI");
-			}
-			XmlConfigurator.Configure(targetRepository, configFile);
-#else
 			// Do we configure just once or do we configure and then watch?
 			if (m_configureAndWatch)
 			{
@@ -329,7 +319,6 @@ private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo conf
 			{
 				XmlConfigurator.Configure(targetRepository, configFile);
 			}
-#endif
 		}
 
 		/// <summary>
diff --git a/src/Core/DefaultRepositorySelector.cs b/src/Core/DefaultRepositorySelector.cs
index 09d46cc..d374e5e 100644
--- a/src/Core/DefaultRepositorySelector.cs
+++ b/src/Core/DefaultRepositorySelector.cs
@@ -705,7 +705,7 @@ private void ConfigureRepository(Assembly assembly, ILoggerRepository repository
 
                     // Determine whether to watch the file or not based on an app setting value:
 				    bool watchRepositoryConfigFile = false;
-#if NET_2_0 || MONO_2_0
+#if !NETCF
 				    Boolean.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out watchRepositoryConfigFile);
 #else
                                     {
diff --git a/src/Core/LoggerManager.cs b/src/Core/LoggerManager.cs
index 9a3afed..710fa91 100644
--- a/src/Core/LoggerManager.cs
+++ b/src/Core/LoggerManager.cs
@@ -805,9 +805,7 @@ private static string GetVersionInfo()
 			sb.Append("log4net assembly [").Append(myAssembly.FullName).Append("]. ");
 			sb.Append("Loaded from [").Append(SystemInfo.AssemblyLocationInfo(myAssembly)).Append("]. ");
 			sb.Append("(.NET Runtime [").Append(Environment.Version.ToString()).Append("]");
-#if (!SSCLI)
             sb.Append(" on ").Append(Environment.OSVersion.ToString());
-#endif
             sb.Append(")");
 			return sb.ToString();
 		}
diff --git a/src/Core/LoggingEvent.cs b/src/Core/LoggingEvent.cs
index 6c551aa..79e5d27 100644
--- a/src/Core/LoggingEvent.cs
+++ b/src/Core/LoggingEvent.cs
@@ -828,7 +828,7 @@ public string UserName
 			{
 				if (m_data.UserName == null  && this.m_cacheUpdatable) 
 				{
-#if (NETCF || SSCLI)
+#if NETCF
 					// On compact framework there's no notion of current Windows user
 					m_data.UserName = SystemInfo.NotAvailableText;
 #else
@@ -876,7 +876,7 @@ public string Identity
 			{
 				if (m_data.Identity == null  && this.m_cacheUpdatable)
 				{
-#if (NETCF || SSCLI)
+#if NETCF
 					// On compact framework there's no notion of current thread principals
 					m_data.Identity = SystemInfo.NotAvailableText;
 #else
diff --git a/src/DateFormatter/AbsoluteTimeDateFormatter.cs b/src/DateFormatter/AbsoluteTimeDateFormatter.cs
index 1174107..8433020 100644
--- a/src/DateFormatter/AbsoluteTimeDateFormatter.cs
+++ b/src/DateFormatter/AbsoluteTimeDateFormatter.cs
@@ -140,11 +140,6 @@ virtual public void FormatDate(DateTime dateToFormat, TextWriter writer)
 						// Render the string buffer to a string
                                                 timeString = s_lastTimeBuf.ToString();
 
-#if NET_1_1
-						// Ensure that the above string is written into the variable NOW on all threads.
-						// This is only required on multiprocessor machines with weak memeory models
-						System.Threading.Thread.MemoryBarrier();
-#endif
 						// Store the time as a string (we only have to do this once per second)
                                                 s_lastTimeStrings[GetType()] = timeString;
 						s_lastTimeToTheSecond = currentTimeToTheSecond;
diff --git a/src/Layout/Pattern/AspNetCachePatternConverter.cs b/src/Layout/Pattern/AspNetCachePatternConverter.cs
index 4452a5b..39aaab6 100644
--- a/src/Layout/Pattern/AspNetCachePatternConverter.cs
+++ b/src/Layout/Pattern/AspNetCachePatternConverter.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 
 using System.IO;
 using System.Web;
diff --git a/src/Layout/Pattern/AspNetContextPatternConverter.cs b/src/Layout/Pattern/AspNetContextPatternConverter.cs
index 61a9e17..9a6e674 100644
--- a/src/Layout/Pattern/AspNetContextPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetContextPatternConverter.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 
 using System.IO;
 using System.Web;
diff --git a/src/Layout/Pattern/AspNetPatternConverter.cs b/src/Layout/Pattern/AspNetPatternConverter.cs
index 7201ecd..d16b5b3 100644
--- a/src/Layout/Pattern/AspNetPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetPatternConverter.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 
 using System.IO;
 using System.Web;
diff --git a/src/Layout/Pattern/AspNetRequestPatternConverter.cs b/src/Layout/Pattern/AspNetRequestPatternConverter.cs
index ca810f6..c83c475 100644
--- a/src/Layout/Pattern/AspNetRequestPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetRequestPatternConverter.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 
 using System.IO;
 using System.Web;
diff --git a/src/Layout/Pattern/AspNetSessionPatternConverter.cs b/src/Layout/Pattern/AspNetSessionPatternConverter.cs
index f50ad8a..782ddb9 100644
--- a/src/Layout/Pattern/AspNetSessionPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetSessionPatternConverter.cs
@@ -17,9 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 
 using System.IO;
 using System.Web;
diff --git a/src/Layout/PatternLayout.cs b/src/Layout/PatternLayout.cs
index 9e15921..d7dcaa6 100644
--- a/src/Layout/PatternLayout.cs
+++ b/src/Layout/PatternLayout.cs
@@ -859,9 +859,8 @@ static PatternLayout()
 			s_globalRulesRegistry.Add("newline", typeof(NewLinePatternConverter));
 			s_globalRulesRegistry.Add("n", typeof(NewLinePatternConverter));
 
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
 			s_globalRulesRegistry.Add("aspnet-cache", typeof(AspNetCachePatternConverter));
 			s_globalRulesRegistry.Add("aspnet-context", typeof(AspNetContextPatternConverter));
 			s_globalRulesRegistry.Add("aspnet-request", typeof(AspNetRequestPatternConverter));
diff --git a/src/Layout/XMLLayout.cs b/src/Layout/XMLLayout.cs
index 6d8e432..cb704cf 100644
--- a/src/Layout/XMLLayout.cs
+++ b/src/Layout/XMLLayout.cs
@@ -220,11 +220,7 @@ override protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
 			writer.WriteStartElement(m_elmEvent);
 			writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName);
 
-#if NET_2_0 || NETCF_2_0 || MONO_2_0
 			writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp, XmlDateTimeSerializationMode.Local));
-#else
-			writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp));
-#endif
 
 			writer.WriteAttributeString(ATTR_LEVEL, loggingEvent.Level.DisplayName);
 			writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName);
diff --git a/src/Log4netAssemblyInfo.cs b/src/Log4netAssemblyInfo.cs
index 08ee5b3..40ad74c 100644
--- a/src/Log4netAssemblyInfo.cs
+++ b/src/Log4netAssemblyInfo.cs
@@ -28,31 +28,21 @@ public sealed class AssemblyInfo {
         public const string Version = "1.2.13";
 
         /// <summary>Version of the framework targeted</summary>
-#if NET_1_1
-        public const decimal TargetFrameworkVersion = 1.1M;
-#elif NET_4_0
+#if NET_4_0
         public const decimal TargetFrameworkVersion = 4.0M;
-#elif NET_2_0 || NETCF_2_0 || MONO_2_0
-#if !CLIENT_PROFILE
+#elif !CLIENT_PROFILE
         public const decimal TargetFrameworkVersion = 2.0M;
 #else
         public const decimal TargetFrameworkVersion = 3.5M;
-#endif  // Client Profile
-#else
-        public const decimal TargetFrameworkVersion = 1.0M;
 #endif
 
         /// <summary>Type of framework targeted</summary>
-#if CLI
-        public const string TargetFramework = "CLI Compatible Frameworks";
-#elif NET
+#if NET
         public const string TargetFramework = ".NET Framework";
 #elif NETCF
         public const string TargetFramework = ".NET Compact Framework";
 #elif MONO
         public const string TargetFramework = "Mono";
-#elif SSCLI
-        public const string TargetFramework = "Shared Source CLI";
 #else
         public const string TargetFramework = "Unknown";
 #endif
diff --git a/src/LogicalThreadContext.cs b/src/LogicalThreadContext.cs
index d23e4fa..40357c4 100644
--- a/src/LogicalThreadContext.cs
+++ b/src/LogicalThreadContext.cs
@@ -125,7 +125,7 @@ public static LogicalThreadContextProperties Properties
 		/// The logical thread stacks.
 		/// </para>
 		/// </remarks>
-		public static ThreadContextStacks Stacks
+		public static LogicalThreadContextStacks Stacks
 		{
 			get { return s_stacks; }
 		}
@@ -142,7 +142,7 @@ public static ThreadContextStacks Stacks
 		/// <summary>
 		/// The thread context stacks instance
 		/// </summary>
-		private readonly static ThreadContextStacks s_stacks = new ThreadContextStacks(s_properties);
+		private readonly static LogicalThreadContextStacks s_stacks = new LogicalThreadContextStacks(s_properties);
 
 		#endregion Private Static Fields
 	}
diff --git a/src/NDC.cs b/src/NDC.cs
index 8fd3d92..b54b1d1 100644
--- a/src/NDC.cs
+++ b/src/NDC.cs
@@ -20,10 +20,6 @@
 using System;
 using System.Collections;
 
-#if NETCF_1_0
-using Stack = log4net.Util.ThreadContextStack.Stack;
-#endif
-
 namespace log4net
 {
 	/// <summary>
diff --git a/src/Repository/Hierarchy/Logger.cs b/src/Repository/Hierarchy/Logger.cs
index f1013d0..d4d3eb1 100644
--- a/src/Repository/Hierarchy/Logger.cs
+++ b/src/Repository/Hierarchy/Logger.cs
@@ -432,7 +432,7 @@ virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, obje
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
 			}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 			catch
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
@@ -469,7 +469,7 @@ virtual public void Log(LoggingEvent logEvent)
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
 			}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 			catch
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
@@ -509,7 +509,7 @@ virtual public bool IsEnabledFor(Level level)
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
 			}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 			catch
 			{
 				log4net.Util.LogLog.Error(declaringType, "Exception while logging");
diff --git a/src/Util/LogicalThreadContextProperties.cs b/src/Util/LogicalThreadContextProperties.cs
index ab40b91..4b92ed0 100644
--- a/src/Util/LogicalThreadContextProperties.cs
+++ b/src/Util/LogicalThreadContextProperties.cs
@@ -100,7 +100,12 @@ internal LogicalThreadContextProperties()
 			set 
 			{ 
 				// Force the dictionary to be created
-				GetProperties(true)[key] = value; 
+				var props = GetProperties(true);
+						// Reason for cloning the dictionary below: object instances set on the CallContext
+						// need to be immutable to correctly flow through async/await
+				var immutableProps = new PropertiesDictionary(props);
+				immutableProps[key] = value;
+				SetCallContextData(immutableProps);
 			}
 		}
 
@@ -122,7 +127,9 @@ public void Remove(string key)
 			PropertiesDictionary dictionary = GetProperties(false);
 			if (dictionary != null)
 			{
-				dictionary.Remove(key);
+				var immutableProps = new PropertiesDictionary(dictionary);
+				immutableProps.Remove(key);
+				SetCallContextData(immutableProps);
 			}
 		}
 
@@ -139,7 +146,8 @@ public void Clear()
 			PropertiesDictionary dictionary = GetProperties(false);
 			if (dictionary != null)
 			{
-				dictionary.Clear();
+				var immutableProps = new PropertiesDictionary();
+				SetCallContextData(immutableProps);
 			}
 		}
 
@@ -208,7 +216,7 @@ internal PropertiesDictionary GetProperties(bool create)
 #endif
         private static PropertiesDictionary GetCallContextData()
 		{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
             return CallContext.LogicalGetData(c_SlotName) as PropertiesDictionary;
 #else
 			return CallContext.GetData(c_SlotName) as PropertiesDictionary;
@@ -229,7 +237,7 @@ private static PropertiesDictionary GetCallContextData()
 #endif
         private static void SetCallContextData(PropertiesDictionary properties)
 		{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
 			CallContext.LogicalSetData(c_SlotName, properties);
 #else
 			CallContext.SetData(c_SlotName, properties);
diff --git a/src/Util/LogicalThreadContextStack.cs b/src/Util/LogicalThreadContextStack.cs
new file mode 100644
index 0000000..59a5f42
--- /dev/null
+++ b/src/Util/LogicalThreadContextStack.cs
@@ -0,0 +1,405 @@
+#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
+
+using System;
+using System.Collections;
+
+using log4net.Core;
+
+namespace log4net.Util
+{
+	/// <summary>
+	/// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
+	/// </summary>
+	/// <remarks>
+	/// <para>
+	/// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
+	/// </para>
+	/// </remarks>
+	/// <author>Nicko Cadell</author>
+	public sealed class LogicalThreadContextStack : IFixingRequired
+	{
+		#region Private Instance Fields
+
+		/// <summary>
+		/// The stack store.
+		/// </summary>
+		private Stack m_stack = new Stack();
+
+		/// <summary>
+		/// The name of this <see cref="log4net.LogicalThreadContextStack"/> within the
+		/// <see cref="log4net.LogicalThreadContextProperties"/>.
+		/// </summary>
+		private string m_propertyKey;
+
+		/// <summary>
+		/// The callback used to let the <see cref="log4net.LogicalThreadContextStacks"/> register a
+		/// new instance of a <see cref="log4net.LogicalThreadContextStack"/>.
+		/// </summary>
+		private Action<string, LogicalThreadContextStack> m_registerNew;
+
+		#endregion Private Instance Fields
+
+		#region Public Instance Constructors
+
+		/// <summary>
+		/// Internal constructor
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Initializes a new instance of the <see cref="LogicalThreadContextStack" /> class. 
+		/// </para>
+		/// </remarks>
+		internal LogicalThreadContextStack(string propertyKey, Action<string, LogicalThreadContextStack> registerNew)
+		{
+			m_propertyKey = propertyKey;
+			m_registerNew = registerNew;
+		}
+
+		#endregion Public Instance Constructors
+
+		#region Public Properties
+
+		/// <summary>
+		/// The number of messages in the stack
+		/// </summary>
+		/// <value>
+		/// The current number of messages in the stack
+		/// </value>
+		/// <remarks>
+		/// <para>
+		/// The current number of messages in the stack. That is
+		/// the number of times <see cref="Push"/> has been called
+		/// minus the number of times <see cref="Pop"/> has been called.
+		/// </para>
+		/// </remarks>
+		public int Count
+		{
+			get { return m_stack.Count; }
+		}
+
+		#endregion // Public Properties
+
+		#region Public Methods
+
+		/// <summary>
+		/// Clears all the contextual information held in this stack.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Clears all the contextual information held in this stack.
+		/// Only call this if you think that this thread is being reused after
+		/// a previous call execution which may not have completed correctly.
+		/// You do not need to use this method if you always guarantee to call
+		/// the <see cref="IDisposable.Dispose"/> method of the <see cref="IDisposable"/>
+		/// returned from <see cref="Push"/> even in exceptional circumstances,
+		/// for example by using the <c>using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message"))</c> 
+		/// syntax.
+		/// </para>
+		/// </remarks>
+		public void Clear()
+		{
+			m_registerNew(m_propertyKey, new LogicalThreadContextStack(m_propertyKey, m_registerNew));
+		}
+
+		/// <summary>
+		/// Removes the top context from this stack.
+		/// </summary>
+		/// <returns>The message in the context that was removed from the top of this stack.</returns>
+		/// <remarks>
+		/// <para>
+		/// Remove the top context from this stack, and return
+		/// it to the caller. If this stack is empty then an
+		/// empty string (not <see langword="null"/>) is returned.
+		/// </para>
+		/// </remarks>
+		public string Pop()
+		{
+			// copy current stack
+			Stack stack = new Stack(new Stack(m_stack));
+			string result = "";
+			if (stack.Count > 0)
+			{
+				result = ((StackFrame)(stack.Pop())).Message;
+			}
+			m_registerNew(m_propertyKey,
+				new LogicalThreadContextStack(m_propertyKey, m_registerNew) { m_stack = stack });
+			return result;
+		}
+
+		/// <summary>
+		/// Pushes a new context message into this stack.
+		/// </summary>
+		/// <param name="message">The new context message.</param>
+		/// <returns>
+		/// An <see cref="IDisposable"/> that can be used to clean up the context stack.
+		/// </returns>
+		/// <remarks>
+		/// <para>
+		/// Pushes a new context onto this stack. An <see cref="IDisposable"/>
+		/// is returned that can be used to clean up this stack. This
+		/// can be easily combined with the <c>using</c> keyword to scope the
+		/// context.
+		/// </para>
+		/// </remarks>
+		/// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+		/// <code lang="C#">
+		/// using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message"))
+		/// {
+		///		log.Warn("This should have an ThreadContext Stack message");
+		///	}
+		/// </code>
+		/// </example>
+		public IDisposable Push(string message)
+		{
+			// do modifications on a copy
+			Stack stack = new Stack(new Stack(m_stack));
+			stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null));
+
+			var contextStack = new LogicalThreadContextStack(m_propertyKey, m_registerNew) { m_stack = stack };
+			m_registerNew(m_propertyKey, contextStack);
+			return new AutoPopStackFrame(contextStack, stack.Count - 1);
+		}
+
+		#endregion Public Methods
+
+		#region Internal Methods
+
+		/// <summary>
+		/// Gets the current context information for this stack.
+		/// </summary>
+		/// <returns>The current context information.</returns>
+		internal string GetFullMessage()
+		{
+			Stack stack = m_stack;
+			if (stack.Count > 0)
+			{
+				return ((StackFrame)(stack.Peek())).FullMessage;
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// Gets and sets the internal stack used by this <see cref="LogicalThreadContextStack"/>
+		/// </summary>
+		/// <value>The internal storage stack</value>
+		/// <remarks>
+		/// <para>
+		/// This property is provided only to support backward compatability 
+		/// of the <see cref="NDC"/>. Tytpically the internal stack should not
+		/// be modified.
+		/// </para>
+		/// </remarks>
+		internal Stack InternalStack
+		{
+			get { return m_stack; }
+			set { m_stack = value; }
+		}
+
+		#endregion Internal Methods
+
+		/// <summary>
+		/// Gets the current context information for this stack.
+		/// </summary>
+		/// <returns>Gets the current context information</returns>
+		/// <remarks>
+		/// <para>
+		/// Gets the current context information for this stack.
+		/// </para>
+		/// </remarks>
+		public override string ToString()
+		{
+			return GetFullMessage();
+		}
+
+		/// <summary>
+		/// Get a portable version of this object
+		/// </summary>
+		/// <returns>the portable instance of this object</returns>
+		/// <remarks>
+		/// <para>
+		/// Get a cross thread portable version of this object
+		/// </para>
+		/// </remarks>
+		object IFixingRequired.GetFixedObject()
+		{
+			return GetFullMessage();
+		}
+
+		/// <summary>
+		/// Inner class used to represent a single context frame in the stack.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Inner class used to represent a single context frame in the stack.
+		/// </para>
+		/// </remarks>
+		private sealed class StackFrame
+		{
+			#region Private Instance Fields
+
+			private readonly string m_message;
+			private readonly StackFrame m_parent;
+			private string m_fullMessage = null;
+
+			#endregion
+
+			#region Internal Instance Constructors
+
+			/// <summary>
+			/// Constructor
+			/// </summary>
+			/// <param name="message">The message for this context.</param>
+			/// <param name="parent">The parent context in the chain.</param>
+			/// <remarks>
+			/// <para>
+			/// Initializes a new instance of the <see cref="StackFrame" /> class
+			/// with the specified message and parent context.
+			/// </para>
+			/// </remarks>
+			internal StackFrame(string message, StackFrame parent)
+			{
+				m_message = message;
+				m_parent = parent;
+
+				if (parent == null)
+				{
+					m_fullMessage = message;
+				}
+			}
+
+			#endregion Internal Instance Constructors
+
+			#region Internal Instance Properties
+
+			/// <summary>
+			/// Get the message.
+			/// </summary>
+			/// <value>The message.</value>
+			/// <remarks>
+			/// <para>
+			/// Get the message.
+			/// </para>
+			/// </remarks>
+			internal string Message
+			{
+				get { return m_message; }
+			}
+
+			/// <summary>
+			/// Gets the full text of the context down to the root level.
+			/// </summary>
+			/// <value>
+			/// The full text of the context down to the root level.
+			/// </value>
+			/// <remarks>
+			/// <para>
+			/// Gets the full text of the context down to the root level.
+			/// </para>
+			/// </remarks>
+			internal string FullMessage
+			{
+				get
+				{
+					if (m_fullMessage == null && m_parent != null)
+					{
+						m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message);
+					}
+					return m_fullMessage;
+				}
+			}
+
+			#endregion Internal Instance Properties
+		}
+
+		/// <summary>
+		/// Struct returned from the <see cref="LogicalThreadContextStack.Push"/> method.
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// This struct implements the <see cref="IDisposable"/> and is designed to be used
+		/// with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
+		/// </para>
+		/// </remarks>
+		private struct AutoPopStackFrame : IDisposable
+		{
+			#region Private Instance Fields
+
+			/// <summary>
+			/// The depth to trim the stack to when this instance is disposed
+			/// </summary>
+			private int m_frameDepth;
+
+			/// <summary>
+			/// The outer LogicalThreadContextStack.
+			/// </summary>
+			private LogicalThreadContextStack m_logicalThreadContextStack;
+
+			#endregion Private Instance Fields
+
+			#region Internal Instance Constructors
+
+			/// <summary>
+			/// Constructor
+			/// </summary>
+			/// <param name="frameStack">The internal stack used by the ThreadContextStack.</param>
+			/// <param name="frameDepth">The depth to return the stack to when this object is disposed.</param>
+			/// <remarks>
+			/// <para>
+			/// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with
+			/// the specified stack and return depth.
+			/// </para>
+			/// </remarks>
+			internal AutoPopStackFrame(LogicalThreadContextStack logicalThreadContextStack, int frameDepth)
+			{
+				m_frameDepth = frameDepth;
+				m_logicalThreadContextStack = logicalThreadContextStack;
+			}
+
+			#endregion Internal Instance Constructors
+
+			#region Implementation of IDisposable
+
+			/// <summary>
+			/// Returns the stack to the correct depth.
+			/// </summary>
+			/// <remarks>
+			/// <para>
+			/// Returns the stack to the correct depth.
+			/// </para>
+			/// </remarks>
+			public void Dispose()
+			{
+				if (m_frameDepth >= 0 && m_logicalThreadContextStack.m_stack != null)
+				{
+					Stack stack = new Stack(new Stack(m_logicalThreadContextStack.m_stack));
+					while (stack.Count > m_frameDepth)
+					{
+						stack.Pop();
+					}
+					m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey,
+						new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew) { m_stack = stack });
+				}
+			}
+
+			#endregion Implementation of IDisposable
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/src/Util/LogicalThreadContextStacks.cs b/src/Util/LogicalThreadContextStacks.cs
new file mode 100644
index 0000000..834f877
--- /dev/null
+++ b/src/Util/LogicalThreadContextStacks.cs
@@ -0,0 +1,132 @@
+#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
+
+using System;
+using System.Collections;
+
+namespace log4net.Util
+{
+	/// <summary>
+	/// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
+	/// </summary>
+	/// <remarks>
+	/// <para>
+	/// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
+	/// </para>
+	/// </remarks>
+	/// <author>Nicko Cadell</author>
+	public sealed class LogicalThreadContextStacks
+	{
+		private readonly LogicalThreadContextProperties m_properties;
+
+		#region Public Instance Constructors
+
+		/// <summary>
+		/// Internal constructor
+		/// </summary>
+		/// <remarks>
+		/// <para>
+		/// Initializes a new instance of the <see cref="ThreadContextStacks" /> class.
+		/// </para>
+		/// </remarks>
+		internal LogicalThreadContextStacks(LogicalThreadContextProperties properties)
+		{
+			m_properties = properties;
+		}
+
+		#endregion Public Instance Constructors
+
+		#region Public Instance Properties
+
+		/// <summary>
+		/// Gets the named thread context stack
+		/// </summary>
+		/// <value>
+		/// The named stack
+		/// </value>
+		/// <remarks>
+		/// <para>
+		/// Gets the named thread context stack
+		/// </para>
+		/// </remarks>
+		public LogicalThreadContextStack this[string key]
+		{
+			get
+			{
+				LogicalThreadContextStack stack = null;
+
+				object propertyValue = m_properties[key];
+				if (propertyValue == null)
+				{
+					// Stack does not exist, create
+					stack = new LogicalThreadContextStack(key, registerNew);
+					m_properties[key] = stack;
+				}
+				else
+				{
+					// Look for existing stack
+					stack = propertyValue as LogicalThreadContextStack;
+					if (stack == null)
+					{
+						// Property is not set to a stack!
+						string propertyValueString = SystemInfo.NullText;
+
+						try
+						{
+							propertyValueString = propertyValue.ToString();
+						}
+						catch
+						{
+						}
+
+						LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]");
+
+						stack = new LogicalThreadContextStack(key, registerNew);
+					}
+				}
+
+				return stack;
+			}
+		}
+
+		#endregion Public Instance Properties
+
+		#region Private Instance Fields
+
+		private void registerNew(string stackName, LogicalThreadContextStack stack)
+		{
+			m_properties[stackName] = stack;
+		}
+
+		#endregion Private Instance Fields
+
+		#region Private Static Fields
+
+		/// <summary>
+		/// The fully qualified type of the ThreadContextStacks class.
+		/// </summary>
+		/// <remarks>
+		/// Used by the internal logger to record the Type of the
+		/// log message.
+		/// </remarks>
+		private readonly static Type declaringType = typeof(LogicalThreadContextStacks);
+
+		#endregion Private Static Fields
+	}
+}
diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs
index 5776c87..f1cbb63 100644
--- a/src/Util/NativeError.cs
+++ b/src/Util/NativeError.cs
@@ -17,13 +17,6 @@
 //
 #endregion
 
-// MONO 1.0 has no support for Win32 Error APIs
-#if !MONO
-// SSCLI 1.0 has no support for Win32 Error APIs
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
-
 using System;
 using System.Globalization;
 using System.Runtime.InteropServices;
@@ -284,7 +277,3 @@ public override string ToString()
 		#endregion
 	}
 }
-
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
diff --git a/src/Util/PatternStringConverters/IdentityPatternConverter.cs b/src/Util/PatternStringConverters/IdentityPatternConverter.cs
index 5f83c76..9ea58d7 100644
--- a/src/Util/PatternStringConverters/IdentityPatternConverter.cs
+++ b/src/Util/PatternStringConverters/IdentityPatternConverter.cs
@@ -48,7 +48,7 @@ internal sealed class IdentityPatternConverter : PatternConverter
 		/// </remarks>
 		override protected void Convert(TextWriter writer, object state) 
 		{
-#if (NETCF || SSCLI)
+#if NETCF
 			// On compact framework there's no notion of current thread principals
 			writer.Write( SystemInfo.NotAvailableText );
 #else
diff --git a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
index cf5df78..aaeb8ad 100644
--- a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
+++ b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
@@ -51,7 +51,7 @@ internal sealed class ProcessIdPatternConverter : PatternConverter
 #endif
         override protected void Convert(TextWriter writer, object state) 
 		{
-#if (NETCF || SSCLI)
+#if NETCF
 			// On compact framework there is no System.Diagnostics.Process class
 			writer.Write( SystemInfo.NotAvailableText );
 #else
diff --git a/src/Util/PatternStringConverters/UserNamePatternConverter.cs b/src/Util/PatternStringConverters/UserNamePatternConverter.cs
index 921ee24..b26ee76 100644
--- a/src/Util/PatternStringConverters/UserNamePatternConverter.cs
+++ b/src/Util/PatternStringConverters/UserNamePatternConverter.cs
@@ -48,7 +48,7 @@ internal sealed class UserNamePatternConverter : PatternConverter
 		/// </remarks>
 		override protected void Convert(TextWriter writer, object state) 
 		{
-#if (NETCF || SSCLI)
+#if NETCF
 			// On compact framework there's no notion of current Windows user
 			writer.Write( SystemInfo.NotAvailableText );
 #else
diff --git a/src/Util/ReadOnlyPropertiesDictionary.cs b/src/Util/ReadOnlyPropertiesDictionary.cs
index 519d4d7..3bd57c6 100644
--- a/src/Util/ReadOnlyPropertiesDictionary.cs
+++ b/src/Util/ReadOnlyPropertiesDictionary.cs
@@ -52,7 +52,7 @@ public class ReadOnlyPropertiesDictionary : IDictionary
 		/// <summary>
 		/// The Hashtable used to store the properties data
 		/// </summary>
-		private Hashtable m_hashtable = new Hashtable();
+		private readonly Hashtable m_hashtable = new Hashtable();
 
 		#endregion Private Instance Fields
 
@@ -210,7 +210,7 @@ protected Hashtable InnerHashtable
 #endif
         public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
 		{
-			foreach(DictionaryEntry entry in InnerHashtable)
+			foreach(DictionaryEntry entry in InnerHashtable.Clone() as IDictionary)
 			{
 				string entryKey = entry.Key as string;
 				object entryValue = entry.Value;
diff --git a/src/Util/SystemInfo.cs b/src/Util/SystemInfo.cs
index d61d5c9..0022cb9 100644
--- a/src/Util/SystemInfo.cs
+++ b/src/Util/SystemInfo.cs
@@ -223,13 +223,7 @@ public static int CurrentThreadId
 		{
 			get 
 			{
-#if NETCF_1_0
-				return System.Threading.Thread.CurrentThread.GetHashCode();
-#elif NET_2_0 || NETCF_2_0 || MONO_2_0
 				return System.Threading.Thread.CurrentThread.ManagedThreadId;
-#else
-				return AppDomain.GetCurrentThreadId();
-#endif
 			}
 		}
 
@@ -283,7 +277,7 @@ public static string HostName
 					{
 						try
 						{
-#if (!SSCLI && !NETCF)
+#if !NETCF
 							s_hostName = Environment.MachineName;
 #endif
 						}
@@ -740,11 +734,7 @@ public static Type GetTypeFromString(Assembly relativeAssembly, string typeName,
 		/// </remarks>
 		public static Guid NewGuid()
 		{
-#if NETCF_1_0
-			return PocketGuid.NewGuid();
-#else
 			return Guid.NewGuid();
-#endif
 		}
 
 		/// <summary>
@@ -768,9 +758,7 @@ public static Guid NewGuid()
 		/// </remarks>
 		public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string parameterName, object actualValue, string message)
 		{
-#if NETCF_1_0
-			return new ArgumentOutOfRangeException(message + " [param=" + parameterName + "] [value=" + actualValue + "]");
-#elif NETCF_2_0
+#if NETCF_2_0
 			return new ArgumentOutOfRangeException(parameterName, message + " [value=" + actualValue + "]");
 #else
 			return new ArgumentOutOfRangeException(parameterName, actualValue, message);
@@ -1013,13 +1001,7 @@ public static string ConvertToFullPath(string path)
 		/// </remarks>
 		public static Hashtable CreateCaseInsensitiveHashtable()
 		{
-#if NETCF_1_0
-			return new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
-#elif NETCF_2_0 || NET_2_0 || MONO_2_0
 			return new Hashtable(StringComparer.OrdinalIgnoreCase);
-#else
-			return System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable();
-#endif
 		}
 
 		#endregion Public Static Methods
@@ -1117,126 +1099,5 @@ private static string NativeEntryAssemblyLocation
 		private static DateTime s_processStartTime = DateTime.Now;
 
 		#endregion
-
-		#region Compact Framework Helper Classes
-#if NETCF_1_0
-		/// <summary>
-		/// Generate GUIDs on the .NET Compact Framework.
-		/// </summary>
-		public class PocketGuid
-		{
-			// guid variant types
-			private enum GuidVariant
-			{
-				ReservedNCS = 0x00,
-				Standard = 0x02,
-				ReservedMicrosoft = 0x06,
-				ReservedFuture = 0x07
-			}
-
-			// guid version types
-			private enum GuidVersion
-			{
-				TimeBased = 0x01,
-				Reserved = 0x02,
-				NameBased = 0x03,
-				Random = 0x04
-			}
-
-			// constants that are used in the class
-			private class Const
-			{
-				// number of bytes in guid
-				public const int ByteArraySize = 16;
-
-				// multiplex variant info
-				public const int VariantByte = 8;
-				public const int VariantByteMask = 0x3f;
-				public const int VariantByteShift = 6;
-
-				// multiplex version info
-				public const int VersionByte = 7;
-				public const int VersionByteMask = 0x0f;
-				public const int VersionByteShift = 4;
-			}
-
-			// imports for the crypto api functions
-			private class WinApi
-			{
-				public const uint PROV_RSA_FULL = 1;
-				public const uint CRYPT_VERIFYCONTEXT = 0xf0000000;
-
-				[DllImport("CoreDll.dll")] 
-				public static extern bool CryptAcquireContext(
-					ref IntPtr phProv, string pszContainer, string pszProvider,
-					uint dwProvType, uint dwFlags);
-
-				[DllImport("CoreDll.dll")] 
-				public static extern bool CryptReleaseContext( 
-					IntPtr hProv, uint dwFlags);
-
-				[DllImport("CoreDll.dll")] 
-				public static extern bool CryptGenRandom(
-					IntPtr hProv, int dwLen, byte[] pbBuffer);
-			}
-
-			// all static methods
-			private PocketGuid()
-			{
-			}
-
-			/// <summary>
-			/// Return a new System.Guid object.
-			/// </summary>
-			public static Guid NewGuid()
-			{
-				IntPtr hCryptProv = IntPtr.Zero;
-				Guid guid = Guid.Empty;
-
-				try
-				{
-					// holds random bits for guid
-					byte[] bits = new byte[Const.ByteArraySize];
-
-					// get crypto provider handle
-					if (!WinApi.CryptAcquireContext(ref hCryptProv, null, null, 
-						WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT))
-					{
-						throw new SystemException(
-							"Failed to acquire cryptography handle.");
-					}
-
-					// generate a 128 bit (16 byte) cryptographically random number
-					if (!WinApi.CryptGenRandom(hCryptProv, bits.Length, bits))
-					{
-						throw new SystemException(
-							"Failed to generate cryptography random bytes.");
-					}
-
-					// set the variant
-					bits[Const.VariantByte] &= Const.VariantByteMask;
-					bits[Const.VariantByte] |= 
-						((int)GuidVariant.Standard << Const.VariantByteShift);
-
-					// set the version
-					bits[Const.VersionByte] &= Const.VersionByteMask;
-					bits[Const.VersionByte] |= 
-						((int)GuidVersion.Random << Const.VersionByteShift);
-
-					// create the new System.Guid object
-					guid = new Guid(bits);
-				}
-				finally
-				{
-					// release the crypto provider handle
-					if (hCryptProv != IntPtr.Zero)
-						WinApi.CryptReleaseContext(hCryptProv, 0);
-				}
-
-				return guid;
-			}
-		}
-#endif
-		#endregion Compact Framework Helper Classes
 	}
 }
diff --git a/src/Util/SystemStringFormat.cs b/src/Util/SystemStringFormat.cs
index 82404b9..d7e504f 100644
--- a/src/Util/SystemStringFormat.cs
+++ b/src/Util/SystemStringFormat.cs
@@ -109,7 +109,7 @@ private static string StringFormat(IFormatProvider provider, string format, para
 				log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex);
 				return StringFormatError(ex, format, args);
 			}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 			catch
 			{
 				log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]");
@@ -148,7 +148,7 @@ private static string StringFormatError(Exception formatException, string format
 				log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex);
 				return "<log4net.Error>Exception during StringFormat. See Internal Log.</log4net.Error>";
 			}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 			catch
 			{
 				log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling");
@@ -210,7 +210,7 @@ private static void RenderObject(Object obj, StringBuilder buffer)
 				{
 					buffer.Append("<Exception: ").Append(ex.Message).Append(">");
 				}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
 				catch
 				{
 					buffer.Append("<Exception>");
diff --git a/src/Util/ThreadContextStack.cs b/src/Util/ThreadContextStack.cs
index d723dca..e8a3074 100644
--- a/src/Util/ThreadContextStack.cs
+++ b/src/Util/ThreadContextStack.cs
@@ -18,10 +18,7 @@
 #endregion
 
 using System;
-
-#if !NETCF_1_0
 using System.Collections;
-#endif
 
 using log4net.Core;
 
@@ -380,56 +377,5 @@ public void Dispose()
 			#endregion Implementation of IDisposable
 		}
 
-#if NETCF_1_0
-		/// <summary>
-		/// Subclass of <see cref="System.Collections.Stack"/> to
-		/// provide missing methods.
-		/// </summary>
-		/// <remarks>
-		/// <para>
-		/// The Compact Framework version of the <see cref="System.Collections.Stack"/>
-		/// class is missing the <c>Clear</c> and <c>Clone</c> methods.
-		/// This subclass adds implementations of those missing methods.
-		/// </para>
-		/// </remarks>
-		public class Stack : System.Collections.Stack
-		{
-			/// <summary>
-			/// Clears the stack of all elements.
-			/// </summary>
-			/// <remarks>
-			/// <para>
-			/// Clears the stack of all elements.
-			/// </para>
-			/// </remarks>
-			public void Clear()
-			{
-				while(Count > 0)
-				{
-					Pop();
-				}
-			}
-
-			/// <summary>
-			/// Makes a shallow copy of the stack's elements.
-			/// </summary>
-			/// <returns>A new stack that has a shallow copy of the stack's elements.</returns>
-			/// <remarks>
-			/// <para>
-			/// Makes a shallow copy of the stack's elements.
-			/// </para>
-			/// </remarks>
-			public Stack Clone()
-			{
-				Stack res = new Stack();
-				object[] items = ToArray();
-				foreach(object item in items)
-				{
-					res.Push(item);
-				}
-				return res;
-			}
-		}
-#endif
 	}
 }
diff --git a/src/Util/WindowsSecurityContext.cs b/src/Util/WindowsSecurityContext.cs
index 357c43d..74ebfaa 100644
--- a/src/Util/WindowsSecurityContext.cs
+++ b/src/Util/WindowsSecurityContext.cs
@@ -17,14 +17,8 @@
 //
 #endregion
 
-// .NET Compact Framework 1.0 has no support for WindowsIdentity
+// .NET Compact Framework has no support for WindowsIdentity
 #if !NETCF 
-// MONO 1.0 has no support for Win32 Logon APIs
-#if !MONO
-// SSCLI 1.0 has no support for Win32 Logon APIs
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
 
 using System;
 using System.Runtime.InteropServices;
@@ -380,8 +374,5 @@ public void Dispose()
 	}
 }
 
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
 #endif // !NETCF
 
diff --git a/src/log4net.vs2008.csproj b/src/log4net.vs2008.csproj
index 1a227aa..51ac524 100644
--- a/src/log4net.vs2008.csproj
+++ b/src/log4net.vs2008.csproj
@@ -69,13 +69,13 @@
     <ErrorReport>prompt</ErrorReport>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <OutputPath>..\build\bin\net\1.0\release\</OutputPath>
+    <OutputPath>..\build\bin\net\2.0\release\</OutputPath>
     <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
     <BaseAddress>285212672</BaseAddress>
     <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
     <ConfigurationOverrideFile>
     </ConfigurationOverrideFile>
-    <DefineConstants>TRACE;STRONG;NET;NET_1_0;</DefineConstants>
+    <DefineConstants>TRACE;STRONG;NET;NET_2_0;</DefineConstants>
     <DocumentationFile>log4net.xml</DocumentationFile>
     <DebugSymbols>false</DebugSymbols>
     <FileAlignment>4096</FileAlignment>
diff --git a/src/log4net.vs2010.csproj b/src/log4net.vs2010.csproj
index e72a356..a67671b 100644
--- a/src/log4net.vs2010.csproj
+++ b/src/log4net.vs2010.csproj
@@ -723,9 +723,15 @@
     <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>
diff --git a/tests/src/Appender/RemotingAppenderTest.cs b/tests/src/Appender/RemotingAppenderTest.cs
index 376ba27..9d88e17 100644
--- a/tests/src/Appender/RemotingAppenderTest.cs
+++ b/tests/src/Appender/RemotingAppenderTest.cs
@@ -207,7 +207,7 @@ private void RegisterRemotingServerChannel()
 				// Setup remoting server
 				try
 				{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
 					ChannelServices.RegisterChannel(m_remotingChannel, false);
 #else
 					ChannelServices.RegisterChannel(m_remotingChannel);
diff --git a/tests/src/Context/LogicalThreadContextTest.cs b/tests/src/Context/LogicalThreadContextTest.cs
new file mode 100644
index 0000000..08ef245
--- /dev/null
+++ b/tests/src/Context/LogicalThreadContextTest.cs
@@ -0,0 +1,344 @@
+#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
+
+using System;
+using System.Threading.Tasks;
+using System.Linq;
+
+using log4net.Config;
+using log4net.Layout;
+using log4net.Repository;
+using log4net.Tests.Appender;
+using log4net.Util;
+
+using NUnit.Framework;
+
+namespace log4net.Tests.Context
+{
+#if FRAMEWORK_4_5_OR_ABOVE
+	/// <summary>
+	/// Used for internal unit testing the <see cref="LogicalThreadContext"/> class.
+	/// </summary>
+	/// <remarks>
+	/// Used for internal unit testing the <see cref="LogicalThreadContext"/> class.
+	/// </remarks>
+	[TestFixture]
+	public class LogicalThreadContextTest
+	{
+		[TearDown]
+		public void TearDown()
+		{
+			Utils.RemovePropertyFromAllContexts();
+		}
+
+		[Test]
+		public void TestLogicalThreadPropertiesPatternBasicGetSet()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread properties value set");
+			stringAppender.Reset();
+
+			LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = "val1";
+
+			log1.Info("TestMessage");
+			Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread properties value set");
+			stringAppender.Reset();
+
+			LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public async Task TestLogicalThreadPropertiesPatternAsyncAwait()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			string testValueForCurrentContext = "Outer";
+			LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = testValueForCurrentContext;
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set");
+			stringAppender.Reset();
+
+			var strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkProperties(x.ToString())));
+
+			// strings should be ["00AA0BB0", "01AA1BB1", "02AA2BB2", ...]
+			for (int i = 0; i < strings.Length; i++)
+			{
+				Assert.AreEqual(string.Format("{0}{1}AA{1}BB{1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence");
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set");
+			stringAppender.Reset();
+
+			LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public void TestLogicalThreadStackPattern()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+			{
+				log1.Info("TestMessage");
+				Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public void TestLogicalThreadStackPattern2()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+			{
+				log1.Info("TestMessage");
+				Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+
+				using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2"))
+				{
+					log1.Info("TestMessage");
+					Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test logical thread stack value pushed 2nd val");
+					stringAppender.Reset();
+				}
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public void TestLogicalThreadStackPatternNullVal()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+			{
+				log1.Info("TestMessage");
+				Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public void TestLogicalThreadStackPatternNullVal2()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+			{
+				log1.Info("TestMessage");
+				Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+
+				using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+				{
+					log1.Info("TestMessage");
+					Assert.AreEqual("val1 ", stringAppender.GetString(), "Test logical thread stack value pushed null");
+					stringAppender.Reset();
+				}
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+			stringAppender.Reset();
+		}
+
+		[Test]
+		public async Task TestLogicalThreadStackPatternAsyncAwait()
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+			stringAppender.Reset();
+
+			string testValueForCurrentContext = "Outer";
+			string[] strings = null;
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(testValueForCurrentContext))
+			{
+				log1.Info("TestMessage");
+				Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+
+				strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkStack(x.ToString())));
+			}
+
+			// strings should be ["Outer 0 AOuter 0 AOuter 0Outer 0 BOuter 0 B Outer 0", ...]
+			for (int i = 0; i < strings.Length; i++)
+			{
+				Assert.AreEqual(string.Format("{0} {1} A{0} {1} A{0} {1}{0} {1} B{0} {1} B{0} {1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence");
+			}
+
+			log1.Info("TestMessage");
+			Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+			stringAppender.Reset();
+		}
+
+		static async Task<string> SomeWorkProperties(string propertyName)
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+			log.Info("TestMessage");
+
+			// set a new one
+			LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName;
+			log.Info("TestMessage");
+
+			await MoreWorkProperties(log, "A");
+			log.Info("TestMessage");
+			await MoreWorkProperties(log, "B");
+			log.Info("TestMessage");
+			return stringAppender.GetString();
+		}
+
+		static async Task MoreWorkProperties(ILog log, string propertyName)
+		{
+			LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName;
+			log.Info("TestMessage");
+			await Task.Delay(1);
+			log.Info("TestMessage");
+		}
+
+		static async Task<string> SomeWorkStack(string stackName)
+		{
+			StringAppender stringAppender = new StringAppender();
+			stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+			ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+			BasicConfigurator.Configure(rep, stringAppender);
+
+			ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName))
+			{
+				log.Info("TestMessage");
+				Assert.AreEqual(string.Format("Outer {0}", stackName), stringAppender.GetString(), "Test logical thread stack value set");
+				stringAppender.Reset();
+
+				await MoreWorkStack(log, "A");
+				log.Info("TestMessage");
+				await MoreWorkStack(log, "B");
+				log.Info("TestMessage");
+			}
+
+			return stringAppender.GetString();
+		}
+
+		static async Task MoreWorkStack(ILog log, string stackName)
+		{
+			using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName))
+			{
+				log.Info("TestMessage");
+				await Task.Delay(1);
+				log.Info("TestMessage");
+			}
+		}
+	}
+#endif
+}
\ No newline at end of file
diff --git a/tests/src/Layout/XmlLayoutTest.cs b/tests/src/Layout/XmlLayoutTest.cs
index 9e016b8..1ce0704 100644
--- a/tests/src/Layout/XmlLayoutTest.cs
+++ b/tests/src/Layout/XmlLayoutTest.cs
@@ -81,7 +81,7 @@ private LoggingEventData CreateBaseEvent()
 		private static string CreateEventNode(string message)
 		{
 			return String.Format("<event logger=\"TestLogger\" timestamp=\"{0}\" level=\"INFO\" thread=\"TestThread\" domain=\"Tests\" identity=\"TestRunner\" username=\"TestRunner\"><message>{1}</message></event>" + Environment.NewLine,
-#if NET_2_0 || MONO_2_0
+#if !NETCF
 			                     XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local),
 #else
 			                     XmlConvert.ToString(DateTime.Today),
@@ -92,7 +92,7 @@ private static string CreateEventNode(string message)
 		private static string CreateEventNode(string key, string value)
 		{
 			return String.Format("<event logger=\"TestLogger\" timestamp=\"{0}\" level=\"INFO\" thread=\"TestThread\" domain=\"Tests\" identity=\"TestRunner\" username=\"TestRunner\"><message>Test message</message><properties><data name=\"{1}\" value=\"{2}\" /></properties></event>" + Environment.NewLine,
-#if NET_2_0 || MONO_2_0
+#if !NETCF
 			                     XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local),
 #else
 			                     XmlConvert.ToString(DateTime.Today),
diff --git a/tests/src/Utils.cs b/tests/src/Utils.cs
index 8de9a9f..4e98283 100644
--- a/tests/src/Utils.cs
+++ b/tests/src/Utils.cs
@@ -105,6 +105,7 @@ private static Type[] GetTypesArray(object[] args)
         internal static void RemovePropertyFromAllContexts() {
             GlobalContext.Properties.Remove(PROPERTY_KEY);
             ThreadContext.Properties.Remove(PROPERTY_KEY);
+            LogicalThreadContext.Properties.Remove(PROPERTY_KEY);
         }
 	}
 }
\ No newline at end of file
diff --git a/tests/src/log4net.Tests.vs2010.csproj b/tests/src/log4net.Tests.vs2010.csproj
index 13c69a6..72903e8 100644
--- a/tests/src/log4net.Tests.vs2010.csproj
+++ b/tests/src/log4net.Tests.vs2010.csproj
@@ -47,7 +47,7 @@
     <UpgradeBackupLocation>
     </UpgradeBackupLocation>
     <OldToolsVersion>3.5</OldToolsVersion>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
     <InstallFrom>Disk</InstallFrom>
@@ -163,6 +165,9 @@
     <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>