#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections;
using log4net.Appender;
using log4net.Core;
using log4net.Util;

namespace log4net.Repository.Hierarchy
{
	#region LoggerCreationEvent

	/// <summary>
	/// Delegate used to handle logger creation event notifications.
	/// </summary>
	/// <param name="sender">The <see cref="Hierarchy"/> in which the <see cref="Logger"/> has been created.</param>
	/// <param name="e">The <see cref="LoggerCreationEventArgs"/> event args that hold the <see cref="Logger"/> instance that has been created.</param>
	/// <remarks>
	/// <para>
	/// Delegate used to handle logger creation event notifications.
	/// </para>
	/// </remarks>
	public delegate void LoggerCreationEventHandler(object sender, LoggerCreationEventArgs e);

	/// <summary>
	/// Provides data for the <see cref="Hierarchy.LoggerCreatedEvent"/> event.
	/// </summary>
	/// <remarks>
	/// <para>
	/// A <see cref="Hierarchy.LoggerCreatedEvent"/> event is raised every time a
	/// <see cref="Logger"/> is created.
	/// </para>
	/// </remarks>
	public class LoggerCreationEventArgs : EventArgs
	{
		/// <summary>
		/// The <see cref="Logger"/> created
		/// </summary>
		private Logger m_log;

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="log">The <see cref="Logger"/> that has been created.</param>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="LoggerCreationEventArgs" /> event argument
		/// class,with the specified <see cref="Logger"/>.
		/// </para>
		/// </remarks>
		public LoggerCreationEventArgs(Logger log)
		{
			m_log = log;
		}

		/// <summary>
		/// Gets the <see cref="Logger"/> that has been created.
		/// </summary>
		/// <value>
		/// The <see cref="Logger"/> that has been created.
		/// </value>
		/// <remarks>
		/// <para>
		/// The <see cref="Logger"/> that has been created.
		/// </para>
		/// </remarks>
		public Logger Logger
		{
			get { return m_log; }
		}
	}

	#endregion LoggerCreationEvent

	/// <summary>
	/// Hierarchical organization of loggers
	/// </summary>
	/// <remarks>
	/// <para>
	/// <i>The casual user should not have to deal with this class
	/// directly.</i>
	/// </para>
	/// <para>
	/// This class is specialized in retrieving loggers by name and
	/// also maintaining the logger hierarchy. Implements the
	/// <see cref="ILoggerRepository"/> interface.
	/// </para>
	/// <para>
	/// The structure of the logger hierarchy is maintained by the
	/// <see cref="M:GetLogger(string)"/> method. The hierarchy is such that children
	/// link to their parent but parents do not have any references to their
	/// children. Moreover, loggers can be instantiated in any order, in
	/// particular descendant before ancestor.
	/// </para>
	/// <para>
	/// In case a descendant is created before a particular ancestor,
	/// then it creates a provision node for the ancestor and adds itself
	/// to the provision node. Other descendants of the same ancestor add
	/// themselves to the previously created provision node.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	public class Hierarchy : LoggerRepositorySkeleton, IBasicRepositoryConfigurator, IXmlRepositoryConfigurator
	{
		#region Public Events

		/// <summary>
		/// Event used to notify that a logger has been created.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Event raised when a logger is created.
		/// </para>
		/// </remarks>
		public event LoggerCreationEventHandler LoggerCreatedEvent
		{
			add { m_loggerCreatedEvent += value; }
			remove { m_loggerCreatedEvent -= value; }
		}

		#endregion Public Events

		#region Public Instance Constructors

		/// <summary>
		/// Default constructor
		/// </summary>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="Hierarchy" /> class.
		/// </para>
		/// </remarks>
		public Hierarchy() : this(new DefaultLoggerFactory())
		{
		}

		/// <summary>
		/// Construct with properties
		/// </summary>
		/// <param name="properties">The properties to pass to this repository.</param>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="Hierarchy" /> class.
		/// </para>
		/// </remarks>
		public Hierarchy(PropertiesDictionary properties) : this(properties, new DefaultLoggerFactory())
		{
		}

		/// <summary>
		/// Construct with a logger factory
		/// </summary>
		/// <param name="loggerFactory">The factory to use to create new logger instances.</param>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="Hierarchy" /> class with
		/// the specified <see cref="ILoggerFactory" />.
		/// </para>
		/// </remarks>
		public Hierarchy(ILoggerFactory loggerFactory) : this(new PropertiesDictionary(), loggerFactory)
		{
		}

		/// <summary>
		/// Construct with properties and a logger factory
		/// </summary>
		/// <param name="properties">The properties to pass to this repository.</param>
		/// <param name="loggerFactory">The factory to use to create new logger instances.</param>
		/// <remarks>
		/// <para>
		/// Initializes a new instance of the <see cref="Hierarchy" /> class with
		/// the specified <see cref="ILoggerFactory" />.
		/// </para>
		/// </remarks>
		public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory) : base(properties)
		{
			if (loggerFactory == null)
			{
				throw new ArgumentNullException("loggerFactory");
			}

			m_defaultFactory = loggerFactory;

			m_ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
		}

