public static MarkupExtensionInfo Parse(string input)
        {
            #region Parameter Checks

            if (!MarkupExtensionPattern.IsMatch(input))
            {
                string msg = String.Format("{0} is not a MarkupExtension.", input);
                throw new InvalidOperationException(msg);
            }

            #endregion Parameter Checks

            var resultInfo = new MarkupExtensionInfo();

            using (var reader = new StringReader(input))
            {
                var parsingMode = MarkupExtensionParsingModeEnum.START;

                try
                {
                    //Debug.Print("Parsing '{0}'", input);
                    //Debug.Indent();

                    while (MarkupExtensionParsingModeEnum.END != parsingMode
                           && MarkupExtensionParsingModeEnum.UNEXPECTED != parsingMode)
                    {
                        //Debug.Print(context.ToString());
                        //Debug.Indent();

                        switch (parsingMode)
                        {
                            case MarkupExtensionParsingModeEnum.START:
                                parsingMode = reader.ReadMarkupExtensionStart();
                                break;

                            case MarkupExtensionParsingModeEnum.MARKUP_NAME:
                                parsingMode = reader.ReadMarkupName(resultInfo);
                                break;

                            case MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR:
                                parsingMode = reader.ReadNameValuePair(resultInfo);
                                break;
                        }

                        //Debug.Unindent();
                    }
                }
                catch (Exception exp)
                {
                    throw new InvalidDataException(
                        String.Format("Cannot parse markup extension string:\r\n \"{0}\"", input), exp);
                }
            }

            return resultInfo;
        }
        private static MarkupExtensionParsingModeEnum ReadNameValuePair(this StringReader reader,
                                                                        MarkupExtensionInfo info)
        {
            string methodName = MethodBase.GetCurrentMethod().Name;

            char[] stopChars = {',', '=', '}'};

            MarkupExtensionParsingModeEnum resultParsingMode;
            string key = null;
            object value = null;

            reader.SeekTill(x => !Char.IsWhiteSpace(x));

            // When '{' is the starting char, the following must be a value instead of a key.
            //
            // E.g.,
            //    <Setter x:Uid="Setter_75"
            //            Property="Foreground"
            //            Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
            //
            // In other words, "key" shall not start with '{', as it won't be a valid property name.
            if ('{' != reader.PeekChar())
            {
                string temp = reader.ReadTill(stopChars.Contains).Trim();
                char keyValueIndicatorChar = reader.PeekChar();

                switch (keyValueIndicatorChar)
                {
                    case ',':
                    case '}':
                        value = temp;
                        break;

                    case '=':
                        key = temp;

                        // Consume the '='
                        reader.Read();
                        break;

                    default:
                        throw new InvalidDataException(
                            String.Format("[{0}] Should not encounter '{1}'.", methodName, keyValueIndicatorChar));
                }
            }

            if (null == value)
            {
                reader.SeekTill(x => !(Char.IsWhiteSpace(x)));

                string input = reader.ReadValueString().Trim();

                if (MarkupExtensionPattern.IsMatch(input))
                {
                    value = Parse(input);
                }
                else
                {
                    value = input;
                }
            }

            if (String.IsNullOrEmpty(key))
            {
                info.ValueOnlyProperties.Add(value);
            }
            else
            {
                info.KeyValueProperties.Add(new KeyValuePair<string, object>(key, value));
            }

            reader.SeekTill(x => !Char.IsWhiteSpace(x));

            char stopChar = reader.ReadChar();

            switch (stopChar)
            {
                case ',':
                    resultParsingMode = MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR;
                    break;

                case '}':
                    resultParsingMode = MarkupExtensionParsingModeEnum.END;
                    break;

                default:
                    throw new InvalidDataException(
                        String.Format("[{0}] Should not encounter '{1}'.", methodName, stopChar));
            }

            if (MarkupExtensionParsingModeEnum.UNEXPECTED == resultParsingMode)
            {
                throw new InvalidDataException(
                    String.Format("[{0}] Invalid result context: {1}", methodName, resultParsingMode));
            }

            return resultParsingMode;
        }
        private static MarkupExtensionParsingModeEnum ReadMarkupName(this StringReader reader, MarkupExtensionInfo info)
        {
            string methodName = MethodBase.GetCurrentMethod().Name;

            char[] stopChars = {' ', '}'};
            var resultParsingMode = MarkupExtensionParsingModeEnum.UNEXPECTED;
            var buffer = new StringBuilder();

            while (!reader.IsEnd())
            {
                char c = reader.ReadChar();

                if (stopChars.Contains(c))
                {
                    switch (c)
                    {
                        case ' ':
                            resultParsingMode = MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR;
                            break;

                        case '}':
                            resultParsingMode = MarkupExtensionParsingModeEnum.END;
                            break;

                        default:
                            throw new InvalidDataException(
                                String.Format("[{0}] Should not encounter '{1}'.", methodName, c));
                    }

                    info.Name = buffer.ToString().Trim();
                    buffer.Clear();

                    // break out the while
                    break;
                }
                
                buffer.Append(c);
            }

            if (MarkupExtensionParsingModeEnum.UNEXPECTED == resultParsingMode)
            {
                throw new InvalidDataException(
                    String.Format("[{0}] Invalid result context: {1}", methodName, resultParsingMode));
            }

            return resultParsingMode;
        }