/// <summary>
 /// Adds a pattern converter to the chain.
 /// </summary>
 /// <param name="pc">The converter to add.</param>
 private void AddToList(PatternConverter pc)
 {
     if (m_head == null)
     {
         m_head = m_tail = pc;
     }
     else
     {
         m_tail.Next = pc;
         m_tail      = pc;
     }
 }
        /// <summary>
        /// Resets the internal state of the parser and adds the specified pattern converter
        /// to the chain.
        /// </summary>
        /// <param name="pc">The pattern converter to add.</param>
        protected void AddConverter(PatternConverter pc)
        {
            m_currentLiteral.Length = 0;

            // Add the pattern converter to the list.
            AddToList(pc);

            // Next pattern is assumed to be a literal.
            m_state = LITERAL_STATE;

            // Reset formatting info
            m_formattingInfo.Reset();
        }
        /// <summary>
        /// Internal method that works on a single option in the
        /// pattern
        /// </summary>
        /// <param name="c">The option specifier.</param>
        protected void FinalizeConverter(char c)
        {
            PatternConverter pc = null;

            switch (c)
            {
            case 'a':
                pc = new BasicPatternConverter(m_formattingInfo, APPDOMAIN_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'c':
                pc = new LoggerPatternConverter(m_formattingInfo, ExtractPrecisionOption());
                m_currentLiteral.Length = 0;
                break;

            case 'C':
                pc = new ClassNamePatternConverter(m_formattingInfo, ExtractPrecisionOption());
                m_currentLiteral.Length = 0;
                break;

            case 'd':
                string         dateFormatStr = AbsoluteTimeDateFormatter.ISO8601_DATE_FORMAT;
                IDateFormatter df;
                string         dOpt = ExtractOption();
                if (dOpt != null)
                {
                    dateFormatStr = dOpt;
                }

                if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.ISO8601_DATE_FORMAT, true, System.Globalization.CultureInfo.InvariantCulture) == 0)
                {
                    df = new ISO8601DateFormatter();
                }
                else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.ABS_TIME_DATE_FORMAT, true, System.Globalization.CultureInfo.InvariantCulture) == 0)
                {
                    df = new AbsoluteTimeDateFormatter();
                }
                else if (string.Compare(dateFormatStr, AbsoluteTimeDateFormatter.DATE_AND_TIME_DATE_FORMAT, true, System.Globalization.CultureInfo.InvariantCulture) == 0)
                {
                    df = new DateTimeDateFormatter();
                }
                else
                {
                    try
                    {
                        df = new SimpleDateFormatter(dateFormatStr);
                    }
                    catch (Exception e)
                    {
                        LogLog.Error("PatternParser: Could not instantiate SimpleDateFormatter with [" + dateFormatStr + "]", e);
                        df = new ISO8601DateFormatter();
                    }
                }
                pc = new DatePatternConverter(m_formattingInfo, df);
                m_currentLiteral.Length = 0;
                break;

            case 'F':
                pc = new LocationPatternConverter(m_formattingInfo, FILE_LOCATION_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'l':
                pc = new LocationPatternConverter(m_formattingInfo, FULL_LOCATION_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'L':
                pc = new LocationPatternConverter(m_formattingInfo, LINE_LOCATION_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'm':
                pc = new BasicPatternConverter(m_formattingInfo, MESSAGE_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'M':
                pc = new LocationPatternConverter(m_formattingInfo, METHOD_LOCATION_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'p':
                pc = new BasicPatternConverter(m_formattingInfo, LEVEL_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'P':
                pc = new PropertyPatternConverter(m_formattingInfo, this.ExtractOption());
                m_currentLiteral.Length = 0;
                break;

            case 'r':
                pc = new BasicPatternConverter(m_formattingInfo, RELATIVE_TIME_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 't':
                pc = new BasicPatternConverter(m_formattingInfo, THREAD_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'u':
                pc = new BasicPatternConverter(m_formattingInfo, IDENTITY_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'W':
                pc = new BasicPatternConverter(m_formattingInfo, USERNAME_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'x':
                pc = new BasicPatternConverter(m_formattingInfo, NDC_CONVERTER);
                m_currentLiteral.Length = 0;
                break;

            case 'X':
                pc = new MDCPatternConverter(m_formattingInfo, this.ExtractOption());
                m_currentLiteral.Length = 0;
                break;

            default:
                LogLog.Error("PatternParser: Unexpected char [" + c + "] at position [" + m_index + "] in conversion pattern.");
                pc = new LiteralPatternConverter(m_currentLiteral.ToString());
                m_currentLiteral.Length = 0;
                break;
            }
            AddConverter(pc);
        }
		/// <summary>
		/// Adds a pattern converter to the chain.
		/// </summary>
		/// <param name="pc">The converter to add.</param>
		private void AddToList(PatternConverter pc) 
		{
			if (m_head == null) 
			{
				m_head = m_tail = pc;
			}
			else 
			{
				m_tail.Next = pc;
				m_tail = pc;	
			}
		}
		/// <summary>
		/// Resets the internal state of the parser and adds the specified pattern converter 
		/// to the chain.
		/// </summary>
		/// <param name="pc">The pattern converter to add.</param>
		protected void AddConverter(PatternConverter pc) 
		{
			m_currentLiteral.Length = 0;

			// Add the pattern converter to the list.
			AddToList(pc);

			// Next pattern is assumed to be a literal.
			m_state = LITERAL_STATE;

			// Reset formatting info
			m_formattingInfo.Reset();
		}
		/// <summary>
		/// Constructs a PatternLayout using the supplied conversion pattern
		/// </summary>
		/// <param name="pattern">the pattern to use</param>
		public PatternLayout(string pattern) 
		{
			m_pattern = pattern;
			m_head = CreatePatternParser((pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern).Parse();
		}