		#endregion Public Instance Constructors

		#region Public Instance Properties

		/// <summary>
		/// Has no appender warning been emitted
		/// </summary>
		/// <remarks>
		/// <para>
		/// Flag to indicate if we have already issued a warning
		/// about not having an appender warning.
		/// </para>
		/// </remarks>
		public bool EmittedNoAppenderWarning
		{
			get { return m_emittedNoAppenderWarning; }
			set { m_emittedNoAppenderWarning = value; }
		}

		/// <summary>
		/// Get the root of this hierarchy
		/// </summary>
		/// <remarks>
		/// <para>
		/// Get the root of this hierarchy.
		/// </para>
		/// </remarks>
		public Logger Root
		{
			get
			{
				if (m_root == null)
				{
					lock (this)
					{
						if (m_root == null)
						{
							// Create the root logger
							Logger root = m_defaultFactory.CreateLogger(this, null);
							root.Hierarchy = this;

							// Store root
							m_root = root;
						}
					}
				}
				return m_root;
			}
		}

		/// <summary>
		/// Gets or sets the default <see cref="ILoggerFactory" /> instance.
		/// </summary>
		/// <value>The default <see cref="ILoggerFactory" /></value>
		/// <remarks>
		/// <para>
		/// The logger factory is used to create logger instances.
		/// </para>
		/// </remarks>
		public ILoggerFactory LoggerFactory
		{
			get { return m_defaultFactory; }
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				m_defaultFactory = value;
			}
		}

		#endregion Public Instance Properties

		#region Override Implementation of LoggerRepositorySkeleton

		/// <summary>
		/// Test if a logger exists
		/// </summary>
		/// <param name="name">The name of the logger to lookup</param>
		/// <returns>The Logger object with the name specified</returns>
		/// <remarks>
		/// <para>
		/// Check if the named logger exists in the hierarchy. If so return
		/// its reference, otherwise returns <c>null</c>.
		/// </para>
		/// </remarks>
		override public ILogger Exists(string name)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}

			lock (m_ht)
			{
				return m_ht[new LoggerKey(name)] as Logger;
			}
		}

		/// <summary>
		/// Returns all the currently defined loggers in the hierarchy as an Array
		/// </summary>
		/// <returns>All the defined loggers</returns>
		/// <remarks>
		/// <para>
		/// Returns all the currently defined loggers in the hierarchy as an Array.
		/// The root logger is <b>not</b> included in the returned
		/// enumeration.
		/// </para>
		/// </remarks>
		override public ILogger[] GetCurrentLoggers()
		{
			// The accumulation in loggers is necessary because not all elements in
			// ht are Logger objects as there might be some ProvisionNodes
			// as well.
			lock (m_ht)
			{
				System.Collections.ArrayList loggers = new System.Collections.ArrayList(m_ht.Count);

				// Iterate through m_ht values
				foreach (object node in m_ht.Values)
				{
					if (node is Logger)
					{
						loggers.Add(node);
					}
				}
				return (Logger[])loggers.ToArray(typeof(Logger));
			}
		}

		/// <summary>
		/// Return a new logger instance named as the first parameter using
		/// the default factory.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Return a new logger instance named as the first parameter using
		/// the default factory.
		/// </para>
		/// <para>
		/// If a logger of that name already exists, then it will be
		/// returned.  Otherwise, a new logger will be instantiated and
		/// then linked with its existing ancestors as well as children.
		/// </para>
		/// </remarks>
		/// <param name="name">The name of the logger to retrieve</param>
		/// <returns>The logger object with the name specified</returns>
		override public ILogger GetLogger(string name)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}

			return GetLogger(name, m_defaultFactory);
		}

		/// <summary>
		/// Shutting down a hierarchy will <i>safely</i> close and remove
		/// all appenders in all loggers including the root logger.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Shutting down a hierarchy will <i>safely</i> close and remove
		/// all appenders in all loggers including the root logger.
		/// </para>
		/// <para>
		/// Some appenders need to be closed before the
		/// application exists. Otherwise, pending logging events might be
		/// lost.
		/// </para>
		/// <para>
		/// The <c>Shutdown</c> method is careful to close nested
		/// appenders before closing regular appenders. This is allows
		/// configurations where a regular appender is attached to a logger
		/// and again to a nested appender.
		/// </para>
		/// </remarks>
		override public void Shutdown()
		{
			LogLog.Debug(declaringType, "Shutdown called on Hierarchy [" + this.Name + "]");

			// begin by closing nested appenders
			Root.CloseNestedAppenders();

			lock (m_ht)
			{
				ILogger[] currentLoggers = this.GetCurrentLoggers();

				foreach (Logger logger in currentLoggers)
				{
					logger.CloseNestedAppenders();
				}

				// then, remove all appenders
				Root.RemoveAllAppenders();

				foreach (Logger logger in currentLoggers)
				{
					logger.RemoveAllAppenders();
				}
			}

			base.Shutdown();
		}

		/// <summary>
		/// Reset all values contained in this hierarchy instance to their default.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Reset all values contained in this hierarchy instance to their
		/// default.  This removes all appenders from all loggers, sets
		/// the level of all non-root loggers to <c>null</c>,
		/// sets their additivity flag to <c>true</c> and sets the level
		/// of the root logger to <see cref="Level.Debug"/>. Moreover,
		/// message disabling is set its default "off" value.
		/// </para>
		/// <para>
		/// Existing loggers are not removed. They are just reset.
		/// </para>
		/// <para>
		/// This method should be used sparingly and with care as it will
		/// block all logging until it is completed.
		/// </para>
		/// </remarks>
		override public void ResetConfiguration()
		{
			Root.Level = LevelMap.LookupWithDefault(Level.Debug);
			Threshold = LevelMap.LookupWithDefault(Level.All);

			// the synchronization is needed to prevent hashtable surprises
			lock (m_ht)
			{
				Shutdown(); // nested locks are OK

				foreach (Logger l in this.GetCurrentLoggers())
				{
					l.Level = null;
					l.Additivity = true;
				}
			}

			base.ResetConfiguration();

			// Notify listeners
			OnConfigurationChanged(null);
		}

		/// <summary>
		/// Log the logEvent through this hierarchy.
		/// </summary>
		/// <param name="logEvent">the event to log</param>
		/// <remarks>
		/// <para>
		/// This method should not normally be used to log.
		/// The <see cref="ILog"/> interface should be used
		/// for routine logging. This interface can be obtained
		/// using the <see cref="M:log4net.LogManager.GetLogger(string)"/> method.
		/// </para>
		/// <para>
		/// The <c>logEvent</c> is delivered to the appropriate logger and
		/// that logger is then responsible for logging the event.
		/// </para>
		/// </remarks>
		override public void Log(LoggingEvent logEvent)
		{
			if (logEvent == null)
			{
				throw new ArgumentNullException("logEvent");
			}

			this.GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent);
		}

		/// <summary>
		/// Returns all the Appenders that are currently configured
		/// </summary>
		/// <returns>An array containing all the currently configured appenders</returns>
		/// <remarks>
		/// <para>
		/// Returns all the <see cref="log4net.Appender.IAppender"/> instances that are currently configured.
		/// All the loggers are searched for appenders. The appenders may also be containers
		/// for appenders and these are also searched for additional loggers.
		/// </para>
		/// <para>
		/// The list returned is unordered but does not contain duplicates.
		/// </para>
		/// </remarks>
		override public Appender.IAppender[] GetAppenders()
		{
			System.Collections.ArrayList appenderList = new System.Collections.ArrayList();

			CollectAppenders(appenderList, Root);

			foreach (Logger logger in GetCurrentLoggers())
			{
				CollectAppenders(appenderList, logger);
			}

			return (Appender.IAppender[])appenderList.ToArray(typeof(Appender.IAppender));
		}

		#endregion Override Implementation of LoggerRepositorySkeleton

		#region Private Static Methods

		/// <summary>
		/// Collect the appenders from an <see cref="IAppenderAttachable"/>.
		/// The appender may also be a container.
		/// </summary>
		/// <param name="appenderList"></param>
		/// <param name="appender"></param>
		private static void CollectAppender(System.Collections.ArrayList appenderList, Appender.IAppender appender)
		{
			if (!appenderList.Contains(appender))
			{
				appenderList.Add(appender);

				IAppenderAttachable container = appender as IAppenderAttachable;
				if (container != null)
				{
					CollectAppenders(appenderList, container);
				}
			}
		}

		/// <summary>
		/// Collect the appenders from an <see cref="IAppenderAttachable"/> container
		/// </summary>
		/// <param name="appenderList"></param>
		/// <param name="container"></param>
		private static void CollectAppenders(System.Collections.ArrayList appenderList, IAppenderAttachable container)
		{
			foreach (Appender.IAppender appender in container.Appenders)
			{
				CollectAppender(appenderList, appender);
			}
		}

		#endregion

		#region Implementation of IBasicRepositoryConfigurator

		/// <summary>
		/// Initialize the log4net system using the specified appender
		/// </summary>
		/// <param name="appender">the appender to use to log all logging events</param>
		void IBasicRepositoryConfigurator.Configure(IAppender appender)
		{
			BasicRepositoryConfigure(appender);
		}

		/// <summary>
		/// Initialize the log4net system using the specified appenders
		/// </summary>
		/// <param name="appenders">the appenders to use to log all logging events</param>
		void IBasicRepositoryConfigurator.Configure(params IAppender[] appenders)
		{
			BasicRepositoryConfigure(appenders);
		}

		/// <summary>
		/// Initialize the log4net system using the specified appenders
		/// </summary>
		/// <param name="appenders">the appenders to use to log all logging events</param>
		/// <remarks>
		/// <para>
		/// This method provides the same functionality as the
		/// <see cref="M:IBasicRepositoryConfigurator.Configure(IAppender)"/> method implemented
		/// on this object, but it is protected and therefore can be called by subclasses.
		/// </para>
		/// </remarks>
		protected void BasicRepositoryConfigure(params IAppender[] appenders)
		{
			ArrayList configurationMessages = new ArrayList();

			using (new LogLog.LogReceivedAdapter(configurationMessages))
			{
				foreach (IAppender appender in appenders)
				{
					Root.AddAppender(appender);
				}
			}

			Configured = true;

			ConfigurationMessages = configurationMessages;

			// Notify listeners
			OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages));
		}

		#endregion Implementation of IBasicRepositoryConfigurator

		#region Implementation of IXmlRepositoryConfigurator

		/// <summary>
		/// Initialize the log4net system using the specified config
		/// </summary>
		/// <param name="element">the element containing the root of the config</param>
		void IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement element)
		{
			XmlRepositoryConfigure(element);
		}

		/// <summary>
		/// Initialize the log4net system using the specified config
		/// </summary>
		/// <param name="element">the element containing the root of the config</param>
		/// <remarks>
		/// <para>
		/// This method provides the same functionality as the
		/// <see cref="M:IBasicRepositoryConfigurator.Configure(IAppender)"/> method implemented
		/// on this object, but it is protected and therefore can be called by subclasses.
		/// </para>
		/// </remarks>
		protected void XmlRepositoryConfigure(System.Xml.XmlElement element)
		{
			ArrayList configurationMessages = new ArrayList();

			using (new LogLog.LogReceivedAdapter(configurationMessages))
			{
				XmlHierarchyConfigurator config = new XmlHierarchyConfigurator(this);
				config.Configure(element);
			}

			Configured = true;

			ConfigurationMessages = configurationMessages;

			// Notify listeners
			OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages));
		}

		#endregion Implementation of IXmlRepositoryConfigurator

		#region Public Instance Methods

		/// <summary>
		/// Test if this hierarchy is disabled for the specified <see cref="Level"/>.
		/// </summary>
		/// <param name="level">The level to check against.</param>
		/// <returns>
		/// <c>true</c> if the repository is disabled for the level argument, <c>false</c> otherwise.
		/// </returns>
		/// <remarks>
		/// <para>
		/// If this hierarchy has not been configured then this method will
		/// always return <c>true</c>.
		/// </para>
		/// <para>
		/// This method will return <c>true</c> if this repository is
		/// disabled for <c>level</c> object passed as parameter and
		/// <c>false</c> otherwise.
		/// </para>
		/// <para>
		/// See also the <see cref="ILoggerRepository.Threshold"/> property.
		/// </para>
		/// </remarks>
		public bool IsDisabled(Level level)
		{
			// Cast level to object for performance
			if ((object)level == null)
			{
				throw new ArgumentNullException("level");
			}

			if (Configured)
			{
				return Threshold > level;
			}
			else
			{
				// If not configured the hierarchy is effectively disabled
				return true;
			}
		}

		/// <summary>
		/// Clear all logger definitions from the internal hashtable
		/// </summary>
		/// <remarks>
		/// <para>
		/// This call will clear all logger definitions from the internal
		/// hashtable. Invoking this method will irrevocably mess up the
		/// logger hierarchy.
		/// </para>
		/// <para>
		/// You should <b>really</b> know what you are doing before
		/// invoking this method.
		/// </para>
		/// </remarks>
		public void Clear()
		{
			lock (m_ht)
			{
				m_ht.Clear();
			}
		}

		/// <summary>
		/// Return a new logger instance named as the first parameter using
		/// <paramref name="factory"/>.
		/// </summary>
		/// <param name="name">The name of the logger to retrieve</param>
		/// <param name="factory">The factory that will make the new logger instance</param>
		/// <returns>The logger object with the name specified</returns>
		/// <remarks>
		/// <para>
		/// If a logger of that name already exists, then it will be
		/// returned. Otherwise, a new logger will be instantiated by the
		/// <paramref name="factory"/> parameter and linked with its existing
		/// ancestors as well as children.
		/// </para>
		/// </remarks>
		public Logger GetLogger(string name, ILoggerFactory factory)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			if (factory == null)
			{
				throw new ArgumentNullException("factory");
			}

			LoggerKey key = new LoggerKey(name);

			// Synchronize to prevent write conflicts. Read conflicts (in
			// GetEffectiveLevel() method) are possible only if variable
			// assignments are non-atomic.

			lock (m_ht)
			{
				Logger logger = null;

				Object node = m_ht[key];
				if (node == null)
				{
					logger = factory.CreateLogger(this, name);
					logger.Hierarchy = this;
					m_ht[key] = logger;
					UpdateParents(logger);
					OnLoggerCreationEvent(logger);
					return logger;
				}

				Logger nodeLogger = node as Logger;
				if (nodeLogger != null)
				{
					return nodeLogger;
				}

				ProvisionNode nodeProvisionNode = node as ProvisionNode;
				if (nodeProvisionNode != null)
				{
					logger = factory.CreateLogger(this, name);
					logger.Hierarchy = this;
					m_ht[key] = logger;
					UpdateChildren(nodeProvisionNode, logger);
					UpdateParents(logger);
					OnLoggerCreationEvent(logger);
					return logger;
				}

				// It should be impossible to arrive here but let's keep the compiler happy.
				return null;
			}
		}

		#endregion Public Instance Methods

		#region Protected Instance Methods

		/// <summary>
		/// Sends a logger creation event to all registered listeners
		/// </summary>
		/// <param name="logger">The newly created logger</param>
		/// <remarks>
		/// Raises the logger creation event.
		/// </remarks>
		protected virtual void OnLoggerCreationEvent(Logger logger)
		{
			LoggerCreationEventHandler handler = m_loggerCreatedEvent;
			if (handler != null)
			{
				handler(this, new LoggerCreationEventArgs(logger));
			}
		}

		#endregion Protected Instance Methods

		#region Private Instance Methods

		/// <summary>
		/// Updates all the parents of the specified logger
		/// </summary>
		/// <param name="log">The logger to update the parents for</param>
		/// <remarks>
		/// <para>
		/// This method loops through all the <i>potential</i> parents of
		/// <paramref name="log"/>. There 3 possible cases:
		/// </para>
		/// <list type="number">
		///		<item>
		///			<term>No entry for the potential parent of <paramref name="log"/> exists</term>
		///			<description>
		///			We create a ProvisionNode for this potential
		///			parent and insert <paramref name="log"/> in that provision node.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type Logger for the potential parent.</term>
		///			<description>
		///			The entry is <paramref name="log"/>'s nearest existing parent. We
		///			update <paramref name="log"/>'s parent field with this entry. We also break from
		///			he loop because updating our parent's parent is our parent's
		///			responsibility.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type ProvisionNode for this potential parent.</term>
		///			<description>
		///			We add <paramref name="log"/> to the list of children for this
		///			potential parent.
		///			</description>
		///		</item>
		/// </list>
		/// </remarks>
		private void UpdateParents(Logger log)
		{
			string name = log.Name;
			int length = name.Length;
			bool parentFound = false;

			// if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z"
			for (int i = name.LastIndexOf('.', length - 1); i >= 0; i = name.LastIndexOf('.', i - 1))
			{
				string substr = name.Substring(0, i);

				LoggerKey key = new LoggerKey(substr); // simple constructor
				Object node = m_ht[key];
				// Create a provision node for a future parent.
				if (node == null)
				{
					ProvisionNode pn = new ProvisionNode(log);
					m_ht[key] = pn;
				}
				else
				{
					Logger nodeLogger = node as Logger;
					if (nodeLogger != null)
					{
						parentFound = true;
						log.Parent = nodeLogger;
						break; // no need to update the ancestors of the closest ancestor
					}
					else
					{
						ProvisionNode nodeProvisionNode = node as ProvisionNode;
						if (nodeProvisionNode != null)
						{
							nodeProvisionNode.Add(log);
						}
						else
						{
							LogLog.Error(declaringType, "Unexpected object type [" + node.GetType() + "] in ht.", new LogException());
						}
					}
				}
				if (i == 0)
				{
					// logger name starts with a dot
					// and we've hit the start
					break;
				}
			}

			// If we could not find any existing parents, then link with root.
			if (!parentFound)
			{
				log.Parent = this.Root;
			}
		}

		/// <summary>
		/// Replace a <see cref="ProvisionNode"/> with a <see cref="Logger"/> in the hierarchy.
		/// </summary>
		/// <param name="pn"></param>
		/// <param name="log"></param>
		/// <remarks>
		/// <para>
		/// We update the links for all the children that placed themselves
		/// in the provision node 'pn'. The second argument 'log' is a
		/// reference for the newly created Logger, parent of all the
		/// children in 'pn'.
		/// </para>
		/// <para>
		/// We loop on all the children 'c' in 'pn'.
		/// </para>
		/// <para>
		/// If the child 'c' has been already linked to a child of
		/// 'log' then there is no need to update 'c'.
		/// </para>
		/// <para>
		/// Otherwise, we set log's parent field to c's parent and set
		/// c's parent field to log.
		/// </para>
		/// </remarks>
		private static void UpdateChildren(ProvisionNode pn, Logger log)
		{
			for (int i = 0; i < pn.Count; i++)
			{
				Logger childLogger = (Logger)pn[i];

				// Unless this child already points to a correct (lower) parent,
				// make log.Parent point to childLogger.Parent and childLogger.Parent to log.
				if (!childLogger.Parent.Name.StartsWith(log.Name))
				{
					log.Parent = childLogger.Parent;
					childLogger.Parent = log;
				}
			}
		}

		/// <summary>
		/// Define or redefine a Level using the values in the <see cref="LevelEntry"/> argument
		/// </summary>
		/// <param name="levelEntry">the level values</param>
		/// <remarks>
		/// <para>
		/// Define or redefine a Level using the values in the <see cref="LevelEntry"/> argument
		/// </para>
		/// <para>
		/// Supports setting levels via the configuration file.
		/// </para>
		/// </remarks>
		internal void AddLevel(LevelEntry levelEntry)
		{
			if (levelEntry == null) throw new ArgumentNullException("levelEntry");
			if (levelEntry.Name == null) throw new ArgumentNullException("levelEntry.Name");

			// Lookup replacement value
			if (levelEntry.Value == -1)
			{
				Level previousLevel = LevelMap[levelEntry.Name];
				if (previousLevel == null)
				{
					throw new InvalidOperationException("Cannot redefine level [" + levelEntry.Name + "] because it is not defined in the LevelMap. To define the level supply the level value.");
				}

				levelEntry.Value = previousLevel.Value;
			}

			LevelMap.Add(levelEntry.Name, levelEntry.Value, levelEntry.DisplayName);
		}

		/// <summary>
		/// A class to hold the value, name and display name for a level
		/// </summary>
		/// <remarks>
		/// <para>
		/// A class to hold the value, name and display name for a level
		/// </para>
		/// </remarks>
		internal class LevelEntry
		{
			private int m_levelValue = -1;
			private string m_levelName = null;
			private string m_levelDisplayName = null;

			/// <summary>
			/// Value of the level
			/// </summary>
			/// <remarks>
			/// <para>
			/// If the value is not set (defaults to -1) the value will be looked
			/// up for the current level with the same name.
			/// </para>
			/// </remarks>
			public int Value
			{
				get { return m_levelValue; }
				set { m_levelValue = value; }
			}

			/// <summary>
			/// Name of the level
			/// </summary>
			/// <value>
			/// The name of the level
			/// </value>
			/// <remarks>
			/// <para>
			/// The name of the level.
			/// </para>
			/// </remarks>
			public string Name
			{
				get { return m_levelName; }
				set { m_levelName = value; }
			}

			/// <summary>
			/// Display name for the level
			/// </summary>
			/// <value>
			/// The display name of the level
			/// </value>
			/// <remarks>
			/// <para>
			/// The display name of the level.
			/// </para>
			/// </remarks>
			public string DisplayName
			{
				get { return m_levelDisplayName; }
				set { m_levelDisplayName = value; }
			}

			/// <summary>
			/// Override <c>Object.ToString</c> to return sensible debug info
			/// </summary>
			/// <returns>string info about this object</returns>
			public override string ToString()
			{
				return "LevelEntry(Value=" + m_levelValue + ", Name=" + m_levelName + ", DisplayName=" + m_levelDisplayName + ")";
			}
		}

		/// <summary>
		/// Set a Property using the values in the <see cref="LevelEntry"/> argument
		/// </summary>
		/// <param name="propertyEntry">the property value</param>
		/// <remarks>
		/// <para>
		/// Set a Property using the values in the <see cref="LevelEntry"/> argument.
		/// </para>
		/// <para>
		/// Supports setting property values via the configuration file.
		/// </para>
		/// </remarks>
		internal void AddProperty(PropertyEntry propertyEntry)
		{
			if (propertyEntry == null) throw new ArgumentNullException("propertyEntry");
			if (propertyEntry.Key == null) throw new ArgumentNullException("propertyEntry.Key");

			Properties[propertyEntry.Key] = propertyEntry.Value;
		}

		#endregion Private Instance Methods

		#region Private Instance Fields

		private ILoggerFactory m_defaultFactory;

		private System.Collections.Hashtable m_ht;
		private Logger m_root;

		private bool m_emittedNoAppenderWarning = false;

		private event LoggerCreationEventHandler m_loggerCreatedEvent;

		#endregion Private Instance Fields

		#region Private Static Fields

		/// <summary>
		/// The fully qualified type of the Hierarchy class.
		/// </summary>
		/// <remarks>
		/// Used by the internal logger to record the Type of the
		/// log message.
		/// </remarks>
		private readonly static Type declaringType = typeof(Hierarchy);

		#endregion Private Static Fields
	}
}
