/// <summary>
        /// Recursive method. Consumes next characters as markup extension definition.
        /// Resolves type, ctor arguments and properties of markup extension,
        /// constructs and initializes it, and returns ProvideValue method result.
        /// </summary>
        /// <param name="context">Context object passed to ProvideValue method.</param>
        private Object processMarkupExtensionCore(IMarkupExtensionContext context)
        {
            if (consumeChar( ) != '{')
            {
                throw new InvalidOperationException("Syntax error: '{{' token expected at 0.");
            }
            processWhitespace(false);
            String markupExtensionName = processQualifiedName( );

            if (markupExtensionName.Length == 0)
            {
                throw new InvalidOperationException("Syntax error: markup extension name is empty.");
            }
            processWhitespace( );

            Type type = resolver.Resolve(markupExtensionName);

            Object        obj      = null;
            List <Object> ctorArgs = new List <object>();

            for ( ;;)
            {
                if (peekNextChar( ) == '{')
                {
                    // inner markup extension processing

                    // syntax error if ctor arg defined after any property
                    if (obj != null)
                    {
                        throw new InvalidOperationException("Syntax error: constructor argument" +
                                                            " cannot be after property assignment.");
                    }

                    Object value = processMarkupExtensionCore(context);
                    if (value is IFixupToken)
                    {
                        return(value);
                    }
                    ctorArgs.Add(value);
                }
                else
                {
                    String membernameOrString = processString( );

                    if (membernameOrString.Length == 0)
                    {
                        throw new InvalidOperationException(
                                  String.Format("Syntax error: member name or string expected at {0}",
                                                index));
                    }

                    if (peekNextChar( ) == '=')
                    {
                        consumeChar( );
                        object value = peekNextChar( ) == '{'
                            ? processMarkupExtensionCore(context)
                            : processString( );

                        if (value is IFixupToken)
                        {
                            return(value);
                        }

                        // construct object if not constructed yet
                        if (obj == null)
                        {
                            obj = construct(type, ctorArgs);
                        }

                        // assign value to specified member
                        assignProperty(type, obj, membernameOrString, value);
                    }
                    else if (peekNextChar( ) == ',' || peekNextChar( ) == '}')
                    {
                        // syntax error if ctor arg defined after any property
                        if (obj != null)
                        {
                            throw new InvalidOperationException("Syntax error: constructor argument" +
                                                                " cannot be after property assignment.");
                        }

                        // store membernameOrString as string argument of ctor
                        ctorArgs.Add(membernameOrString);
                    }
                    else
                    {
                        // it is '{' token, throw syntax error
                        throw new InvalidOperationException(
                                  String.Format("Syntax error : unexpected '{{' token at {0}.",
                                                index));
                    }
                }

                // after ctor arg or property assignment should be , or }
                if (peekNextChar( ) == ',')
                {
                    consumeChar( );
                }
                else if (peekNextChar( ) == '}')
                {
                    consumeChar( );

                    // construct object
                    if (obj == null)
                    {
                        obj = construct(type, ctorArgs);
                    }

                    // markup extension is finished
                    break;
                }
                else
                {
                    // it is '{' token (without whitespace), throw syntax error
                    throw new InvalidOperationException(
                              String.Format("Syntax error : unexpected '{{' token at {0}.",
                                            index));
                }

                processWhitespace(false);
            }

            return(((IMarkupExtension)obj).ProvideValue(context));
        }