Modified: 
logging/log4net/trunk/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
URL: 
http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs?rev=1671382&r1=1671381&r2=1671382&view=diff
==============================================================================
--- 
logging/log4net/trunk/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
 (original)
+++ 
logging/log4net/trunk/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
 Sun Apr  5 10:11:47 2015
@@ -30,69 +30,69 @@ using log4net.ObjectRenderer;
 
 namespace log4net.Repository.Hierarchy
 {
-       /// <summary>
-       /// Initializes the log4net environment using an XML DOM.
-       /// </summary>
-       /// <remarks>
-       /// <para>
-       /// Configures a <see cref="Hierarchy"/> using an XML DOM.
-       /// </para>
-       /// </remarks>
-       /// <author>Nicko Cadell</author>
-       /// <author>Gert Driesen</author>
-       public class XmlHierarchyConfigurator
-       {
-               private enum ConfigUpdateMode
-               {
-                       Merge, 
-                       Overwrite
-               }
-
-               #region Public Instance Constructors
-
-               /// <summary>
-               /// Construct the configurator for a hierarchy
-               /// </summary>
-               /// <param name="hierarchy">The hierarchy to build.</param>
-               /// <remarks>
-               /// <para>
-               /// Initializes a new instance of the <see 
cref="XmlHierarchyConfigurator" /> class
-               /// with the specified <see cref="Hierarchy" />.
-               /// </para>
-               /// </remarks>
-               public XmlHierarchyConfigurator(Hierarchy hierarchy) 
-               {
-                       m_hierarchy = hierarchy;
-                       m_appenderBag = new Hashtable();
-               }
-
-               #endregion Public Instance Constructors
-
-               #region Public Instance Methods
-
-               /// <summary>
-               /// Configure the hierarchy by parsing a DOM tree of XML 
elements.
-               /// </summary>
-               /// <param name="element">The root element to parse.</param>
-               /// <remarks>
-               /// <para>
-               /// Configure the hierarchy by parsing a DOM tree of XML 
elements.
-               /// </para>
-               /// </remarks>
-               public void Configure(XmlElement element) 
-               {
-                       if (element == null || m_hierarchy == null)
-                       {
+    /// <summary>
+    /// Initializes the log4net environment using an XML DOM.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// Configures a <see cref="Hierarchy"/> using an XML DOM.
+    /// </para>
+    /// </remarks>
+    /// <author>Nicko Cadell</author>
+    /// <author>Gert Driesen</author>
+    public class XmlHierarchyConfigurator
+    {
+        private enum ConfigUpdateMode
+        {
+            Merge,
+            Overwrite
+        }
+
+        #region Public Instance Constructors
+
+        /// <summary>
+        /// Construct the configurator for a hierarchy
+        /// </summary>
+        /// <param name="hierarchy">The hierarchy to build.</param>
+        /// <remarks>
+        /// <para>
+        /// Initializes a new instance of the <see 
cref="XmlHierarchyConfigurator" /> class
+        /// with the specified <see cref="Hierarchy" />.
+        /// </para>
+        /// </remarks>
+        public XmlHierarchyConfigurator(Hierarchy hierarchy)
+        {
+            m_hierarchy = hierarchy;
+            m_appenderBag = new Hashtable();
+        }
+
+        #endregion Public Instance Constructors
+
+        #region Public Instance Methods
+
+        /// <summary>
+        /// Configure the hierarchy by parsing a DOM tree of XML elements.
+        /// </summary>
+        /// <param name="element">The root element to parse.</param>
+        /// <remarks>
+        /// <para>
+        /// Configure the hierarchy by parsing a DOM tree of XML elements.
+        /// </para>
+        /// </remarks>
+        public void Configure(XmlElement element)
+        {
+            if (element == null || m_hierarchy == null)
+            {
                 return;
-                       }
+            }
 
-                       string rootElementName = element.LocalName;
+            string rootElementName = element.LocalName;
 
-                       if (rootElementName != CONFIGURATION_TAG)
-                       {
-                               LogLog.Error(declaringType, "Xml element is - 
not a <" + CONFIGURATION_TAG + "> element.");
+            if (rootElementName != CONFIGURATION_TAG)
+            {
+                LogLog.Error(declaringType, "Xml element is - not a <" + 
CONFIGURATION_TAG + "> element.");
                 return;
-                       }
+            }
 
             if (!LogLog.EmitInternalMessages)
             {
@@ -110,1007 +110,1009 @@ namespace log4net.Repository.Hierarchy
                 }
             }
 
-                   if (!LogLog.InternalDebugging)
-                       {
-                               // Look for a debug attribute to enable 
internal debug
-                               string debugAttribute = 
element.GetAttribute(INTERNAL_DEBUG_ATTR);
-                               LogLog.Debug(declaringType, 
INTERNAL_DEBUG_ATTR+" attribute [" + debugAttribute + "].");
-
-                               if (debugAttribute.Length>0 && debugAttribute 
!= "null") 
-                               {         
-                                       LogLog.InternalDebugging = 
OptionConverter.ToBoolean(debugAttribute, true);
-                               }
-                               else 
-                               {
-                                       LogLog.Debug(declaringType, "Ignoring " 
+ INTERNAL_DEBUG_ATTR + " attribute.");
-                               }
-
-                               string confDebug = 
element.GetAttribute(CONFIG_DEBUG_ATTR);
-                               if (confDebug.Length>0 && confDebug != "null")
-                               {         
-                                       LogLog.Warn(declaringType, "The \"" + 
CONFIG_DEBUG_ATTR + "\" attribute is deprecated.");
-                                       LogLog.Warn(declaringType, "Use the \"" 
+ INTERNAL_DEBUG_ATTR + "\" attribute instead.");
-                                       LogLog.InternalDebugging = 
OptionConverter.ToBoolean(confDebug, true);
-                               }
-                       }
-
-                       // Default mode is merge
-                       ConfigUpdateMode configUpdateMode = 
ConfigUpdateMode.Merge;
-
-                       // Look for the config update attribute
-                       string configUpdateModeAttribute = 
element.GetAttribute(CONFIG_UPDATE_MODE_ATTR);
-                       if (configUpdateModeAttribute != null && 
configUpdateModeAttribute.Length > 0)
-                       {
-                               // Parse the attribute
-                               try
-                               {
-                                       configUpdateMode = 
(ConfigUpdateMode)OptionConverter.ConvertStringTo(typeof(ConfigUpdateMode), 
configUpdateModeAttribute);
-                               }
-                               catch
-                               {
-                                       LogLog.Error(declaringType, "Invalid " 
+ CONFIG_UPDATE_MODE_ATTR + " attribute value [" + configUpdateModeAttribute + 
"]");
-                               }
-                       }
-
-                       // IMPL: The IFormatProvider argument to 
Enum.ToString() is deprecated in .NET 2.0
-                       LogLog.Debug(declaringType, "Configuration update mode 
[" + configUpdateMode.ToString() + "].");
-
-                       // Only reset configuration if overwrite flag specified
-                       if (configUpdateMode == ConfigUpdateMode.Overwrite)
-                       {
-                               // Reset to original unset configuration
-                               m_hierarchy.ResetConfiguration();
-                               LogLog.Debug(declaringType, "Configuration 
reset before reading config.");
-                       }
-
-                       /* Building Appender objects, placing them in a local 
namespace
-                          for future reference */
-
-                       /* Process all the top level elements */
-
-                       foreach (XmlNode currentNode in element.ChildNodes)
-                       {
-                               if (currentNode.NodeType == 
XmlNodeType.Element) 
-                               {
-                                       XmlElement currentElement = 
(XmlElement)currentNode;
-
-                                       if (currentElement.LocalName == 
LOGGER_TAG)
-                                       {
-                                               ParseLogger(currentElement);
-                                       } 
-                                       else if (currentElement.LocalName == 
CATEGORY_TAG)
-                                       {
-                                               // TODO: deprecated use of 
category
-                                               ParseLogger(currentElement);
-                                       } 
-                                       else if (currentElement.LocalName == 
ROOT_TAG)
-                                       {
-                                               ParseRoot(currentElement);
-                                       } 
-                                       else if (currentElement.LocalName == 
RENDERER_TAG)
-                                       {
-                                               ParseRenderer(currentElement);
-                                       }
-                                       else if (currentElement.LocalName == 
APPENDER_TAG)
-                                       {
-                                               // We ignore appenders in this 
pass. They will
-                                               // be found and loaded if they 
are referenced.
-                                       }
-                                       else
-                                       {
-                                               // Read the param tags and set 
properties on the hierarchy
-                                               SetParameter(currentElement, 
m_hierarchy);
-                                       }
-                               }
-                       }
-
-                       // Lastly set the hierarchy threshold
-                       string thresholdStr = 
element.GetAttribute(THRESHOLD_ATTR);
-                       LogLog.Debug(declaringType, "Hierarchy Threshold [" + 
thresholdStr + "]");
-                       if (thresholdStr.Length > 0 && thresholdStr != "null") 
-                       {
-                               Level thresholdLevel = (Level) 
ConvertStringTo(typeof(Level), thresholdStr);
-                               if (thresholdLevel != null)
-                               {
-                                       m_hierarchy.Threshold = thresholdLevel;
-                               }
-                               else
-                               {
-                                       LogLog.Warn(declaringType, "Unable to 
set hierarchy threshold using value [" + thresholdStr + "] (with acceptable 
conversion types)");
-                               }
-                       }
-
-                       // Done reading config
-               }
-
-           #endregion Public Instance Methods
-
-               #region Protected Instance Methods
-
-               /// <summary>
-               /// Parse appenders by IDREF.
-               /// </summary>
-               /// <param name="appenderRef">The appender ref element.</param>
-               /// <returns>The instance of the appender that the ref refers 
to.</returns>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents an appender and return 
-               /// the appender.
-               /// </para>
-               /// </remarks>
-               protected IAppender FindAppenderByReference(XmlElement 
appenderRef) 
-               {       
-                       string appenderName = 
appenderRef.GetAttribute(REF_ATTR);
-
-                       IAppender appender = 
(IAppender)m_appenderBag[appenderName];
-                       if (appender != null) 
-                       {
-                               return appender;
-                       } 
-                       else 
-                       {
-                               // Find the element with that id
-                               XmlElement element = null;
-
-                               if (appenderName != null && appenderName.Length 
> 0)
-                               {
-                                       foreach (XmlElement curAppenderElement 
in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG))
-                                       {
-                                               if 
(curAppenderElement.GetAttribute("name") == appenderName)
-                                               {
-                                                       element = 
curAppenderElement;
-                                                       break;
-                                               }
-                                       }
-                               }
-
-                               if (element == null) 
-                               {
-                                       LogLog.Error(declaringType, 
"XmlHierarchyConfigurator: No appender named [" + appenderName + "] could be 
found."); 
-                                       return null;
-                               } 
-                               else
-                               {
-                                       appender = ParseAppender(element);
-                                       if (appender != null)
-                                       {
-                                               m_appenderBag[appenderName] = 
appender;
-                                       }
-                                       return appender;
-                               }
-                       } 
-               }
-
-               /// <summary>
-               /// Parses an appender element.
-               /// </summary>
-               /// <param name="appenderElement">The appender element.</param>
-               /// <returns>The appender instance or <c>null</c> when parsing 
failed.</returns>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents an appender and return
-               /// the appender instance.
-               /// </para>
-               /// </remarks>
-               protected IAppender ParseAppender(XmlElement appenderElement) 
-               {
-                       string appenderName = 
appenderElement.GetAttribute(NAME_ATTR);
-                       string typeName = 
appenderElement.GetAttribute(TYPE_ATTR);
-
-                       LogLog.Debug(declaringType, "Loading Appender [" + 
appenderName + "] type: [" + typeName + "]");
-                       try 
-                       {
-                               IAppender appender = 
(IAppender)Activator.CreateInstance(SystemInfo.GetTypeFromString(typeName, 
true, true));
-                               appender.Name = appenderName;
-
-                               foreach (XmlNode currentNode in 
appenderElement.ChildNodes)
-                               {
-                                       /* We're only interested in Elements */
-                                       if (currentNode.NodeType == 
XmlNodeType.Element) 
-                                       {
-                                               XmlElement currentElement = 
(XmlElement)currentNode;
-
-                                               // Look for the appender ref tag
-                                               if (currentElement.LocalName == 
APPENDER_REF_TAG)
-                                               {
-                                                       string refName = 
currentElement.GetAttribute(REF_ATTR);
-
-                                                       IAppenderAttachable 
appenderContainer = appender as IAppenderAttachable;
-                                                       if (appenderContainer 
!= null) 
-                                                       {
-                                                               
LogLog.Debug(declaringType, "Attaching appender named [" + refName + "] to 
appender named [" + appender.Name + "].");
-
-                                                               IAppender 
referencedAppender = FindAppenderByReference(currentElement);
-                                                               if 
(referencedAppender != null)
-                                                               {
-                                                                       
appenderContainer.AddAppender(referencedAppender);
-                                                               }
-                                                       } 
-                                                       else 
-                                                       {
-                                                               
LogLog.Error(declaringType, "Requesting attachment of appender named 
["+refName+ "] to appender named [" + appender.Name + "] which does not 
implement log4net.Core.IAppenderAttachable.");
-                                                       }
-                                               }
-                                               else
-                                               {
-                                                       // For all other tags 
we use standard set param method
-                                                       
SetParameter(currentElement, appender);
-                                               }
-                                       }
-                               }
-
-                               IOptionHandler optionHandler = appender as 
IOptionHandler;
-                               if (optionHandler != null) 
-                               {
-                                       optionHandler.ActivateOptions();
-                               }
-
-                               LogLog.Debug(declaringType, "Created Appender 
[" + appenderName + "]"); 
-                               return appender;
-                       }
-                       catch (Exception ex) 
-                       {
-                               // Yes, it's ugly.  But all exceptions point to 
the same problem: we can't create an Appender
-
-                               LogLog.Error(declaringType, "Could not create 
Appender [" + appenderName + "] of type [" + typeName + "]. Reported error 
follows.", ex);
-                               return null;
-                       }
-               }
-
-               /// <summary>
-               /// Parses a logger element.
-               /// </summary>
-               /// <param name="loggerElement">The logger element.</param>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents a logger.
-               /// </para>
-               /// </remarks>
-               protected void ParseLogger(XmlElement loggerElement) 
-               {
-                       // Create a new log4net.Logger object from the <logger> 
element.
-                       string loggerName = 
loggerElement.GetAttribute(NAME_ATTR);
-
-                       LogLog.Debug(declaringType, "Retrieving an instance of 
log4net.Repository.Logger for logger [" + loggerName + "].");
-                       Logger log = m_hierarchy.GetLogger(loggerName) as 
Logger;
-
-                       // Setting up a logger needs to be an atomic operation, 
in order
-                       // to protect potential log operations while logger
-                       // configuration is in progress.
-                       lock(log) 
-                       {
-                               bool additivity = 
OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true);
-       
-                               LogLog.Debug(declaringType, "Setting [" + 
log.Name + "] additivity to [" + additivity + "].");
-                               log.Additivity = additivity;
-                               ParseChildrenOfLoggerElement(loggerElement, 
log, false);
-                       }
-               }
-
-               /// <summary>
-               /// Parses the root logger element.
-               /// </summary>
-               /// <param name="rootElement">The root element.</param>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents the root logger.
-               /// </para>
-               /// </remarks>
-               protected void ParseRoot(XmlElement rootElement) 
-               {
-                       Logger root = m_hierarchy.Root;
-                       // logger configuration needs to be atomic
-                       lock(root) 
-                       {       
-                               ParseChildrenOfLoggerElement(rootElement, root, 
true);
-                       }
-               }
-
-               /// <summary>
-               /// Parses the children of a logger element.
-               /// </summary>
-               /// <param name="catElement">The category element.</param>
-               /// <param name="log">The logger instance.</param>
-               /// <param name="isRoot">Flag to indicate if the logger is the 
root logger.</param>
-               /// <remarks>
-               /// <para>
-               /// Parse the child elements of a &lt;logger&gt; element.
-               /// </para>
-               /// </remarks>
-               protected void ParseChildrenOfLoggerElement(XmlElement 
catElement, Logger log, bool isRoot) 
-               {
-                       // Remove all existing appenders from log. They will be
-                       // reconstructed if need be.
-                       log.RemoveAllAppenders();
-
-                       foreach (XmlNode currentNode in catElement.ChildNodes)
-                       {
-                               if (currentNode.NodeType == 
XmlNodeType.Element) 
-                               {
-                                       XmlElement currentElement = 
(XmlElement) currentNode;
-       
-                                       if (currentElement.LocalName == 
APPENDER_REF_TAG)
-                                       {
-                                               IAppender appender = 
FindAppenderByReference(currentElement);
-                                               string refName =  
currentElement.GetAttribute(REF_ATTR);
-                                               if (appender != null)
-                                               {
-                                                       
LogLog.Debug(declaringType, "Adding appender named [" + refName + "] to logger 
[" + log.Name + "].");
-                                                       
log.AddAppender(appender);
-                                               }
-                                               else 
-                                               {
-                                                       
LogLog.Error(declaringType, "Appender named [" + refName + "] not found.");
-                                               }
-                                       } 
-                                       else if (currentElement.LocalName == 
LEVEL_TAG || currentElement.LocalName == PRIORITY_TAG) 
-                                       {
-                                               ParseLevel(currentElement, log, 
isRoot);        
-                                       } 
-                                       else
-                                       {
-                                               SetParameter(currentElement, 
log);
-                                       }
-                               }
-                       }
-
-                       IOptionHandler optionHandler = log as IOptionHandler;
-                       if (optionHandler != null) 
-                       {
-                               optionHandler.ActivateOptions();
-                       }
-               }
-
-               /// <summary>
-               /// Parses an object renderer.
-               /// </summary>
-               /// <param name="element">The renderer element.</param>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents a renderer.
-               /// </para>
-               /// </remarks>
-               protected void ParseRenderer(XmlElement element) 
-               {
-                       string renderingClassName = 
element.GetAttribute(RENDERING_TYPE_ATTR);
-                       string renderedClassName = 
element.GetAttribute(RENDERED_TYPE_ATTR);
-
-                       LogLog.Debug(declaringType, "Rendering class [" + 
renderingClassName + "], Rendered class [" + renderedClassName + "].");
-                       IObjectRenderer renderer = 
(IObjectRenderer)OptionConverter.InstantiateByClassName(renderingClassName, 
typeof(IObjectRenderer), null);
-                       if (renderer == null) 
-                       {
-                               LogLog.Error(declaringType, "Could not 
instantiate renderer [" + renderingClassName + "].");
-                               return;
-                       } 
-                       else 
-                       {
-                               try 
-                               {
-                                       
m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, 
true, true), renderer);
-                               } 
-                               catch(Exception e) 
-                               {
-                                       LogLog.Error(declaringType, "Could not 
find class [" + renderedClassName + "].", e);
-                               }
-                       }
-               }
-
-               /// <summary>
-               /// Parses a level element.
-               /// </summary>
-               /// <param name="element">The level element.</param>
-               /// <param name="log">The logger object to set the level 
on.</param>
-               /// <param name="isRoot">Flag to indicate if the logger is the 
root logger.</param>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element that represents a level.
-               /// </para>
-               /// </remarks>
-               protected void ParseLevel(XmlElement element, Logger log, bool 
isRoot) 
-               {
-                       string loggerName = log.Name;
-                       if (isRoot) 
-                       {
-                               loggerName = "root";
-                       }
-
-                       string levelStr = element.GetAttribute(VALUE_ATTR);
-                       LogLog.Debug(declaringType, "Logger [" + loggerName + 
"] Level string is [" + levelStr + "].");
-       
-                       if (INHERITED == levelStr) 
-                       {
-                               if (isRoot) 
-                               {
-                                       LogLog.Error(declaringType, "Root level 
cannot be inherited. Ignoring directive.");
-                               } 
-                               else 
-                               {
-                                       LogLog.Debug(declaringType, "Logger [" 
+ loggerName + "] level set to inherit from parent.");   
-                                       log.Level = null;
-                               }
-                       } 
-                       else 
-                       {
-                               log.Level = log.Hierarchy.LevelMap[levelStr];
-                               if (log.Level == null)
-                               {
-                                       LogLog.Error(declaringType, "Undefined 
level [" + levelStr + "] on Logger [" + loggerName + "].");
-                               }
-                               else
-                               {
-                                       LogLog.Debug(declaringType, "Logger [" 
+ loggerName + "] level set to [name=\"" + log.Level.Name + "\",value=" + 
log.Level.Value + "].");       
-                               }
-                       }
-               }
-
-               /// <summary>
-               /// Sets a parameter on an object.
-               /// </summary>
-               /// <param name="element">The parameter element.</param>
-               /// <param name="target">The object to set the parameter 
on.</param>
-               /// <remarks>
-               /// The parameter name must correspond to a writable property
-               /// on the object. The value of the parameter is a string,
-               /// therefore this function will attempt to set a string
-               /// property first. If unable to set a string property it
-               /// will inspect the property and its argument type. It will
-               /// attempt to call a static method called <c>Parse</c> on the
-               /// type of the property. This method will take a single
-               /// string argument and return a value that can be used to
-               /// set the property.
-               /// </remarks>
-               protected void SetParameter(XmlElement element, object target) 
-               {
-                       // Get the property name
-                       string name = element.GetAttribute(NAME_ATTR);
-
-                       // If the name attribute does not exist then use the 
name of the element
-                       if (element.LocalName != PARAM_TAG || name == null || 
name.Length == 0)
-                       {
-                               name = element.LocalName;
-                       }
-
-                       // Look for the property on the target object
-                       Type targetType = target.GetType();
-                       Type propertyType = null;
-
-                       PropertyInfo propInfo = null;
-                       MethodInfo methInfo = null;
-
-                       // Try to find a writable property
-                       propInfo = targetType.GetProperty(name, 
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.IgnoreCase);
-                       if (propInfo != null && propInfo.CanWrite)
-                       {
-                               // found a property
-                               propertyType = propInfo.PropertyType;
-                       }
-                       else
-                       {
-                               propInfo = null;
-
-                               // look for a method with the signature 
Add<property>(type)
-                               methInfo = FindMethodInfo(targetType, name);
-
-                               if (methInfo != null)
-                               {
-                                       propertyType = 
methInfo.GetParameters()[0].ParameterType;
-                               }
-                       }
-
-                       if (propertyType == null)
-                       {
-                               LogLog.Error(declaringType, 
"XmlHierarchyConfigurator: Cannot find Property [" + name + "] to set object on 
[" + target.ToString() + "]");
-                       }
-                       else
-                       {
-                               string propertyValue = null;
-
-                               if (element.GetAttributeNode(VALUE_ATTR) != 
null)
-                               {
-                                       propertyValue = 
element.GetAttribute(VALUE_ATTR);
-                               }
-                               else if (element.HasChildNodes)
-                               {
-                                       // Concatenate the CDATA and Text nodes 
together
-                                       foreach(XmlNode childNode in 
element.ChildNodes)
-                                       {
-                                               if (childNode.NodeType == 
XmlNodeType.CDATA || childNode.NodeType == XmlNodeType.Text)
-                                               {
-                                                       if (propertyValue == 
null)
-                                                       {
-                                                               propertyValue = 
childNode.InnerText;
-                                                       }
-                                                       else
-                                                       {
-                                                               propertyValue 
+= childNode.InnerText;
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               if(propertyValue != null)
-                               {
-#if !NETCF     
-                                       try
-                                       {
-                                               // Expand environment variables 
in the string.
-                                           IDictionary environmentVariables = 
Environment.GetEnvironmentVariables();
-                                           if (HasCaseInsensitiveEnvironment) {
-                                               environmentVariables = 
CreateCaseInsensitiveWrapper(environmentVariables);
-                                           }
-                                               propertyValue = 
OptionConverter.SubstituteVariables(propertyValue, environmentVariables);
-                                       }
-                                       catch(System.Security.SecurityException)
-                                       {
-                                               // This security exception will 
occur if the caller does not have 
-                                               // unrestricted environment 
permission. If this occurs the expansion 
-                                               // will be skipped with the 
following warning message.
-                                               LogLog.Debug(declaringType, 
"Security exception while trying to expand environment variables. Error 
Ignored. No Expansion.");
-                                       }
+            if (!LogLog.InternalDebugging)
+            {
+                // Look for a debug attribute to enable internal debug
+                string debugAttribute = 
element.GetAttribute(INTERNAL_DEBUG_ATTR);
+                LogLog.Debug(declaringType, INTERNAL_DEBUG_ATTR + " attribute 
[" + debugAttribute + "].");
+
+                if (debugAttribute.Length > 0 && debugAttribute != "null")
+                {
+                    LogLog.InternalDebugging = 
OptionConverter.ToBoolean(debugAttribute, true);
+                }
+                else
+                {
+                    LogLog.Debug(declaringType, "Ignoring " + 
INTERNAL_DEBUG_ATTR + " attribute.");
+                }
+
+                string confDebug = element.GetAttribute(CONFIG_DEBUG_ATTR);
+                if (confDebug.Length > 0 && confDebug != "null")
+                {
+                    LogLog.Warn(declaringType, "The \"" + CONFIG_DEBUG_ATTR + 
"\" attribute is deprecated.");
+                    LogLog.Warn(declaringType, "Use the \"" + 
INTERNAL_DEBUG_ATTR + "\" attribute instead.");
+                    LogLog.InternalDebugging = 
OptionConverter.ToBoolean(confDebug, true);
+                }
+            }
+
+            // Default mode is merge
+            ConfigUpdateMode configUpdateMode = ConfigUpdateMode.Merge;
+
+            // Look for the config update attribute
+            string configUpdateModeAttribute = 
element.GetAttribute(CONFIG_UPDATE_MODE_ATTR);
+            if (configUpdateModeAttribute != null && 
configUpdateModeAttribute.Length > 0)
+            {
+                // Parse the attribute
+                try
+                {
+                    configUpdateMode = 
(ConfigUpdateMode)OptionConverter.ConvertStringTo(typeof(ConfigUpdateMode), 
configUpdateModeAttribute);
+                }
+                catch
+                {
+                    LogLog.Error(declaringType, "Invalid " + 
CONFIG_UPDATE_MODE_ATTR + " attribute value [" + configUpdateModeAttribute + 
"]");
+                }
+            }
+
+            // IMPL: The IFormatProvider argument to Enum.ToString() is 
deprecated in .NET 2.0
+            LogLog.Debug(declaringType, "Configuration update mode [" + 
configUpdateMode.ToString() + "].");
+
+            // Only reset configuration if overwrite flag specified
+            if (configUpdateMode == ConfigUpdateMode.Overwrite)
+            {
+                // Reset to original unset configuration
+                m_hierarchy.ResetConfiguration();
+                LogLog.Debug(declaringType, "Configuration reset before 
reading config.");
+            }
+
+            /* Building Appender objects, placing them in a local namespace
+               for future reference */
+
+            /* Process all the top level elements */
+
+            foreach (XmlNode currentNode in element.ChildNodes)
+            {
+                if (currentNode.NodeType == XmlNodeType.Element)
+                {
+                    XmlElement currentElement = (XmlElement)currentNode;
+
+                    if (currentElement.LocalName == LOGGER_TAG)
+                    {
+                        ParseLogger(currentElement);
+                    }
+                    else if (currentElement.LocalName == CATEGORY_TAG)
+                    {
+                        // TODO: deprecated use of category
+                        ParseLogger(currentElement);
+                    }
+                    else if (currentElement.LocalName == ROOT_TAG)
+                    {
+                        ParseRoot(currentElement);
+                    }
+                    else if (currentElement.LocalName == RENDERER_TAG)
+                    {
+                        ParseRenderer(currentElement);
+                    }
+                    else if (currentElement.LocalName == APPENDER_TAG)
+                    {
+                        // We ignore appenders in this pass. They will
+                        // be found and loaded if they are referenced.
+                    }
+                    else
+                    {
+                        // Read the param tags and set properties on the 
hierarchy
+                        SetParameter(currentElement, m_hierarchy);
+                    }
+                }
+            }
+
+            // Lastly set the hierarchy threshold
+            string thresholdStr = element.GetAttribute(THRESHOLD_ATTR);
+            LogLog.Debug(declaringType, "Hierarchy Threshold [" + thresholdStr 
+ "]");
+            if (thresholdStr.Length > 0 && thresholdStr != "null")
+            {
+                Level thresholdLevel = (Level)ConvertStringTo(typeof(Level), 
thresholdStr);
+                if (thresholdLevel != null)
+                {
+                    m_hierarchy.Threshold = thresholdLevel;
+                }
+                else
+                {
+                    LogLog.Warn(declaringType, "Unable to set hierarchy 
threshold using value [" + thresholdStr + "] (with acceptable conversion 
types)");
+                }
+            }
+
+            // Done reading config
+        }
+
+        #endregion Public Instance Methods
+
+        #region Protected Instance Methods
+
+        /// <summary>
+        /// Parse appenders by IDREF.
+        /// </summary>
+        /// <param name="appenderRef">The appender ref element.</param>
+        /// <returns>The instance of the appender that the ref refers 
to.</returns>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents an appender and return 
+        /// the appender.
+        /// </para>
+        /// </remarks>
+        protected IAppender FindAppenderByReference(XmlElement appenderRef)
+        {
+            string appenderName = appenderRef.GetAttribute(REF_ATTR);
+
+            IAppender appender = (IAppender)m_appenderBag[appenderName];
+            if (appender != null)
+            {
+                return appender;
+            }
+            else
+            {
+                // Find the element with that id
+                XmlElement element = null;
+
+                if (appenderName != null && appenderName.Length > 0)
+                {
+                    foreach (XmlElement curAppenderElement in 
appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG))
+                    {
+                        if (curAppenderElement.GetAttribute("name") == 
appenderName)
+                        {
+                            element = curAppenderElement;
+                            break;
+                        }
+                    }
+                }
+
+                if (element == null)
+                {
+                    LogLog.Error(declaringType, "XmlHierarchyConfigurator: No 
appender named [" + appenderName + "] could be found.");
+                    return null;
+                }
+                else
+                {
+                    appender = ParseAppender(element);
+                    if (appender != null)
+                    {
+                        m_appenderBag[appenderName] = appender;
+                    }
+                    return appender;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Parses an appender element.
+        /// </summary>
+        /// <param name="appenderElement">The appender element.</param>
+        /// <returns>The appender instance or <c>null</c> when parsing 
failed.</returns>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents an appender and return
+        /// the appender instance.
+        /// </para>
+        /// </remarks>
+        protected IAppender ParseAppender(XmlElement appenderElement)
+        {
+            string appenderName = appenderElement.GetAttribute(NAME_ATTR);
+            string typeName = appenderElement.GetAttribute(TYPE_ATTR);
+
+            LogLog.Debug(declaringType, "Loading Appender [" + appenderName + 
"] type: [" + typeName + "]");
+            try
+            {
+                IAppender appender = 
(IAppender)Activator.CreateInstance(SystemInfo.GetTypeFromString(typeName, 
true, true));
+                appender.Name = appenderName;
+
+                foreach (XmlNode currentNode in appenderElement.ChildNodes)
+                {
+                    /* We're only interested in Elements */
+                    if (currentNode.NodeType == XmlNodeType.Element)
+                    {
+                        XmlElement currentElement = (XmlElement)currentNode;
+
+                        // Look for the appender ref tag
+                        if (currentElement.LocalName == APPENDER_REF_TAG)
+                        {
+                            string refName = 
currentElement.GetAttribute(REF_ATTR);
+
+                            IAppenderAttachable appenderContainer = appender 
as IAppenderAttachable;
+                            if (appenderContainer != null)
+                            {
+                                LogLog.Debug(declaringType, "Attaching 
appender named [" + refName + "] to appender named [" + appender.Name + "].");
+
+                                IAppender referencedAppender = 
FindAppenderByReference(currentElement);
+                                if (referencedAppender != null)
+                                {
+                                    
appenderContainer.AddAppender(referencedAppender);
+                                }
+                            }
+                            else
+                            {
+                                LogLog.Error(declaringType, "Requesting 
attachment of appender named [" + refName + "] to appender named [" + 
appender.Name + "] which does not implement log4net.Core.IAppenderAttachable.");
+                            }
+                        }
+                        else
+                        {
+                            // For all other tags we use standard set param 
method
+                            SetParameter(currentElement, appender);
+                        }
+                    }
+                }
+
+                IOptionHandler optionHandler = appender as IOptionHandler;
+                if (optionHandler != null)
+                {
+                    optionHandler.ActivateOptions();
+                }
+
+                LogLog.Debug(declaringType, "Created Appender [" + 
appenderName + "]");
+                return appender;
+            }
+            catch (Exception ex)
+            {
+                // Yes, it's ugly.  But all exceptions point to the same 
problem: we can't create an Appender
+
+                LogLog.Error(declaringType, "Could not create Appender [" + 
appenderName + "] of type [" + typeName + "]. Reported error follows.", ex);
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// Parses a logger element.
+        /// </summary>
+        /// <param name="loggerElement">The logger element.</param>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents a logger.
+        /// </para>
+        /// </remarks>
+        protected void ParseLogger(XmlElement loggerElement)
+        {
+            // Create a new log4net.Logger object from the <logger> element.
+            string loggerName = loggerElement.GetAttribute(NAME_ATTR);
+
+            LogLog.Debug(declaringType, "Retrieving an instance of 
log4net.Repository.Logger for logger [" + loggerName + "].");
+            Logger log = m_hierarchy.GetLogger(loggerName) as Logger;
+
+            // Setting up a logger needs to be an atomic operation, in order
+            // to protect potential log operations while logger
+            // configuration is in progress.
+            lock (log)
+            {
+                bool additivity = 
OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true);
+
+                LogLog.Debug(declaringType, "Setting [" + log.Name + "] 
additivity to [" + additivity + "].");
+                log.Additivity = additivity;
+                ParseChildrenOfLoggerElement(loggerElement, log, false);
+            }
+        }
+
+        /// <summary>
+        /// Parses the root logger element.
+        /// </summary>
+        /// <param name="rootElement">The root element.</param>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents the root logger.
+        /// </para>
+        /// </remarks>
+        protected void ParseRoot(XmlElement rootElement)
+        {
+            Logger root = m_hierarchy.Root;
+            // logger configuration needs to be atomic
+            lock (root)
+            {
+                ParseChildrenOfLoggerElement(rootElement, root, true);
+            }
+        }
+
+        /// <summary>
+        /// Parses the children of a logger element.
+        /// </summary>
+        /// <param name="catElement">The category element.</param>
+        /// <param name="log">The logger instance.</param>
+        /// <param name="isRoot">Flag to indicate if the logger is the root 
logger.</param>
+        /// <remarks>
+        /// <para>
+        /// Parse the child elements of a &lt;logger&gt; element.
+        /// </para>
+        /// </remarks>
+        protected void ParseChildrenOfLoggerElement(XmlElement catElement, 
Logger log, bool isRoot)
+        {
+            // Remove all existing appenders from log. They will be
+            // reconstructed if need be.
+            log.RemoveAllAppenders();
+
+            foreach (XmlNode currentNode in catElement.ChildNodes)
+            {
+                if (currentNode.NodeType == XmlNodeType.Element)
+                {
+                    XmlElement currentElement = (XmlElement)currentNode;
+
+                    if (currentElement.LocalName == APPENDER_REF_TAG)
+                    {
+                        IAppender appender = 
FindAppenderByReference(currentElement);
+                        string refName = currentElement.GetAttribute(REF_ATTR);
+                        if (appender != null)
+                        {
+                            LogLog.Debug(declaringType, "Adding appender named 
[" + refName + "] to logger [" + log.Name + "].");
+                            log.AddAppender(appender);
+                        }
+                        else
+                        {
+                            LogLog.Error(declaringType, "Appender named [" + 
refName + "] not found.");
+                        }
+                    }
+                    else if (currentElement.LocalName == LEVEL_TAG || 
currentElement.LocalName == PRIORITY_TAG)
+                    {
+                        ParseLevel(currentElement, log, isRoot);
+                    }
+                    else
+                    {
+                        SetParameter(currentElement, log);
+                    }
+                }
+            }
+
+            IOptionHandler optionHandler = log as IOptionHandler;
+            if (optionHandler != null)
+            {
+                optionHandler.ActivateOptions();
+            }
+        }
+
+        /// <summary>
+        /// Parses an object renderer.
+        /// </summary>
+        /// <param name="element">The renderer element.</param>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents a renderer.
+        /// </para>
+        /// </remarks>
+        protected void ParseRenderer(XmlElement element)
+        {
+            string renderingClassName = 
element.GetAttribute(RENDERING_TYPE_ATTR);
+            string renderedClassName = 
element.GetAttribute(RENDERED_TYPE_ATTR);
+
+            LogLog.Debug(declaringType, "Rendering class [" + 
renderingClassName + "], Rendered class [" + renderedClassName + "].");
+            IObjectRenderer renderer = 
(IObjectRenderer)OptionConverter.InstantiateByClassName(renderingClassName, 
typeof(IObjectRenderer), null);
+            if (renderer == null)
+            {
+                LogLog.Error(declaringType, "Could not instantiate renderer [" 
+ renderingClassName + "].");
+                return;
+            }
+            else
+            {
+                try
+                {
+                    
m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, 
true, true), renderer);
+                }
+                catch (Exception e)
+                {
+                    LogLog.Error(declaringType, "Could not find class [" + 
renderedClassName + "].", e);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Parses a level element.
+        /// </summary>
+        /// <param name="element">The level element.</param>
+        /// <param name="log">The logger object to set the level on.</param>
+        /// <param name="isRoot">Flag to indicate if the logger is the root 
logger.</param>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element that represents a level.
+        /// </para>
+        /// </remarks>
+        protected void ParseLevel(XmlElement element, Logger log, bool isRoot)
+        {
+            string loggerName = log.Name;
+            if (isRoot)
+            {
+                loggerName = "root";
+            }
+
+            string levelStr = element.GetAttribute(VALUE_ATTR);
+            LogLog.Debug(declaringType, "Logger [" + loggerName + "] Level 
string is [" + levelStr + "].");
+
+            if (INHERITED == levelStr)
+            {
+                if (isRoot)
+                {
+                    LogLog.Error(declaringType, "Root level cannot be 
inherited. Ignoring directive.");
+                }
+                else
+                {
+                    LogLog.Debug(declaringType, "Logger [" + loggerName + "] 
level set to inherit from parent.");
+                    log.Level = null;
+                }
+            }
+            else
+            {
+                log.Level = log.Hierarchy.LevelMap[levelStr];
+                if (log.Level == null)
+                {
+                    LogLog.Error(declaringType, "Undefined level [" + levelStr 
+ "] on Logger [" + loggerName + "].");
+                }
+                else
+                {
+                    LogLog.Debug(declaringType, "Logger [" + loggerName + "] 
level set to [name=\"" + log.Level.Name + "\",value=" + log.Level.Value + "].");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Sets a parameter on an object.
+        /// </summary>
+        /// <param name="element">The parameter element.</param>
+        /// <param name="target">The object to set the parameter on.</param>
+        /// <remarks>
+        /// The parameter name must correspond to a writable property
+        /// on the object. The value of the parameter is a string,
+        /// therefore this function will attempt to set a string
+        /// property first. If unable to set a string property it
+        /// will inspect the property and its argument type. It will
+        /// attempt to call a static method called <c>Parse</c> on the
+        /// type of the property. This method will take a single
+        /// string argument and return a value that can be used to
+        /// set the property.
+        /// </remarks>
+        protected void SetParameter(XmlElement element, object target)
+        {
+            // Get the property name
+            string name = element.GetAttribute(NAME_ATTR);
+
+            // If the name attribute does not exist then use the name of the 
element
+            if (element.LocalName != PARAM_TAG || name == null || name.Length 
== 0)
+            {
+                name = element.LocalName;
+            }
+
+            // Look for the property on the target object
+            Type targetType = target.GetType();
+            Type propertyType = null;
+
+            PropertyInfo propInfo = null;
+            MethodInfo methInfo = null;
+
+            // Try to find a writable property
+            propInfo = targetType.GetProperty(name, BindingFlags.Instance | 
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
+            if (propInfo != null && propInfo.CanWrite)
+            {
+                // found a property
+                propertyType = propInfo.PropertyType;
+            }
+            else
+            {
+                propInfo = null;
+
+                // look for a method with the signature Add<property>(type)
+                methInfo = FindMethodInfo(targetType, name);
+
+                if (methInfo != null)
+                {
+                    propertyType = methInfo.GetParameters()[0].ParameterType;
+                }
+            }
+
+            if (propertyType == null)
+            {
+                LogLog.Error(declaringType, "XmlHierarchyConfigurator: Cannot 
find Property [" + name + "] to set object on [" + target.ToString() + "]");
+            }
+            else
+            {
+                string propertyValue = null;
+
+                if (element.GetAttributeNode(VALUE_ATTR) != null)
+                {
+                    propertyValue = element.GetAttribute(VALUE_ATTR);
+                }
+                else if (element.HasChildNodes)
+                {
+                    // Concatenate the CDATA and Text nodes together
+                    foreach (XmlNode childNode in element.ChildNodes)
+                    {
+                        if (childNode.NodeType == XmlNodeType.CDATA || 
childNode.NodeType == XmlNodeType.Text)
+                        {
+                            if (propertyValue == null)
+                            {
+                                propertyValue = childNode.InnerText;
+                            }
+                            else
+                            {
+                                propertyValue += childNode.InnerText;
+                            }
+                        }
+                    }
+                }
+
+                if (propertyValue != null)
+                {
+#if !NETCF
+                    try
+                    {
+                        // Expand environment variables in the string.
+                        IDictionary environmentVariables = 
Environment.GetEnvironmentVariables();
+                        if (HasCaseInsensitiveEnvironment)
+                        {
+                            environmentVariables = 
CreateCaseInsensitiveWrapper(environmentVariables);
+                        }
+                        propertyValue = 
OptionConverter.SubstituteVariables(propertyValue, environmentVariables);
+                    }
+                    catch (System.Security.SecurityException)
+                    {
+                        // This security exception will occur if the caller 
does not have 
+                        // unrestricted environment permission. If this occurs 
the expansion 
+                        // will be skipped with the following warning message.
+                        LogLog.Debug(declaringType, "Security exception while 
trying to expand environment variables. Error Ignored. No Expansion.");
+                    }
 #endif
 
-                                       Type parsedObjectConversionTargetType = 
null;
+                    Type parsedObjectConversionTargetType = null;
+
+                    // Check if a specific subtype is specified on the element 
using the 'type' attribute
+                    string subTypeString = element.GetAttribute(TYPE_ATTR);
+                    if (subTypeString != null && subTypeString.Length > 0)
+                    {
+                        // Read the explicit subtype
+                        try
+                        {
+                            Type subType = 
SystemInfo.GetTypeFromString(subTypeString, true, true);
+
+                            LogLog.Debug(declaringType, "Parameter [" + name + 
"] specified subtype [" + subType.FullName + "]");
+
+                            if (!propertyType.IsAssignableFrom(subType))
+                            {
+                                // Check if there is an appropriate type 
converter
+                                if (OptionConverter.CanConvertTypeTo(subType, 
propertyType))
+                                {
+                                    // Must re-convert to the real property 
type
+                                    parsedObjectConversionTargetType = 
propertyType;
+
+                                    // Use sub type as intermediary type
+                                    propertyType = subType;
+                                }
+                                else
+                                {
+                                    LogLog.Error(declaringType, "subtype [" + 
subType.FullName + "] set on [" + name + "] is not a subclass of property type 
[" + propertyType.FullName + "] and there are no acceptable type conversions.");
+                                }
+                            }
+                            else
+                            {
+                                // The subtype specified is found and is 
actually a subtype of the property
+                                // type, therefore we can switch to using this 
type.
+                                propertyType = subType;
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            LogLog.Error(declaringType, "Failed to find type 
[" + subTypeString + "] set on [" + name + "]", ex);
+                        }
+                    }
+
+                    // Now try to convert the string value to an acceptable 
type
+                    // to pass to this property.
+
+                    object convertedValue = ConvertStringTo(propertyType, 
propertyValue);
+
+                    // Check if we need to do an additional conversion
+                    if (convertedValue != null && 
parsedObjectConversionTargetType != null)
+                    {
+                        LogLog.Debug(declaringType, "Performing additional 
conversion of value from [" + convertedValue.GetType().Name + "] to [" + 
parsedObjectConversionTargetType.Name + "]");
+                        convertedValue = 
OptionConverter.ConvertTypeTo(convertedValue, parsedObjectConversionTargetType);
+                    }
+
+                    if (convertedValue != null)
+                    {
+                        if (propInfo != null)
+                        {
+                            // Got a converted result
+                            LogLog.Debug(declaringType, "Setting Property [" + 
propInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + 
convertedValue.ToString() + "]");
+
+                            try
+                            {
+                                // Pass to the property
+                                propInfo.SetValue(target, convertedValue, 
BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture);
+                            }
+                            catch (TargetInvocationException 
targetInvocationEx)
+                            {
+                                LogLog.Error(declaringType, "Failed to set 
parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + 
convertedValue + "]", targetInvocationEx.InnerException);
+                            }
+                        }
+                        else if (methInfo != null)
+                        {
+                            // Got a converted result
+                            LogLog.Debug(declaringType, "Setting Collection 
Property [" + methInfo.Name + "] to " + convertedValue.GetType().Name + " value 
[" + convertedValue.ToString() + "]");
+
+                            try
+                            {
+                                // Pass to the property
+                                methInfo.Invoke(target, 
BindingFlags.InvokeMethod, null, new object[] { convertedValue }, 
CultureInfo.InvariantCulture);
+                            }
+                            catch (TargetInvocationException 
targetInvocationEx)
+                            {
+                                LogLog.Error(declaringType, "Failed to set 
parameter [" + name + "] on object [" + target + "] using value [" + 
convertedValue + "]", targetInvocationEx.InnerException);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        LogLog.Warn(declaringType, "Unable to set property [" 
+ name + "] on object [" + target + "] using value [" + propertyValue + "] 
(with acceptable conversion types)");
+                    }
+                }
+                else
+                {
+                    object createdObject = null;
+
+                    if (propertyType == typeof(string) && 
!HasAttributesOrElements(element))
+                    {
+                        // If the property is a string and the element is 
empty (no attributes
+                        // or child elements) then we special case the object 
value to an empty string.
+                        // This is necessary because while the String is a 
class it does not have
+                        // a default constructor that creates an empty string, 
which is the behavior
+                        // we are trying to simulate and would be expected 
from CreateObjectFromXml
+                        createdObject = "";
+                    }
+                    else
+                    {
+                        // No value specified
+                        Type defaultObjectType = null;
+                        if (IsTypeConstructible(propertyType))
+                        {
+                            defaultObjectType = propertyType;
+                        }
+
+                        createdObject = CreateObjectFromXml(element, 
defaultObjectType, propertyType);
+                    }
+
+                    if (createdObject == null)
+                    {
+                        LogLog.Error(declaringType, "Failed to create object 
to set param: " + name);
+                    }
+                    else
+                    {
+                        if (propInfo != null)
+                        {
+                            // Got a converted result
+                            LogLog.Debug(declaringType, "Setting Property [" + 
propInfo.Name + "] to object [" + createdObject + "]");
+
+                            try
+                            {
+                                // Pass to the property
+                                propInfo.SetValue(target, createdObject, 
BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture);
+                            }
+                            catch (TargetInvocationException 
targetInvocationEx)
+                            {
+                                LogLog.Error(declaringType, "Failed to set 
parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + 
createdObject + "]", targetInvocationEx.InnerException);
+                            }
+                        }
+                        else if (methInfo != null)
+                        {
+                            // Got a converted result
+                            LogLog.Debug(declaringType, "Setting Collection 
Property [" + methInfo.Name + "] to object [" + createdObject + "]");
+
+                            try
+                            {
+                                // Pass to the property
+                                methInfo.Invoke(target, 
BindingFlags.InvokeMethod, null, new object[] { createdObject }, 
CultureInfo.InvariantCulture);
+                            }
+                            catch (TargetInvocationException 
targetInvocationEx)
+                            {
+                                LogLog.Error(declaringType, "Failed to set 
parameter [" + methInfo.Name + "] on object [" + target + "] using value [" + 
createdObject + "]", targetInvocationEx.InnerException);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Test if an element has no attributes or child elements
+        /// </summary>
+        /// <param name="element">the element to inspect</param>
+        /// <returns><c>true</c> if the element has any attributes or child 
elements, <c>false</c> otherwise</returns>
+        private bool HasAttributesOrElements(XmlElement element)
+        {
+            foreach (XmlNode node in element.ChildNodes)
+            {
+                if (node.NodeType == XmlNodeType.Attribute || node.NodeType == 
XmlNodeType.Element)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Test if a <see cref="Type"/> is constructible with 
<c>Activator.CreateInstance</c>.
+        /// </summary>
+        /// <param name="type">the type to inspect</param>
+        /// <returns><c>true</c> if the type is creatable using a default 
constructor, <c>false</c> otherwise</returns>
+        private static bool IsTypeConstructible(Type type)
+        {
+            if (type.IsClass && !type.IsAbstract)
+            {
+                ConstructorInfo defaultConstructor = type.GetConstructor(new 
Type[0]);
+                if (defaultConstructor != null && 
!defaultConstructor.IsAbstract && !defaultConstructor.IsPrivate)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
 
-                                       // Check if a specific subtype is 
specified on the element using the 'type' attribute
-                                       string subTypeString = 
element.GetAttribute(TYPE_ATTR);
-                                       if (subTypeString != null && 
subTypeString.Length > 0)
-                                       {
-                                               // Read the explicit subtype
-                                               try
-                                               {
-                                                       Type subType = 
SystemInfo.GetTypeFromString(subTypeString, true, true);
-
-                                                       
LogLog.Debug(declaringType, "Parameter ["+name+"] specified subtype 
["+subType.FullName+"]");
-
-                                                       if 
(!propertyType.IsAssignableFrom(subType))
-                                                       {
-                                                               // Check if 
there is an appropriate type converter
-                                                               if 
(OptionConverter.CanConvertTypeTo(subType, propertyType))
-                                                               {
-                                                                       // Must 
re-convert to the real property type
-                                                                       
parsedObjectConversionTargetType = propertyType;
-
-                                                                       // Use 
sub type as intermediary type
-                                                                       
propertyType = subType;
-                                                               }
-                                                               else
-                                                               {
-                                                                       
LogLog.Error(declaringType, "subtype ["+subType.FullName+"] set on ["+name+"] 
is not a subclass of property type ["+propertyType.FullName+"] and there are no 
acceptable type conversions.");
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               // The subtype 
specified is found and is actually a subtype of the property
-                                                               // type, 
therefore we can switch to using this type.
-                                                               propertyType = 
subType;
-                                                       }
-                                               }
-                                               catch(Exception ex)
-                                               {
-                                                       
LogLog.Error(declaringType, "Failed to find type ["+subTypeString+"] set on 
["+name+"]", ex);
-                                               }
-                                       }
-
-                                       // Now try to convert the string value 
to an acceptable type
-                                       // to pass to this property.
-
-                                       object convertedValue = 
ConvertStringTo(propertyType, propertyValue);
-                                       
-                                       // Check if we need to do an additional 
conversion
-                                       if (convertedValue != null && 
parsedObjectConversionTargetType != null)
-                                       {
-                                               LogLog.Debug(declaringType, 
"Performing additional conversion of value from [" + 
convertedValue.GetType().Name + "] to [" + 
parsedObjectConversionTargetType.Name + "]");
-                                               convertedValue = 
OptionConverter.ConvertTypeTo(convertedValue, parsedObjectConversionTargetType);
-                                       }
-
-                                       if (convertedValue != null)
-                                       {
-                                               if (propInfo != null)
-                                               {
-                                                       // Got a converted 
result
-                                                       
LogLog.Debug(declaringType, "Setting Property [" + propInfo.Name + "] to " + 
convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]");
-
-                                                       try
-                                                       {
-                                                               // Pass to the 
property
-                                                               
propInfo.SetValue(target, convertedValue, BindingFlags.SetProperty, null, null, 
CultureInfo.InvariantCulture);
-                                                       }
-                                                       
catch(TargetInvocationException targetInvocationEx)
-                                                       {
-                                                               
LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on 
object [" + target + "] using value [" + convertedValue + "]", 
targetInvocationEx.InnerException);
-                                                       }
-                                               }
-                                               else if (methInfo != null)
-                                               {
-                                                       // Got a converted 
result
-                                                       
LogLog.Debug(declaringType, "Setting Collection Property [" + methInfo.Name + 
"] to " + convertedValue.GetType().Name + " value [" + 
convertedValue.ToString() + "]");
-
-                                                       try
-                                                       {
-                                                               // Pass to the 
property
-                                                               
methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] 
{convertedValue}, CultureInfo.InvariantCulture);
-                                                       }
-                                                       
catch(TargetInvocationException targetInvocationEx)
-                                                       {
-                                                               
LogLog.Error(declaringType, "Failed to set parameter [" + name + "] on object 
[" + target + "] using value [" + convertedValue + "]", 
targetInvocationEx.InnerException);
-                                                       }
-                                               }
-                                       }
-                                       else
-                                       {
-                                               LogLog.Warn(declaringType, 
"Unable to set property [" + name + "] on object [" + target + "] using value 
[" + propertyValue + "] (with acceptable conversion types)");
-                                       }
-                               }
-                               else
-                               {
-                                       object createdObject = null;
-
-                                       if (propertyType == typeof(string) && 
!HasAttributesOrElements(element))
-                                       {
-                                               // If the property is a string 
and the element is empty (no attributes
-                                               // or child elements) then we 
special case the object value to an empty string.
-                                               // This is necessary because 
while the String is a class it does not have
-                                               // a default constructor that 
creates an empty string, which is the behavior
-                                               // we are trying to simulate 
and would be expected from CreateObjectFromXml
-                                               createdObject = "";
-                                       }
-                                       else
-                                       {
-                                               // No value specified
-                                               Type defaultObjectType = null;
-                                               if 
(IsTypeConstructible(propertyType))
-                                               {
-                                                       defaultObjectType = 
propertyType;
-                                               }
-
-                                               createdObject = 
CreateObjectFromXml(element, defaultObjectType, propertyType);
-                                       }
-
-                                       if (createdObject == null)
-                                       {
-                                               LogLog.Error(declaringType, 
"Failed to create object to set param: "+name);
-                                       }
-                                       else
-                                       {
-                                               if (propInfo != null)
-                                               {
-                                                       // Got a converted 
result
-                                                       
LogLog.Debug(declaringType, "Setting Property ["+ propInfo.Name +"] to object 
["+ createdObject +"]");
-
-                                                       try
-                                                       {
-                                                               // Pass to the 
property
-                                                               
propInfo.SetValue(target, createdObject, BindingFlags.SetProperty, null, null, 
CultureInfo.InvariantCulture);
-                                                       }
-                                                       
catch(TargetInvocationException targetInvocationEx)
-                                                       {
-                                                               
LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on 
object [" + target + "] using value [" + createdObject + "]", 
targetInvocationEx.InnerException);
-                                                       }
-                                               }
-                                               else if (methInfo != null)
-                                               {
-                                                       // Got a converted 
result
-                                                       
LogLog.Debug(declaringType, "Setting Collection Property ["+ methInfo.Name +"] 
to object ["+ createdObject +"]");
-
-                                                       try
-                                                       {
-                                                               // Pass to the 
property
-                                                               
methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] 
{createdObject}, CultureInfo.InvariantCulture);
-                                                       }
-                                                       
catch(TargetInvocationException targetInvocationEx)
-                                                       {
-                                                               
LogLog.Error(declaringType, "Failed to set parameter [" + methInfo.Name + "] on 
object [" + target + "] using value [" + createdObject + "]", 
targetInvocationEx.InnerException);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /// <summary>
-               /// Test if an element has no attributes or child elements
-               /// </summary>
-               /// <param name="element">the element to inspect</param>
-               /// <returns><c>true</c> if the element has any attributes or 
child elements, <c>false</c> otherwise</returns>
-               private bool HasAttributesOrElements(XmlElement element)
-               {
-                       foreach(XmlNode node in element.ChildNodes)
-                       {
-                               if (node.NodeType == XmlNodeType.Attribute || 
node.NodeType == XmlNodeType.Element)
-                               {
-                                       return true;
-                               }
-                       }
-                       return false;
-               }
-
-               /// <summary>
-               /// Test if a <see cref="Type"/> is constructible with 
<c>Activator.CreateInstance</c>.
-               /// </summary>
-               /// <param name="type">the type to inspect</param>
-               /// <returns><c>true</c> if the type is creatable using a 
default constructor, <c>false</c> otherwise</returns>
-               private static bool IsTypeConstructible(Type type)
-               {
-                       if (type.IsClass && !type.IsAbstract)
-                       {
-                               ConstructorInfo defaultConstructor = 
type.GetConstructor(new Type[0]);
-                               if (defaultConstructor != null && 
!defaultConstructor.IsAbstract && !defaultConstructor.IsPrivate)
-                               {
-                                       return true;
-                               }
-                       }
-                       return false;
-               }
-
-               /// <summary>
-               /// Look for a method on the <paramref name="targetType"/> that 
matches the <paramref name="name"/> supplied
-               /// </summary>
-               /// <param name="targetType">the type that has the 
method</param>
-               /// <param name="name">the name of the method</param>
-               /// <returns>the method info found</returns>
-               /// <remarks>
-               /// <para>
-               /// The method must be a public instance method on the 
<paramref name="targetType"/>.
-               /// The method must be named <paramref name="name"/> or "Add" 
followed by <paramref name="name"/>.
-               /// The method must take a single parameter.
-               /// </para>
-               /// </remarks>
-               private MethodInfo FindMethodInfo(Type targetType, string name)
-               {
-                       string requiredMethodNameA = name;
-                       string requiredMethodNameB = "Add" + name;
-
-                       MethodInfo[] methods = 
targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public | 
BindingFlags.NonPublic);
-
-                       foreach(MethodInfo methInfo in methods)
-                       {
-                               if (!methInfo.IsStatic)
-                               {
-                                       if (string.Compare(methInfo.Name, 
requiredMethodNameA, true, System.Globalization.CultureInfo.InvariantCulture) 
== 0 ||
-                                               string.Compare(methInfo.Name, 
requiredMethodNameB, true, System.Globalization.CultureInfo.InvariantCulture) 
== 0)
-                                       {
-                                               // Found matching method name
-
-                                               // Look for version with one 
arg only
-                                               
System.Reflection.ParameterInfo[] methParams = methInfo.GetParameters();
-                                               if (methParams.Length == 1)
-                                               {
-                                                       return methInfo;
-                                               }
-                                       }
-                               }
-                       }
-                       return null;
-               }
-
-               /// <summary>
-               /// Converts a string value to a target type.
-               /// </summary>
-               /// <param name="type">The type of object to convert the string 
to.</param>
-               /// <param name="value">The string value to use as the value of 
the object.</param>
-               /// <returns>
-               /// <para>
-               /// An object of type <paramref name="type"/> with value 
<paramref name="value"/> or 
-               /// <c>null</c> when the conversion could not be performed.
-               /// </para>
-               /// </returns>
-               protected object ConvertStringTo(Type type, string value)
-               {
-                       // Hack to allow use of Level in property
-                       if (typeof(Level) == type)
-                       {
-                               // Property wants a level
-                               Level levelValue = m_hierarchy.LevelMap[value];
-
-                               if (levelValue == null)
-                               {
-                                       LogLog.Error(declaringType, 
"XmlHierarchyConfigurator: Unknown Level Specified ["+ value +"]");
-                               }
-
-                               return levelValue;
-                       }
-                       return OptionConverter.ConvertStringTo(type, value);
-               }
-
-               /// <summary>
-               /// Creates an object as specified in XML.
-               /// </summary>
-               /// <param name="element">The XML element that contains the 
definition of the object.</param>
-               /// <param name="defaultTargetType">The object type to use if 
not explicitly specified.</param>
-               /// <param name="typeConstraint">The type that the returned 
object must be or must inherit from.</param>
-               /// <returns>The object or <c>null</c></returns>
-               /// <remarks>
-               /// <para>
-               /// Parse an XML element and create an object instance based on 
the configuration
-               /// data.
-               /// </para>
-               /// <para>
-               /// The type of the instance may be specified in the XML. If not
-               /// specified then the <paramref name="defaultTargetType"/> is 
used
-               /// as the type. However the type is specified it must support 
the
-               /// <paramref name="typeConstraint"/> type.
-               /// </para>
-               /// </remarks>
-               protected object CreateObjectFromXml(XmlElement element, Type 
defaultTargetType, Type typeConstraint) 
-               {
-                       Type objectType = null;
-
-                       // Get the object type
-                       string objectTypeString = 
element.GetAttribute(TYPE_ATTR);
-                       if (objectTypeString == null || objectTypeString.Length 
== 0)
-                       {
-                               if (defaultTargetType == null)
-                               {
-                                       LogLog.Error(declaringType, "Object 
type not specified. Cannot create object of type ["+typeConstraint.FullName+"]. 
Missing Value or Type.");
-                                       return null;
-                               }
-                               else
-                               {
-                                       // Use the default object type
-                                       objectType = defaultTargetType;
-                               }
-                       }
-                       else
-                       {
-                               // Read the explicit object type
-                               try
-                               {
-                                       objectType = 
SystemInfo.GetTypeFromString(objectTypeString, true, true);
-                               }
-                               catch(Exception ex)
-                               {
-                                       LogLog.Error(declaringType, "Failed to 
find type ["+objectTypeString+"]", ex);
-                                       return null;
-                               }
-                       }
-
-                       bool requiresConversion = false;
-
-                       // Got the object type. Check that it meets the 
typeConstraint
-                       if (typeConstraint != null)
-                       {
-                               if 
(!typeConstraint.IsAssignableFrom(objectType))
-                               {
-                                       // Check if there is an appropriate 
type converter
-                                       if 
(OptionConverter.CanConvertTypeTo(objectType, typeConstraint))
-                                       {
-                                               requiresConversion = true;
-                                       }
-                                       else
-                                       {
-                                               LogLog.Error(declaringType, 
"Object type ["+objectType.FullName+"] is not assignable to type 
["+typeConstraint.FullName+"]. There are no acceptable type conversions.");
-                                               return null;
-                                       }
-                               }
-                       }
-
-                       // Create using the default constructor
-                       object createdObject = null;
-                       try
-                       {
-                               createdObject = 
Activator.CreateInstance(objectType);
-                       }
-                       catch(Exception createInstanceEx)
-                       {
-                               LogLog.Error(declaringType, 
"XmlHierarchyConfigurator: Failed to construct object of type [" + 
objectType.FullName + "] Exception: "+createInstanceEx.ToString());
-                       }
-
-                       // Set any params on object
-                       foreach (XmlNode currentNode in element.ChildNodes)
-                       {
-                               if (currentNode.NodeType == 
XmlNodeType.Element) 
-                               {
-                                       SetParameter((XmlElement)currentNode, 
createdObject);
-                               }
-                       }
-
-                       // Check if we need to call ActivateOptions
-                       IOptionHandler optionHandler = createdObject as 
IOptionHandler;
-                       if (optionHandler != null)
-                       {
-                               optionHandler.ActivateOptions();
-                       }
-
-                       // Ok object should be initialized
-
-                       if (requiresConversion)
-                       {
-                               // Convert the object type
-                               return 
OptionConverter.ConvertTypeTo(createdObject, typeConstraint);
-                       }
-                       else
-                       {
-                               // The object is of the correct type
-                               return createdObject;
-                       }
-               }
+        /// <summary>
+        /// Look for a method on the <paramref name="targetType"/> that 
matches the <paramref name="name"/> supplied
+        /// </summary>
+        /// <param name="targetType">the type that has the method</param>
+        /// <param name="name">the name of the method</param>
+        /// <returns>the method info found</returns>
+        /// <remarks>
+        /// <para>
+        /// The method must be a public instance method on the <paramref 
name="targetType"/>.
+        /// The method must be named <paramref name="name"/> or "Add" followed 
by <paramref name="name"/>.
+        /// The method must take a single parameter.
+        /// </para>
+        /// </remarks>
+        private MethodInfo FindMethodInfo(Type targetType, string name)
+        {
+            string requiredMethodNameA = name;
+            string requiredMethodNameB = "Add" + name;
 
-               #endregion Protected Instance Methods
+            MethodInfo[] methods = targetType.GetMethods(BindingFlags.Instance 
| BindingFlags.Public | BindingFlags.NonPublic);
+
+            foreach (MethodInfo methInfo in methods)
+            {
+                if (!methInfo.IsStatic)
+                {
+                    if (string.Compare(methInfo.Name, requiredMethodNameA, 
true, System.Globalization.CultureInfo.InvariantCulture) == 0 ||
+                        string.Compare(methInfo.Name, requiredMethodNameB, 
true, System.Globalization.CultureInfo.InvariantCulture) == 0)
+                    {
+                        // Found matching method name
+
+                        // Look for version with one arg only
+                        System.Reflection.ParameterInfo[] methParams = 
methInfo.GetParameters();
+                        if (methParams.Length == 1)
+                        {
+                            return methInfo;
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /// <summary>
+        /// Converts a string value to a target type.
+        /// </summary>
+        /// <param name="type">The type of object to convert the string 
to.</param>
+        /// <param name="value">The string value to use as the value of the 
object.</param>
+        /// <returns>
+        /// <para>
+        /// An object of type <paramref name="type"/> with value <paramref 
name="value"/> or 
+        /// <c>null</c> when the conversion could not be performed.
+        /// </para>
+        /// </returns>
+        protected object ConvertStringTo(Type type, string value)
+        {
+            // Hack to allow use of Level in property
+            if (typeof(Level) == type)
+            {
+                // Property wants a level
+                Level levelValue = m_hierarchy.LevelMap[value];
+
+                if (levelValue == null)
+                {
+                    LogLog.Error(declaringType, "XmlHierarchyConfigurator: 
Unknown Level Specified [" + value + "]");
+                }
+
+                return levelValue;
+            }
+            return OptionConverter.ConvertStringTo(type, value);
+        }
+
+        /// <summary>
+        /// Creates an object as specified in XML.
+        /// </summary>
+        /// <param name="element">The XML element that contains the definition 
of the object.</param>
+        /// <param name="defaultTargetType">The object type to use if not 
explicitly specified.</param>
+        /// <param name="typeConstraint">The type that the returned object 
must be or must inherit from.</param>
+        /// <returns>The object or <c>null</c></returns>
+        /// <remarks>
+        /// <para>
+        /// Parse an XML element and create an object instance based on the 
configuration
+        /// data.
+        /// </para>
+        /// <para>
+        /// The type of the instance may be specified in the XML. If not
+        /// specified then the <paramref name="defaultTargetType"/> is used
+        /// as the type. However the type is specified it must support the
+        /// <paramref name="typeConstraint"/> type.
+        /// </para>
+        /// </remarks>
+        protected object CreateObjectFromXml(XmlElement element, Type 
defaultTargetType, Type typeConstraint)
+        {
+            Type objectType = null;
+
+            // Get the object type
+            string objectTypeString = element.GetAttribute(TYPE_ATTR);
+            if (objectTypeString == null || objectTypeString.Length == 0)
+            {
+                if (defaultTargetType == null)
+                {
+                    LogLog.Error(declaringType, "Object type not specified. 
Cannot create object of type [" + typeConstraint.FullName + "]. Missing Value 
or Type.");
+                    return null;
+                }
+                else
+                {
+                    // Use the default object type
+                    objectType = defaultTargetType;
+                }
+            }
+            else
+            {
+                // Read the explicit object type
+                try
+                {
+                    objectType = 
SystemInfo.GetTypeFromString(objectTypeString, true, true);
+                }
+                catch (Exception ex)
+                {
+                    LogLog.Error(declaringType, "Failed to find type [" + 
objectTypeString + "]", ex);
+                    return null;
+                }
+            }
+
+            bool requiresConversion = false;
+
+            // Got the object type. Check that it meets the typeConstraint
+            if (typeConstraint != null)
+            {
+                if (!typeConstraint.IsAssignableFrom(objectType))
+                {
+                    // Check if there is an appropriate type converter
+                    if (OptionConverter.CanConvertTypeTo(objectType, 
typeConstraint))
+                    {
+                        requiresConversion = true;
+                    }
+                    else
+                    {
+                        LogLog.Error(declaringType, "Object type [" + 
objectType.FullName + "] is not assignable to type [" + typeConstraint.FullName 
+ "]. There are no acceptable type conversions.");
+                        return null;
+                    }
+                }
+            }
+
+            // Create using the default constructor
+            object createdObject = null;
+            try
+            {
+                createdObject = Activator.CreateInstance(objectType);
+            }
+            catch (Exception createInstanceEx)
+            {
+                LogLog.Error(declaringType, "XmlHierarchyConfigurator: Failed 
to construct object of type [" + objectType.FullName + "] Exception: " + 
createInstanceEx.ToString());
+            }
+
+            // Set any params on object
+            foreach (XmlNode currentNode in element.ChildNodes)
+            {
+                if (currentNode.NodeType == XmlNodeType.Element)
+                {
+                    SetParameter((XmlElement)currentNode, createdObject);
+                }
+            }
+
+            // Check if we need to call ActivateOptions
+            IOptionHandler optionHandler = createdObject as IOptionHandler;
+            if (optionHandler != null)
+            {
+                optionHandler.ActivateOptions();
+            }
+
+            // Ok object should be initialized
+
+            if (requiresConversion)
+            {
+                // Convert the object type
+                return OptionConverter.ConvertTypeTo(createdObject, 
typeConstraint);
+            }
+            else
+            {
+                // The object is of the correct type
+                return createdObject;
+            }
+        }
+
+        #endregion Protected Instance Methods
 
 #if !NETCF
-               private bool HasCaseInsensitiveEnvironment
-               {
-                   get
-                   {
-                       PlatformID platform = Environment.OSVersion.Platform;
-                       return platform != PlatformID.Unix && platform != 
PlatformID.MacOSX;
-                   }
-               }
-
-               private IDictionary CreateCaseInsensitiveWrapper(IDictionary 
dict)
-               {
-                   if (dict == null)
-                   {
-                       return dict;
-                   }
-                   Hashtable hash = 
SystemInfo.CreateCaseInsensitiveHashtable();
-                   foreach (DictionaryEntry entry in dict) {
-                       hash[entry.Key] = entry.Value;
-                   }
-                   return hash;
-               }
+        private bool HasCaseInsensitiveEnvironment
+        {
+            get
+            {
+                PlatformID platform = Environment.OSVersion.Platform;
+                return platform != PlatformID.Unix && platform != 
PlatformID.MacOSX;
+            }
+        }
+
+        private IDictionary CreateCaseInsensitiveWrapper(IDictionary dict)
+        {
+            if (dict == null)
+            {
+                return dict;
+            }
+            Hashtable hash = SystemInfo.CreateCaseInsensitiveHashtable();
+            foreach (DictionaryEntry entry in dict)
+            {
+                hash[entry.Key] = entry.Value;
+            }
+            return hash;
+        }
 #endif
 
-               #region Private Constants
+        #region Private Constants
 
-               // String constants used while parsing the XML data
-               private const string CONFIGURATION_TAG                  = 
"log4net";
-               private const string RENDERER_TAG                               
= "renderer";
-               private const string APPENDER_TAG                               
= "appender";
-               private const string APPENDER_REF_TAG                   = 
"appender-ref";  
-               private const string PARAM_TAG                                  
= "param";
-
-               // TODO: Deprecate use of category tags
-               private const string CATEGORY_TAG                               
= "category";
-               // TODO: Deprecate use of priority tag
-               private const string PRIORITY_TAG                               
= "priority";
-
-               private const string LOGGER_TAG                                 
= "logger";
-               private const string NAME_ATTR                                  
= "name";
-               private const string TYPE_ATTR                                  
= "type";
-               private const string VALUE_ATTR                                 
= "value";
-               private const string ROOT_TAG                                   
= "root";
-               private const string LEVEL_TAG                                  
= "level";
-               private const string REF_ATTR                                   
= "ref";
-               private const string ADDITIVITY_ATTR                    = 
"additivity";  
-               private const string THRESHOLD_ATTR                             
= "threshold";
-               private const string CONFIG_DEBUG_ATTR                  = 
"configDebug";
-               private const string INTERNAL_DEBUG_ATTR                = 
"debug";
-               private const string EMIT_INTERNAL_DEBUG_ATTR   = "emitDebug";
-               private const string CONFIG_UPDATE_MODE_ATTR    = "update";
-               private const string RENDERING_TYPE_ATTR                = 
"renderingClass";
-               private const string RENDERED_TYPE_ATTR                 = 
"renderedClass";
-
-               // flag used on the level element
-               private const string INHERITED = "inherited";
-
-               #endregion Private Constants
-
-               #region Private Instance Fields
-
-               /// <summary>
-               /// key: appenderName, value: appender.
-               /// </summary>
-               private Hashtable m_appenderBag;
-
-               /// <summary>
-               /// The Hierarchy being configured.
-               /// </summary>
-               private readonly Hierarchy m_hierarchy;
-
-               #endregion Private Instance Fields
-
-           #region Private Static Fields
-
-           /// <summary>
-           /// The fully qualified type of the XmlHierarchyConfigurator class.
-           /// </summary>
-           /// <remarks>
-           /// Used by the internal logger to record the Type of the
-           /// log message.
-           /// </remarks>
-           private readonly static Type declaringType = 
typeof(XmlHierarchyConfigurator);
+        // String constants used while parsing the XML data
+        private const string CONFIGURATION_TAG = "log4net";
+        private const string RENDERER_TAG = "renderer";
+        private const string APPENDER_TAG = "appender";
+        private const string APPENDER_REF_TAG = "appender-ref";
+        private const string PARAM_TAG = "param";
+
+        // TODO: Deprecate use of category tags
+        private const string CATEGORY_TAG = "category";
+        // TODO: Deprecate use of priority tag
+        private const string PRIORITY_TAG = "priority";
+
+        private const string LOGGER_TAG = "logger";
+        private const string NAME_ATTR = "name";
+        private const string TYPE_ATTR = "type";
+        private const string VALUE_ATTR = "value";
+        private const string ROOT_TAG = "root";
+        private const string LEVEL_TAG = "level";
+        private const string REF_ATTR = "ref";
+        private const string ADDITIVITY_ATTR = "additivity";
+        private const string THRESHOLD_ATTR = "threshold";
+        private const string CONFIG_DEBUG_ATTR = "configDebug";
+        private const string INTERNAL_DEBUG_ATTR = "debug";
+        private const string EMIT_INTERNAL_DEBUG_ATTR = "emitDebug";
+        private const string CONFIG_UPDATE_MODE_ATTR = "update";
+        private const string RENDERING_TYPE_ATTR = "renderingClass";
+        private const string RENDERED_TYPE_ATTR = "renderedClass";
+
+        // flag used on the level element
+        private const string INHERITED = "inherited";
+
+        #endregion Private Constants
+
+        #region Private Instance Fields
+
+        /// <summary>
+        /// key: appenderName, value: appender.
+        /// </summary>
+        private Hashtable m_appenderBag;
+
+        /// <summary>
+        /// The Hierarchy being configured.
+        /// </summary>
+        private readonly Hierarchy m_hierarchy;
+
+        #endregion Private Instance Fields
+
+        #region Private Static Fields
+
+        /// <summary>
+        /// The fully qualified type of the XmlHierarchyConfigurator class.
+        /// </summary>
+        /// <remarks>
+        /// Used by the internal logger to record the Type of the
+        /// log message.
+        /// </remarks>
+        private readonly static Type declaringType = 
typeof(XmlHierarchyConfigurator);
 
-           #endregion Private Static Fields
-       }
+        #endregion Private Static Fields
+    }
 }


Reply via email to