/* Generated By:JavaCC: Do not edit this line. CueryParser.java */
package org.trix.cuery.parser;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Locale;

import org.trix.cuery.filter.DenialFIlter;
import org.trix.cuery.filter.FirstNumeralFilter;
import org.trix.cuery.filter.FirstTypedNumeralFilter;
import org.trix.cuery.filter.IndirectAdjacentFilter;
import org.trix.cuery.filter.LastNumeralFilter;
import org.trix.cuery.filter.LastTypedNumeralFilter;
import org.trix.cuery.filter.PrefixMatchFilter;
import org.trix.cuery.filter.SubstringMatchFilter;
import org.trix.cuery.filter.SuffixMatchFilter;
import org.trix.cuery.sac.ConditionFactoryImpl;
import org.trix.cuery.sac.SACMediaListImpl;
import org.trix.cuery.sac.SelectorFactoryImpl;
import org.trix.cuery.sac.SelectorListImpl;
import org.trix.cuery.util.CSSUtil;
import org.trix.cuery.value.CSSAttrFunction;
import org.trix.cuery.value.CSSColor;
import org.trix.cuery.value.CSSCounterFunction;
import org.trix.cuery.value.CSSCountersFunction;
import org.trix.cuery.value.CSSFunction;
import org.trix.cuery.value.CSSIdent;
import org.trix.cuery.value.CSSNumber;
import org.trix.cuery.value.CSSOperator;
import org.trix.cuery.value.CSSPercentage;
import org.trix.cuery.value.CSSRectFunction;
import org.trix.cuery.value.CSSString;
import org.trix.cuery.value.CSSURI;
import org.trix.cuery.value.CSSUnicodeRange;
import org.trix.cuery.value.CSScmLength;
import org.trix.cuery.value.CSSdegAngle;
import org.trix.cuery.value.CSSemLength;
import org.trix.cuery.value.CSSexLength;
import org.trix.cuery.value.CSSgradAngle;
import org.trix.cuery.value.CSShzFrequency;
import org.trix.cuery.value.CSSinLength;
import org.trix.cuery.value.CSSkhzFrequency;
import org.trix.cuery.value.CSSmmLength;
import org.trix.cuery.value.CSSmsTime;
import org.trix.cuery.value.CSSpcLength;
import org.trix.cuery.value.CSSptLength;
import org.trix.cuery.value.CSSpxLength;
import org.trix.cuery.value.CSSradAngle;
import org.trix.cuery.value.CSSsTime;
import org.trix.cuery.value.Value;

import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.CSSParseException;
import org.w3c.css.sac.Condition;
import org.w3c.css.sac.ConditionFactory;
import org.w3c.css.sac.DocumentHandler;
import org.w3c.css.sac.ErrorHandler;
import org.w3c.css.sac.InputSource;
import org.w3c.css.sac.LexicalUnit;
import org.w3c.css.sac.Parser;
import org.w3c.css.sac.Selector;
import org.w3c.css.sac.SelectorFactory;
import org.w3c.css.sac.SelectorList;
import org.w3c.css.sac.SimpleSelector;

/**
 * DOCUMENT.
 * 
 * @author <a href="mailto:Teletha.T@gmail.com">Teletha Testarossa</a>
 * @version $ Id: CueryParser.java,v 1.15 2005/08/10 0:27:18 Teletha Exp $
 */
public class CueryParser implements Parser, CueryParserConstants {

    /** The stylesheet source to parse. */
    private InputSource source;

    /** The document handler. */
    private DocumentHandler handler;

    /** The error handler. */
    private ErrorHandler errorHandler;

    /** The selector factory. */
    private SelectorFactory selectorFactory = new SelectorFactoryImpl();

    /** The condition factory. */
    private ConditionFactory conditionFactory = new ConditionFactoryImpl();

    /** The locale. */
    private Locale locale = Locale.getDefault();

    /**
     * Create CueryParser instance.
     */
    public CueryParser() {
        this(System.in);
    }

    /**
     * @see org.w3c.css.sac.Parser#getParserVersion()
     */
    public String getParserVersion() {
        return "http://www.w3.org/TR/REC-CSS2";
    }

    /**
     * @see org.w3c.css.sac.Parser#setLocale(java.util.Locale)
     */
    public void setLocale(Locale locale) throws CSSException {
        // check null
        if (locale == null) {
            return;
        }
        this.locale = locale;
    }

    /**
     * @see org.w3c.css.sac.Parser#setDocumentHandler(org.w3c.css.sac.DocumentHandler)
     */
    public void setDocumentHandler(DocumentHandler handler) {
        this.handler = handler;
    }

    /**
     * @see org.w3c.css.sac.Parser#setSelectorFactory(org.w3c.css.sac.SelectorFactory)
     */
    public void setSelectorFactory(SelectorFactory selectorFactory) {
        // check null
        if (selectorFactory == null) {
            return;
        }
        this.selectorFactory = selectorFactory;
    }

    /**
     * @see org.w3c.css.sac.Parser#setConditionFactory(org.w3c.css.sac.ConditionFactory)
     */
    public void setConditionFactory(ConditionFactory conditionFactory) {
        // check null
        if (conditionFactory == null) {
            return;
        }
        this.conditionFactory = conditionFactory;
    }

    /**
     * @see org.w3c.css.sac.Parser#setErrorHandler(org.w3c.css.sac.ErrorHandler)
     */
    public void setErrorHandler(ErrorHandler errorHandler) {
        // check null
        if (errorHandler == null) {
            return;
        }
        this.errorHandler = errorHandler;
    }

    /**
     * @see org.w3c.css.sac.Parser#parseStyleSheet(java.lang.String)
     */
    public void parseStyleSheet(String uri) throws CSSException, IOException {
        // check null
        if (uri == null || uri.length() == 0) {
            throw new IOException("Unable to parse a stylesheet because this uri is null.");
        }

        // create input stream
        InputSource source = null;

        try {
            source = CSSUtil.getSource(uri);

            // start parsing
            parseStyleSheet(source);
        } finally {
            if (source != null) {
                source.getCharacterStream().close();
            }
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parseStyleSheet(org.w3c.css.sac.InputSource)
     */
    public void parseStyleSheet(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            handler.startDocument(source);
            styleSheet();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        } finally {
            handler.endDocument(source);
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parseStyleDeclaration(org.w3c.css.sac.InputSource)
     */
    public void parseStyleDeclaration(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            parseStyleDeclaration();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parseRule(org.w3c.css.sac.InputSource)
     */
    public void parseRule(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            parseStyleRule();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parseSelectors(org.w3c.css.sac.InputSource)
     */
    public SelectorList parseSelectors(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            return selectorList();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parsePropertyValue(org.w3c.css.sac.InputSource)
     */
    public LexicalUnit parsePropertyValue(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            return expr();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * @see org.w3c.css.sac.Parser#parsePriority(org.w3c.css.sac.InputSource)
     */
    public boolean parsePriority(InputSource source) throws CSSException, IOException {
        initializeParser(source);

        try {
            return priority();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * Parse a selector expression.
     * 
     * @param expression A selector expression for css.
     * @return A parsed selector instance.
     * @throws CSSException If this expression is invalid.
     */
    public Selector parseSelector(String expression) throws CSSException {
        // cehck null
        if (expression == null || expression.length() == 0) {
            throw new CSSException("This selector expression is null.");
        }

        ReInit(new StringReader(expression));

        try {
            return selector();
        } catch (ParseException e) {
            throw new CSSException(CSSException.SAC_SYNTAX_ERR, e.getMessage(), e);
        }
    }

    /**
     * Initialize parser.
     * 
     * @param source A stylesheet source.
     */
    private void initializeParser(InputSource source) {
        this.source = source;
        Reader reader = source.getCharacterStream();

        if (reader == null) {
            ReInit(source.getByteStream(), source.getEncoding());
        } else {
            ReInit(reader);
        }
    }

    /**
     * Handle parse error message.
     * 
     * @param message A message.
     * @param cause A cause of this error.
     */
    private void handleError(String message, Exception cause) {
        // check null
        if (errorHandler == null) {
            return;
        }
        CSSParseException exception = new CSSParseException(message, source.getURI(), token.beginLine, token.beginColumn, cause);
        errorHandler.warning(exception);
    }

    /* ====================== Parse Style Declaration ====================== */
    final public void parseStyleDeclaration() throws ParseException {
        jj_consume_token(LBRACE);
        label_1: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[0] = jj_gen;
                break label_1;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case IDENT:
            declaration();
            break;
        default:
            jj_la1[1] = jj_gen;
            ;
        }
        label_2: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case SEMICOLON:
                ;
                break;
            default:
                jj_la1[2] = jj_gen;
                break label_2;
            }
            jj_consume_token(SEMICOLON);
            label_3: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[3] = jj_gen;
                    break label_3;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IDENT:
                declaration();
                break;
            default:
                jj_la1[4] = jj_gen;
                ;
            }
        }
        jj_consume_token(RBRACE);
    }

    /* ====================== Parse Style Rule ====================== */
    final public void parseStyleRule() throws ParseException {
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case IMPORT_SYM:
            importRule();
            break;
        case DOT:
        case COLON:
        case ASTERISK:
        case LSQUARE:
        case IDENT:
        case HASH:
            styleRule();
            break;
        case MEDIA_SYM:
            mediaRule();
            break;
        case PAGE_SYM:
            pageRule();
            break;
        case FONT_FACE_SYM:
            fontFaceRule();
            break;
        case ATKEYWORD:
            unknownRule();
            break;
        default:
            jj_la1[5] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
    }

    /* ====================== Entire Stylesheet ====================== */
    final public void styleSheet() throws ParseException {
        try {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case CHARSET_SYM:
                jj_consume_token(CHARSET_SYM);
                label_4: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[6] = jj_gen;
                        break label_4;
                    }
                    jj_consume_token(S);
                }
                jj_consume_token(STRING);
                label_5: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[7] = jj_gen;
                        break label_5;
                    }
                    jj_consume_token(S);
                }
                jj_consume_token(SEMICOLON);
                break;
            default:
                jj_la1[8] = jj_gen;
                ;
            }
            label_6: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                case CDO:
                case CDC:
                    ;
                    break;
                default:
                    jj_la1[9] = jj_gen;
                    break label_6;
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    jj_consume_token(S);
                    break;
                case CDO:
                    jj_consume_token(CDO);
                    break;
                case CDC:
                    jj_consume_token(CDC);
                    break;
                default:
                    jj_la1[10] = jj_gen;
                    jj_consume_token(-1);
                    throw new ParseException();
                }
            }
            label_7: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case IMPORT_SYM:
                    ;
                    break;
                default:
                    jj_la1[11] = jj_gen;
                    break label_7;
                }
                importRule();
                label_8: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                    case CDO:
                    case CDC:
                        ;
                        break;
                    default:
                        jj_la1[12] = jj_gen;
                        break label_8;
                    }
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        jj_consume_token(S);
                        break;
                    case CDO:
                        jj_consume_token(CDO);
                        break;
                    case CDC:
                        jj_consume_token(CDC);
                        break;
                    default:
                        jj_la1[13] = jj_gen;
                        jj_consume_token(-1);
                        throw new ParseException();
                    }
                }
            }
            label_9: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case DOT:
                case COLON:
                case ASTERISK:
                case LSQUARE:
                case FONT_FACE_SYM:
                case MEDIA_SYM:
                case PAGE_SYM:
                case ATKEYWORD:
                case IDENT:
                case HASH:
                    ;
                    break;
                default:
                    jj_la1[14] = jj_gen;
                    break label_9;
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case DOT:
                case COLON:
                case ASTERISK:
                case LSQUARE:
                case IDENT:
                case HASH:
                    styleRule();
                    break;
                case MEDIA_SYM:
                    mediaRule();
                    break;
                case PAGE_SYM:
                    pageRule();
                    break;
                case FONT_FACE_SYM:
                    fontFaceRule();
                    break;
                case ATKEYWORD:
                    unknownRule();
                    break;
                default:
                    jj_la1[15] = jj_gen;
                    jj_consume_token(-1);
                    throw new ParseException();
                }
                label_10: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                    case CDO:
                    case CDC:
                        ;
                        break;
                    default:
                        jj_la1[16] = jj_gen;
                        break label_10;
                    }
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        jj_consume_token(S);
                        break;
                    case CDO:
                        jj_consume_token(CDO);
                        break;
                    case CDC:
                        jj_consume_token(CDC);
                        break;
                    default:
                        jj_la1[17] = jj_gen;
                        jj_consume_token(-1);
                        throw new ParseException();
                    }
                }
            }
            jj_consume_token(0);
        } catch (ParseException e) {
            skipBlock(e);
            styleSheet();
        }
    }

    /* ====================== Import Rule ====================== */
    final public void importRule() throws ParseException {
        Token token;
        SACMediaListImpl mediaList = new SACMediaListImpl();
        jj_consume_token(IMPORT_SYM);
        label_11: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[18] = jj_gen;
                break label_11;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case STRING:
            token = jj_consume_token(STRING);
            break;
        case URL:
            token = jj_consume_token(URL);
            break;
        default:
            jj_la1[19] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_12: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[20] = jj_gen;
                break label_12;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case IDENT:
            mediaList(mediaList);
            break;
        default:
            jj_la1[21] = jj_gen;
            ;
        }
        jj_consume_token(SEMICOLON);
        handler.importStyle(token.image, mediaList, null);
    }

    /* ====================== Media Rule ====================== */
    final public void mediaRule() throws ParseException {
        boolean start = false;
        SACMediaListImpl media = new SACMediaListImpl();
        try {
            jj_consume_token(MEDIA_SYM);
            label_13: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[22] = jj_gen;
                    break label_13;
                }
                jj_consume_token(S);
            }
            mediaList(media);
            start = true;
            handler.startMedia(media);
            jj_consume_token(LBRACE);
            label_14: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[23] = jj_gen;
                    break label_14;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case DOT:
            case COLON:
            case ASTERISK:
            case LSQUARE:
            case PAGE_SYM:
            case ATKEYWORD:
            case IDENT:
            case HASH:
                mediaRuleList();
                break;
            default:
                jj_la1[24] = jj_gen;
                ;
            }
            jj_consume_token(RBRACE);
        } finally {
            if (start) {
                handler.endMedia(media);
            }
        }
    }

    /* ====================== Unknown Rule ====================== */
    final public void unknownRule() throws ParseException {
        String token;
        jj_consume_token(ATKEYWORD);
        token = skip();
        handler.ignorableAtRule(token);
    }

    /* ====================== Media List ====================== */
    final public void mediaList(SACMediaListImpl list) throws ParseException {
        String medium;
        medium = medium();
        label_15: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case COMMA:
                ;
                break;
            default:
                jj_la1[25] = jj_gen;
                break label_15;
            }
            jj_consume_token(COMMA);
            label_16: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[26] = jj_gen;
                    break label_16;
                }
                jj_consume_token(S);
            }
            list.appendMedium(medium);
            medium = medium();
        }
        list.appendMedium(medium);
    }

    // ===============================================
    final public void mediaRuleList() throws ParseException {
        label_17: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case DOT:
            case COLON:
            case ASTERISK:
            case LSQUARE:
            case IDENT:
            case HASH:
                styleRule();
                break;
            case PAGE_SYM:
                pageRule();
                break;
            case ATKEYWORD:
                unknownRule();
                break;
            default:
                jj_la1[27] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            label_18: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[28] = jj_gen;
                    break label_18;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case DOT:
            case COLON:
            case ASTERISK:
            case LSQUARE:
            case PAGE_SYM:
            case ATKEYWORD:
            case IDENT:
            case HASH:
                ;
                break;
            default:
                jj_la1[29] = jj_gen;
                break label_17;
            }
        }
    }

    // ===============================================
    final public void mediaRuleSingle() throws ParseException {
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case DOT:
        case COLON:
        case ASTERISK:
        case LSQUARE:
        case IDENT:
        case HASH:
            styleRule();
            break;
        case PAGE_SYM:
            pageRule();
            break;
        case ATKEYWORD:
            unknownRule();
            break;
        default:
            jj_la1[30] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
    }

    // ===============================================
    final public String medium() throws ParseException {
        Token token;
        token = jj_consume_token(IDENT);
        label_19: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[31] = jj_gen;
                break label_19;
            }
            jj_consume_token(S);
        }
        {
            if (true) return token.image;
        }
        throw new Error("Missing return statement in function");
    }

    // ===============================================
    final public void pageRule() throws ParseException {
        Token t = null;
        String s = null;
        boolean start = false;
        try {
            jj_consume_token(PAGE_SYM);
            label_20: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[32] = jj_gen;
                    break label_20;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case COLON:
            case IDENT:
                if (jj_2_1(2)) {
                    t = jj_consume_token(IDENT);
                    label_21: while (true) {
                        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                        case S:
                            ;
                            break;
                        default:
                            jj_la1[33] = jj_gen;
                            break label_21;
                        }
                        jj_consume_token(S);
                    }
                } else {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case IDENT:
                        t = jj_consume_token(IDENT);
                        s = pseudoPage();
                        label_22: while (true) {
                            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                            case S:
                                ;
                                break;
                            default:
                                jj_la1[34] = jj_gen;
                                break label_22;
                            }
                            jj_consume_token(S);
                        }
                        break;
                    case COLON:
                        s = pseudoPage();
                        label_23: while (true) {
                            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                            case S:
                                ;
                                break;
                            default:
                                jj_la1[35] = jj_gen;
                                break label_23;
                            }
                            jj_consume_token(S);
                        }
                        break;
                    default:
                        jj_la1[36] = jj_gen;
                        jj_consume_token(-1);
                        throw new ParseException();
                    }
                }
                break;
            default:
                jj_la1[37] = jj_gen;
                ;
            }
            jj_consume_token(LBRACE);
            label_24: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[38] = jj_gen;
                    break label_24;
                }
                jj_consume_token(S);
            }
            start = true;
            handler.startPage((t != null) ? t.image : null, s);
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IDENT:
                declaration();
                break;
            default:
                jj_la1[39] = jj_gen;
                ;
            }
            label_25: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case SEMICOLON:
                    ;
                    break;
                default:
                    jj_la1[40] = jj_gen;
                    break label_25;
                }
                jj_consume_token(SEMICOLON);
                label_26: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[41] = jj_gen;
                        break label_26;
                    }
                    jj_consume_token(S);
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case IDENT:
                    declaration();
                    break;
                default:
                    jj_la1[42] = jj_gen;
                    ;
                }
            }
            jj_consume_token(RBRACE);
        } finally {
            if (start) {
                handler.endPage((t != null) ? t.image : null, s);
            }
        }
    }

    // ===============================================
    final public String pseudoPage() throws ParseException {
        Token token;
        jj_consume_token(COLON);
        token = jj_consume_token(IDENT);
        {
            if (true) return token.image;
        }
        throw new Error("Missing return statement in function");
    }

    // ===============================================
    final public void fontFaceRule() throws ParseException {
        boolean start = false;
        try {
            jj_consume_token(FONT_FACE_SYM);
            label_27: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[43] = jj_gen;
                    break label_27;
                }
                jj_consume_token(S);
            }
            jj_consume_token(LBRACE);
            label_28: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[44] = jj_gen;
                    break label_28;
                }
                jj_consume_token(S);
            }
            start = true;
            handler.startFontFace();
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IDENT:
                declaration();
                break;
            default:
                jj_la1[45] = jj_gen;
                ;
            }
            label_29: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case SEMICOLON:
                    ;
                    break;
                default:
                    jj_la1[46] = jj_gen;
                    break label_29;
                }
                jj_consume_token(SEMICOLON);
                label_30: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[47] = jj_gen;
                        break label_30;
                    }
                    jj_consume_token(S);
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case IDENT:
                    declaration();
                    break;
                default:
                    jj_la1[48] = jj_gen;
                    ;
                }
            }
            jj_consume_token(RBRACE);
        } finally {
            if (start) {
                handler.endFontFace();
            }
        }
    }

    /* ====================== Cominator Unit ====================== */
    final public char combinator() throws ParseException {
        char c = ' ';
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case PLUS:
        case GT:
        case TILDE:
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case PLUS:
                jj_consume_token(PLUS);
                c = '+';
                break;
            case GT:
                jj_consume_token(GT);
                c = '>';
                break;
            case TILDE:
                jj_consume_token(TILDE);
                c = '~';
                break;
            default:
                jj_la1[49] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            label_31: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[50] = jj_gen;
                    break label_31;
                }
                jj_consume_token(S);
            }
            break;
        case S:
            jj_consume_token(S);
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case PLUS:
            case GT:
            case TILDE:
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case PLUS:
                    jj_consume_token(PLUS);
                    c = '+';
                    break;
                case GT:
                    jj_consume_token(GT);
                    c = '>';
                    break;
                case TILDE:
                    jj_consume_token(TILDE);
                    c = '~';
                    break;
                default:
                    jj_la1[51] = jj_gen;
                    jj_consume_token(-1);
                    throw new ParseException();
                }
                label_32: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[52] = jj_gen;
                        break label_32;
                    }
                    jj_consume_token(S);
                }
                break;
            default:
                jj_la1[53] = jj_gen;
                ;
            }
            break;
        default:
            jj_la1[54] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        {
            if (true) return c;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Property Name ====================== */
    final public String property() throws ParseException {
        Token tokne;
        tokne = jj_consume_token(IDENT);
        label_33: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[55] = jj_gen;
                break label_33;
            }
            jj_consume_token(S);
        }
        {
            if (true) return tokne.image;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Selector Rule ====================== */
    final public void styleRule() throws ParseException {
        SelectorList selectorList = null;
        boolean start = false;
        try {
            selectorList = selectorList();
            jj_consume_token(LBRACE);
            label_34: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[56] = jj_gen;
                    break label_34;
                }
                jj_consume_token(S);
            }
            start = true;
            handler.startSelector(selectorList);
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IDENT:
                declaration();
                break;
            default:
                jj_la1[57] = jj_gen;
                ;
            }
            label_35: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case SEMICOLON:
                    ;
                    break;
                default:
                    jj_la1[58] = jj_gen;
                    break label_35;
                }
                jj_consume_token(SEMICOLON);
                label_36: while (true) {
                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                    case S:
                        ;
                        break;
                    default:
                        jj_la1[59] = jj_gen;
                        break label_36;
                    }
                    jj_consume_token(S);
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case IDENT:
                    declaration();
                    break;
                default:
                    jj_la1[60] = jj_gen;
                    ;
                }
            }
            jj_consume_token(RBRACE);
        } catch (ParseException e) {
            skipBlock(e);
        } finally {
            if (start) {
                handler.endSelector(selectorList);
            }
        }
    }

    /* ====================== Selector List ====================== */
    // All parse exception ocurred in selector context, rethrow up.
    final public SelectorList selectorList() throws ParseException {
        SelectorListImpl selectorList = new SelectorListImpl();
        Selector selector;
        selector = selector();
        label_37: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case COMMA:
                ;
                break;
            default:
                jj_la1[61] = jj_gen;
                break label_37;
            }
            jj_consume_token(COMMA);
            label_38: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[62] = jj_gen;
                    break label_38;
                }
                jj_consume_token(S);
            }
            selectorList.add(selector);
            selector = selector();
        }
        selectorList.add(selector);
        {
            if (true) return selectorList;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Selector ====================== */
    // All parse exception ocurred in selector context, rethrow up.
    final public Selector selector() throws ParseException {
        Selector selector;
        char combinator;
        selector = simpleSelector(null, ' ');
        label_39: while (true) {
            if (jj_2_2(2)) {
                ;
            } else {
                break label_39;
            }
            combinator = combinator();
            selector = simpleSelector(selector, combinator);
        }
        label_40: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[63] = jj_gen;
                break label_40;
            }
            jj_consume_token(S);
        }
        {
            if (true) return selector;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Simple Selector ====================== */
    // All parse exception ocurred in simple selector context, rethrow up.
    final public Selector simpleSelector(Selector selector, char combinator) throws ParseException {
        SimpleSelector current = null;
        Condition con = null;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case ASTERISK:
        case IDENT:
            current = elementName();
            label_41: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case DOT:
                case COLON:
                case LSQUARE:
                case HASH:
                    ;
                    break;
                default:
                    jj_la1[64] = jj_gen;
                    break label_41;
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case HASH:
                    con = hash(con);
                    break;
                case DOT:
                    con = clazz(con);
                    break;
                case LSQUARE:
                    con = attrib(con);
                    break;
                case COLON:
                    con = pseudo(con);
                    break;
                default:
                    jj_la1[65] = jj_gen;
                    jj_consume_token(-1);
                    throw new ParseException();
                }
            }
            break;
        case DOT:
        case COLON:
        case LSQUARE:
        case HASH:
            label_42: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case HASH:
                    con = hash(con);
                    break;
                case DOT:
                    con = clazz(con);
                    break;
                case LSQUARE:
                    con = attrib(con);
                    break;
                case COLON:
                    con = pseudo(con);
                    break;
                default:
                    jj_la1[66] = jj_gen;
                    jj_consume_token(-1);
                    throw new ParseException();
                }
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case DOT:
                case COLON:
                case LSQUARE:
                case HASH:
                    ;
                    break;
                default:
                    jj_la1[67] = jj_gen;
                    break label_42;
                }
            }
            break;
        default:
            jj_la1[68] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        // check whether the current selector is a universal selector or not
        if (current == null) {
            current = selectorFactory.createElementSelector(null, null);
        }

        // check whether the current selector is a conditional selector or not
        if (con != null) {
            current = selectorFactory.createConditionalSelector(current, con);
        }

        // check parent selector
        if (selector == null) {
            {
                if (true) return current;
            }
        }

        switch (combinator) {
        case ' ': {
            if (true) return selectorFactory.createDescendantSelector(selector, current);
        }
        case '+': {
            if (true)
                return selectorFactory.createDirectAdjacentSelector(selector.getSelectorType(), selector, current);
        }
        case '>': {
            if (true) return selectorFactory.createChildSelector(selector, current);
        }
        case '~': {
            if (true) return new IndirectAdjacentFilter(selector.getSelectorType(), selector, current);
        }
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Class Selector ====================== */
    final public Condition clazz(Condition previous) throws ParseException {
        Token token;
        jj_consume_token(DOT);
        token = jj_consume_token(IDENT);
        Condition condition = conditionFactory.createClassCondition(null, token.image);

        if (previous == null) {
            {
                if (true) return condition;
            }
        } else {
            {
                if (true) return conditionFactory.createAndCondition(previous, condition);
            }
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Element Selector ====================== */
    final public SimpleSelector elementName() throws ParseException {
        Token token;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case IDENT:
            token = jj_consume_token(IDENT);
            {
                if (true) return selectorFactory.createElementSelector(null, token.image);
            }
            break;
        case ASTERISK:
            jj_consume_token(ASTERISK);
            {
                if (true) return selectorFactory.createElementSelector(null, null);
            }
            break;
        default:
            jj_la1[69] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Attribute Selector ====================== */
    final public Condition attrib(Condition previous) throws ParseException {
        Token name = null;
        Token value = null;
        int type = 0;
        jj_consume_token(LSQUARE);
        label_43: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[70] = jj_gen;
                break label_43;
            }
            jj_consume_token(S);
        }
        name = jj_consume_token(IDENT);
        label_44: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[71] = jj_gen;
                break label_44;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case EQUALS:
        case INCLUDES:
        case DASHMATCH:
        case PREFIXMATCH:
        case SUFFIXMATCH:
        case SUBSTRINGMATCH:
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case EQUALS:
                jj_consume_token(EQUALS);
                type = 1;
                break;
            case INCLUDES:
                jj_consume_token(INCLUDES);
                type = 2;
                break;
            case DASHMATCH:
                jj_consume_token(DASHMATCH);
                type = 3;
                break;
            case PREFIXMATCH:
                jj_consume_token(PREFIXMATCH);
                type = 4;
                break;
            case SUFFIXMATCH:
                jj_consume_token(SUFFIXMATCH);
                type = 5;
                break;
            case SUBSTRINGMATCH:
                jj_consume_token(SUBSTRINGMATCH);
                type = 6;
                break;
            default:
                jj_la1[72] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            label_45: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[73] = jj_gen;
                    break label_45;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IDENT:
                value = jj_consume_token(IDENT);
                break;
            case STRING:
                value = jj_consume_token(STRING);
                break;
            default:
                jj_la1[74] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            label_46: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[75] = jj_gen;
                    break label_46;
                }
                jj_consume_token(S);
            }
            break;
        default:
            jj_la1[76] = jj_gen;
            ;
        }
        jj_consume_token(RSQUARE);
        Condition condition = null;

        switch (type) {
        case 0:
            condition = conditionFactory.createAttributeCondition(name.image, null, false, null);
            break;
        case 1:
            condition = conditionFactory.createAttributeCondition(name.image, null, false, value.image);
            break;
        case 2:
            condition = conditionFactory.createOneOfAttributeCondition(name.image, null, false, value.image);
            break;
        case 3:
            condition = conditionFactory.createBeginHyphenAttributeCondition(name.image, null, false, value.image);
            break;
        case 4:
            condition = new PrefixMatchFilter(name.image, value.image);
            break;
        case 5:
            condition = new SuffixMatchFilter(name.image, value.image);
            break;
        case 6:
            condition = new SubstringMatchFilter(name.image, value.image);
            break;
        }

        // check conditional
        if (previous == null) {
            {
                if (true) return condition;
            }
        } else {
            {
                if (true) return conditionFactory.createAndCondition(previous, condition);
            }
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Pseudo Selector ====================== */
    final public Condition pseudo(Condition previous) throws ParseException {
        Condition condition = null;
        Selector selector;
        Token function;
        Token argument;
        jj_consume_token(COLON);
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case IDENT:
            function = jj_consume_token(IDENT);
            try {
                condition = conditionFactory.createPseudoClassCondition(null, function.image);
            } catch (CSSException e) {
                {
                    if (true) throw new ParseException(e.getMessage());
                }
            }
            break;
        case NOT:
            jj_consume_token(NOT);
            label_47: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[77] = jj_gen;
                    break label_47;
                }
                jj_consume_token(S);
            }
            selector = selector();
            label_48: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[78] = jj_gen;
                    break label_48;
                }
                jj_consume_token(S);
            }
            jj_consume_token(RROUND);
            condition = new DenialFIlter(CSSUtil.converte(selector));
            break;
        case FUNCTION:
            function = jj_consume_token(FUNCTION);
            label_49: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[79] = jj_gen;
                    break label_49;
                }
                jj_consume_token(S);
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case NUMBER:
                argument = jj_consume_token(NUMBER);
                break;
            case NUMERAL:
                argument = jj_consume_token(NUMERAL);
                break;
            case IDENT:
                argument = jj_consume_token(IDENT);
                break;
            case STRING:
                argument = jj_consume_token(STRING);
                break;
            default:
                jj_la1[80] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            label_50: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[81] = jj_gen;
                    break label_50;
                }
                jj_consume_token(S);
            }
            jj_consume_token(RROUND);
            String name = function.image.substring(0, function.image.length() - 1);

            // check function name
            if (name.equals("lang")) {
                condition = conditionFactory.createLangCondition(argument.image);
            } else if (name.equals("contains")) {
                condition = conditionFactory.createContentCondition(argument.image);
            } else if (name.equals("nth-child")) {
                condition = new FirstNumeralFilter(argument.image);
            } else if (name.equals("nth-of-type")) {
                condition = new FirstTypedNumeralFilter(argument.image);
            } else if (name.equals("nth-last-child")) {
                condition = new LastNumeralFilter(argument.image);
            } else if (name.equals("nth-last-of-type")) {
                condition = new LastTypedNumeralFilter(argument.image);
            } else {
                {
                    if (true) throw new ParseException("Invalid pseudo function name '" + name + "'.");
                }
            }
            break;
        default:
            jj_la1[82] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        {
            if (true) return (previous == null) ? condition : conditionFactory.createAndCondition(previous, condition);
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Identified Selector ====================== */
    final public Condition hash(Condition previous) throws ParseException {
        Token token;
        token = jj_consume_token(HASH);
        Condition condition = conditionFactory.createIdCondition(token.image.substring(1));

        // check conditional
        if (previous == null) {
            {
                if (true) return condition;
            }
        } else {
            {
                if (true) return conditionFactory.createAndCondition(previous, condition);
            }
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Property Declaration ====================== */
    final public void declaration() throws ParseException {
        String property;
        LexicalUnit unit;
        boolean priority = false;
        try {
            property = property();
            jj_consume_token(COLON);
            label_51: while (true) {
                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
                case S:
                    ;
                    break;
                default:
                    jj_la1[83] = jj_gen;
                    break label_51;
                }
                jj_consume_token(S);
            }
            unit = expr();
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case IMPORTANT_SYM:
                priority = priority();
                break;
            default:
                jj_la1[84] = jj_gen;
                ;
            }
            handler.property(property, unit, priority);
        } catch (ParseException e) {
            skipDeclaration(e);
        }
    }

    /* ====================== Property Priority ====================== */
    final public boolean priority() throws ParseException {
        jj_consume_token(IMPORTANT_SYM);
        label_52: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[85] = jj_gen;
                break label_52;
            }
            jj_consume_token(S);
        }
        {
            if (true) return true;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Property Expression ====================== */
    final public Value expr() throws ParseException {
        Value head;
        Value body;
        head = term(null);
        body = head;
        label_53: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case COMMA:
            case SLASH:
            case STRING:
            case IDENT:
            case NUMBER:
            case URL:
            case UNICODERANGE:
            case ANGLE_DEG:
            case ANGLE_GRAD:
            case ANGLE_RAD:
            case EMS:
            case EXS:
            case FREQ_HZ:
            case FREQ_KHZ:
            case LENGTH_CM:
            case LENGTH_IN:
            case LENGTH_MM:
            case LENGTH_PC:
            case LENGTH_PT:
            case LENGTH_PX:
            case PERCENTAGE:
            case TIME_MS:
            case TIME_S:
            case DIMEN:
            case HASH:
            case RGB:
            case FUNCTION:
                ;
                break;
            default:
                jj_la1[86] = jj_gen;
                break label_53;
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case COMMA:
            case SLASH:
                body = operator(body);
                break;
            default:
                jj_la1[87] = jj_gen;
                ;
            }
            body = term(body);
        }
        {
            if (true) return head;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Operator ====================== */
    final public Value operator(Value prev) throws ParseException {
        Token token;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case SLASH:
            token = jj_consume_token(SLASH);
            break;
        case COMMA:
            token = jj_consume_token(COMMA);
            break;
        default:
            jj_la1[88] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_54: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[89] = jj_gen;
                break label_54;
            }
            jj_consume_token(S);
        }
        {
            if (true) return new CSSOperator(token.image, prev);
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Property Value ====================== */
    final public Value term(Value prev) throws ParseException {
        Token token;
        Value value = null;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case NUMBER:
        case ANGLE_DEG:
        case ANGLE_GRAD:
        case ANGLE_RAD:
        case EMS:
        case EXS:
        case FREQ_HZ:
        case FREQ_KHZ:
        case LENGTH_CM:
        case LENGTH_IN:
        case LENGTH_MM:
        case LENGTH_PC:
        case LENGTH_PT:
        case LENGTH_PX:
        case PERCENTAGE:
        case TIME_MS:
        case TIME_S:
        case DIMEN:
        case FUNCTION:
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case NUMBER:
                token = jj_consume_token(NUMBER);
                value = new CSSNumber(token.image, prev);
                break;
            case PERCENTAGE:
                token = jj_consume_token(PERCENTAGE);
                value = new CSSPercentage(token.image.substring(0, token.image.length() - 1), prev);
                break;
            case LENGTH_PX:
                token = jj_consume_token(LENGTH_PX);
                value = new CSSpxLength(token.image, prev);
                break;
            case LENGTH_CM:
                token = jj_consume_token(LENGTH_CM);
                value = new CSScmLength(token.image, prev);
                break;
            case LENGTH_MM:
                token = jj_consume_token(LENGTH_MM);
                value = new CSSmmLength(token.image, prev);
                break;
            case LENGTH_IN:
                token = jj_consume_token(LENGTH_IN);
                value = new CSSinLength(token.image, prev);
                break;
            case LENGTH_PT:
                token = jj_consume_token(LENGTH_PT);
                value = new CSSptLength(token.image, prev);
                break;
            case LENGTH_PC:
                token = jj_consume_token(LENGTH_PC);
                value = new CSSpcLength(token.image, prev);
                break;
            case EMS:
                token = jj_consume_token(EMS);
                value = new CSSemLength(token.image, prev);
                break;
            case EXS:
                token = jj_consume_token(EXS);
                value = new CSSexLength(token.image, prev);
                break;
            case ANGLE_DEG:
                token = jj_consume_token(ANGLE_DEG);
                value = new CSSdegAngle(token.image, prev);
                break;
            case ANGLE_RAD:
                token = jj_consume_token(ANGLE_RAD);
                value = new CSSradAngle(token.image, prev);
                break;
            case ANGLE_GRAD:
                token = jj_consume_token(ANGLE_GRAD);
                value = new CSSgradAngle(token.image, prev);
                break;
            case TIME_MS:
                token = jj_consume_token(TIME_MS);
                value = new CSSmsTime(token.image, prev);
                break;
            case TIME_S:
                token = jj_consume_token(TIME_S);
                value = new CSSsTime(token.image, prev);
                break;
            case FREQ_HZ:
                token = jj_consume_token(FREQ_HZ);
                value = new CSShzFrequency(token.image, prev);
                break;
            case FREQ_KHZ:
                token = jj_consume_token(FREQ_KHZ);
                value = new CSSkhzFrequency(token.image, prev);
                break;
            case DIMEN:
                token = jj_consume_token(DIMEN);
                {
                    if (true) throw new ParseException("This value '" + token.image + "' has a unknown dimension.");
                }
                break;
            case FUNCTION:
                value = function(prev);
                break;
            default:
                jj_la1[90] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
            }
            break;
        case STRING:
            token = jj_consume_token(STRING);
            value = new CSSString(token.image, prev);
            break;
        case IDENT:
            token = jj_consume_token(IDENT);
            // check color
            if (CSSColor.isDefinedColor(token.image)) {
                value = new CSSColor(token.image, prev);
            } else {
                value = new CSSIdent(token.image, prev);
            }
            break;
        case URL:
            token = jj_consume_token(URL);
            value = new CSSURI(token.image, prev);
            break;
        case RGB:
            value = rgb(prev);
            break;
        case HASH:
            value = hexcolor(prev);
            break;
        case UNICODERANGE:
            token = jj_consume_token(UNICODERANGE);
            value = new CSSUnicodeRange(token.image, prev);
            break;
        default:
            jj_la1[91] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_55: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[92] = jj_gen;
                break label_55;
            }
            jj_consume_token(S);
        }
        {
            if (true) return value;
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== Special Function ====================== */
    final public Value function(Value prev) throws ParseException {
        Token token;
        Value params;
        token = jj_consume_token(FUNCTION);
        label_56: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[93] = jj_gen;
                break label_56;
            }
            jj_consume_token(S);
        }
        params = expr();
        jj_consume_token(RROUND);
        String function = token.image.substring(0, token.image.length() - 1);

        if (function.equals("counter")) {
            {
                if (true) return new CSSCounterFunction(params, prev);
            }
        } else if (function.equals("counters")) {
            {
                if (true) return new CSSCountersFunction(params, prev);
            }
        } else if (function.equals("attr")) {
            {
                if (true) return new CSSAttrFunction(params, prev);
            }
        } else if (function.equals("rect")) {
            {
                if (true) return new CSSRectFunction(params, prev);
            }
        }
        {
            if (true) return new CSSFunction(function, params, prev);
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== RGB Color Units ====================== */
    final public Value rgb(Value previous) throws ParseException {
        Token red;
        Token green;
        Token blue;
        jj_consume_token(RGB);
        label_57: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[94] = jj_gen;
                break label_57;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case NUMBER:
            red = jj_consume_token(NUMBER);
            break;
        case PERCENTAGE:
            red = jj_consume_token(PERCENTAGE);
            break;
        default:
            jj_la1[95] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_58: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[96] = jj_gen;
                break label_58;
            }
            jj_consume_token(S);
        }
        jj_consume_token(COMMA);
        label_59: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[97] = jj_gen;
                break label_59;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case NUMBER:
            green = jj_consume_token(NUMBER);
            break;
        case PERCENTAGE:
            green = jj_consume_token(PERCENTAGE);
            break;
        default:
            jj_la1[98] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_60: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[99] = jj_gen;
                break label_60;
            }
            jj_consume_token(S);
        }
        jj_consume_token(COMMA);
        label_61: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[100] = jj_gen;
                break label_61;
            }
            jj_consume_token(S);
        }
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case NUMBER:
            blue = jj_consume_token(NUMBER);
            break;
        case PERCENTAGE:
            blue = jj_consume_token(PERCENTAGE);
            break;
        default:
            jj_la1[101] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        label_62: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case S:
                ;
                break;
            default:
                jj_la1[102] = jj_gen;
                break label_62;
            }
            jj_consume_token(S);
        }
        jj_consume_token(RROUND);
        try {
            {
                if (true) return new CSSColor(red.image, green.image, blue.image, previous);
            }
        } catch (CSSException e) {
            {
                if (true) throw new ParseException(e.getMessage());
            }
        }
        throw new Error("Missing return statement in function");
    }

    /* ====================== HEX Color Units ====================== */
    // All parse exception ocurred in hex color context are resolved at declaration context.
    final public Value hexcolor(Value previous) throws ParseException {
        Token token;
        token = jj_consume_token(HASH);
        try {
            {
                if (true) return new CSSColor(token.image, previous);
            }
        } catch (CSSException e) {
            {
                if (true) throw new ParseException(e.getMessage());
            }
        }
        throw new Error("Missing return statement in function");
    }

    /**
     * Skip to the end of statement or the end of file.
     * 
     * @return A skipped contents.
     */
    String skip() throws ParseException, ParseException {
        int nesting = 0;
        Token token = getToken(0);
        StringBuffer buffer = new StringBuffer();

        if (token.image != null) {
            buffer.append(token.image);
        }

        do {
            token = getNextToken();

            // check end of file
            if (token.kind == EOF) {
                break;
            }

            buffer.append(token.image);

            // check end of statement
            if (token.kind == LBRACE) {
                nesting++;
            } else if (token.kind == RBRACE) {
                nesting--;
            } else if (token.kind == SEMICOLON && nesting <= 0) {
                break;
            }
        } while (token.kind != RBRACE || nesting > 0);

        return buffer.toString();
    }

    /**
     * Catch a parse error and skip to the end of statement.
     * 
     * @param e A cause.
     * @throws ParseException If parse error is occured.
     */
    void skipDeclaration(Exception e) throws ParseException {
        Token token = getToken(1);
        handleError("Unexpected token is appered in the declaration context, so skip to the next one.", e);

        // check statement
        while (token.kind != SEMICOLON && token.kind != RBRACE && token.kind != EOF) {
            if (token.kind == LBRACE) {
                skipNext();
            }
            getNextToken();
            token = getToken(1);
        }
    }

    void skipNext() throws ParseException {
        int counter = 0;
        getNextToken();
        Token token = getToken(1);

        while (token.kind != RBRACE || counter > 0) {
            if (token.kind == LBRACE) {
                counter++;
            }

            if (token.kind == RBRACE) {
                counter--;
            }
            getNextToken();
            token = getToken(1);
        }
    }

    /**
     * Skip the parser pointing to the next valid block statement.
     * 
     * @param e A cause.
     * @throws ParseException If parse error is occured.
     */
    void skipBlock(ParseException e) throws ParseException {
        int nesting = -1;
        Token token = getNextToken();

        // check EOF
        if (token.kind == EOF) {
            return;
        }
        handleError("Unexpected token is appered in the block context, so skip to the next one.", e);

        // cehck end of block statement
        while (token.kind != RBRACE || nesting > 0) {
            if (token.kind == LBRACE) {
                nesting++;
            } else if (token.kind == RBRACE && nesting > 0) {
                nesting--;
            } else if (token.kind == EOF) {
                break;
            }
            token = getNextToken();
        }
    }

    final private boolean jj_2_1(int xla) {
        jj_la = xla;
        jj_lastpos = jj_scanpos = token;
        try {
            return !jj_3_1();
        } catch (LookaheadSuccess ls) {
            return true;
        } finally {
            jj_save(0, xla);
        }
    }

    final private boolean jj_2_2(int xla) {
        jj_la = xla;
        jj_lastpos = jj_scanpos = token;
        try {
            return !jj_3_2();
        } catch (LookaheadSuccess ls) {
            return true;
        } finally {
            jj_save(1, xla);
        }
    }

    final private boolean jj_3R_80() {
        if (jj_3R_84()) return true;
        return false;
    }

    final private boolean jj_3R_74() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_80()) {
            jj_scanpos = xsp;
            if (jj_3R_81()) {
                jj_scanpos = xsp;
                if (jj_3R_82()) {
                    jj_scanpos = xsp;
                    if (jj_3R_83()) return true;
                }
            }
        }
        return false;
    }

    final private boolean jj_3R_68() {
        Token xsp;
        if (jj_3R_74()) return true;
        while (true) {
            xsp = jj_scanpos;
            if (jj_3R_74()) {
                jj_scanpos = xsp;
                break;
            }
        }
        return false;
    }

    final private boolean jj_3R_78() {
        if (jj_scan_token(IDENT)) return true;
        return false;
    }

    final private boolean jj_3R_67() {
        if (jj_3R_73()) return true;
        return false;
    }

    final private boolean jj_3R_73() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_78()) {
            jj_scanpos = xsp;
            if (jj_3R_79()) return true;
        }
        return false;
    }

    final private boolean jj_3R_76() {
        if (jj_scan_token(GT)) return true;
        return false;
    }

    final private boolean jj_3R_64() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_67()) {
            jj_scanpos = xsp;
            if (jj_3R_68()) return true;
        }
        return false;
    }

    final private boolean jj_3R_82() {
        if (jj_3R_86()) return true;
        return false;
    }

    final private boolean jj_3R_70() {
        if (jj_scan_token(GT)) return true;
        return false;
    }

    final private boolean jj_3R_85() {
        if (jj_scan_token(DOT)) return true;
        return false;
    }

    final private boolean jj_3R_75() {
        if (jj_scan_token(PLUS)) return true;
        return false;
    }

    final private boolean jj_3R_72() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_75()) {
            jj_scanpos = xsp;
            if (jj_3R_76()) {
                jj_scanpos = xsp;
                if (jj_3R_77()) return true;
            }
        }
        return false;
    }

    final private boolean jj_3_2() {
        if (jj_3R_63()) return true;
        if (jj_3R_64()) return true;
        return false;
    }

    final private boolean jj_3R_81() {
        if (jj_3R_85()) return true;
        return false;
    }

    final private boolean jj_3R_87() {
        if (jj_scan_token(COLON)) return true;
        return false;
    }

    final private boolean jj_3R_69() {
        if (jj_scan_token(PLUS)) return true;
        return false;
    }

    final private boolean jj_3R_66() {
        if (jj_scan_token(S)) return true;
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_72()) jj_scanpos = xsp;
        return false;
    }

    final private boolean jj_3R_65() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_69()) {
            jj_scanpos = xsp;
            if (jj_3R_70()) {
                jj_scanpos = xsp;
                if (jj_3R_71()) return true;
            }
        }
        while (true) {
            xsp = jj_scanpos;
            if (jj_scan_token(35)) {
                jj_scanpos = xsp;
                break;
            }
        }
        return false;
    }

    final private boolean jj_3_1() {
        if (jj_scan_token(IDENT)) return true;
        Token xsp;
        while (true) {
            xsp = jj_scanpos;
            if (jj_scan_token(35)) {
                jj_scanpos = xsp;
                break;
            }
        }
        return false;
    }

    final private boolean jj_3R_77() {
        if (jj_scan_token(TILDE)) return true;
        return false;
    }

    final private boolean jj_3R_86() {
        if (jj_scan_token(LSQUARE)) return true;
        return false;
    }

    final private boolean jj_3R_63() {
        Token xsp;
        xsp = jj_scanpos;
        if (jj_3R_65()) {
            jj_scanpos = xsp;
            if (jj_3R_66()) return true;
        }
        return false;
    }

    final private boolean jj_3R_84() {
        if (jj_scan_token(HASH)) return true;
        return false;
    }

    final private boolean jj_3R_83() {
        if (jj_3R_87()) return true;
        return false;
    }

    final private boolean jj_3R_71() {
        if (jj_scan_token(TILDE)) return true;
        return false;
    }

    final private boolean jj_3R_79() {
        if (jj_scan_token(ASTERISK)) return true;
        return false;
    }

    public CueryParserTokenManager token_source;

    JavaCharStream jj_input_stream;

    public Token token, jj_nt;

    private int jj_ntk;

    private Token jj_scanpos, jj_lastpos;

    private int jj_la;

    public boolean lookingAhead = false;

    private boolean jj_semLA;

    private int jj_gen;

    final private int[] jj_la1 = new int[103];

    static private int[] jj_la1_0;

    static private int[] jj_la1_1;

    static private int[] jj_la1_2;
    static {
        jj_la1_0();
        jj_la1_1();
        jj_la1_2();
    }

    private static void jj_la1_0() {
        jj_la1_0 = new int[] {0x0, 0x0, 0x100, 0x0, 0x0, 0xf0010680, 0x0, 0x0, 0x4000000, 0x0, 0x0, 0x20000000, 0x0,
                0x0, 0xd0010680, 0xd0010680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80010680, 0x40, 0x0, 0x80010680,
                0x0, 0x80010680, 0x80010680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200, 0x200, 0x0, 0x0, 0x100, 0x0, 0x0, 0x0,
                0x0, 0x0, 0x100, 0x0, 0x0, 0x109000, 0x0, 0x109000, 0x0, 0x109000, 0x109000, 0x0, 0x0, 0x0, 0x100, 0x0,
                0x0, 0x40, 0x0, 0x0, 0x10280, 0x10280, 0x10280, 0x10280, 0x10680, 0x400, 0x0, 0x0, 0x4000, 0x0, 0x0,
                0x0, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x840, 0x840, 0x840, 0x0, 0x0, 0x0, 0x0, 0x0,
                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,};
    }

    private static void jj_la1_1() {
        jj_la1_1 = new int[] {0x8, 0x8000, 0x0, 0x8, 0x8000, 0x8004, 0x8, 0x8, 0x0, 0x8, 0x8, 0x0, 0x8, 0x8, 0x8004,
                0x8004, 0x8, 0x8, 0x8, 0x44000, 0x8, 0x8000, 0x8, 0x8, 0x8004, 0x0, 0x8, 0x8004, 0x8, 0x8004, 0x8004,
                0x8, 0x8, 0x8, 0x8, 0x8, 0x8000, 0x8000, 0x8, 0x8000, 0x0, 0x8, 0x8000, 0x8, 0x8, 0x8000, 0x0, 0x8,
                0x8000, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x8, 0x8, 0x8000, 0x0, 0x8, 0x8000, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0,
                0x0, 0x8000, 0x8000, 0x8, 0x8, 0x0, 0x8, 0xc000, 0x8, 0x0, 0x8, 0x8, 0x8, 0x3c000, 0x8, 0x8000, 0x8,
                0x0, 0x8, 0xe00dc000, 0x0, 0x0, 0x8, 0xe0010000, 0xe00dc000, 0x8, 0x8, 0x8, 0x10000, 0x8, 0x8, 0x10000,
                0x8, 0x8, 0x10000, 0x8,};
    }

    private static void jj_la1_2() {
        jj_la1_2 = new int[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x0, 0x0, 0x0, 0x60000, 0x60000, 0x0, 0x60000, 0x60000,
                0x80000, 0x80000, 0x60000, 0x60000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x0, 0x0, 0x80000, 0x0,
                0x80000, 0x80000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
                0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x80000,
                0x80000, 0x80000, 0x80000, 0x0, 0x0, 0x0, 0x1f00000, 0x0, 0x0, 0x0, 0x1f00000, 0x0, 0x0, 0x0, 0x0, 0x0,
                0x30000000, 0x0, 0x2000000, 0x0, 0x2808bfbf, 0x0, 0x0, 0x0, 0x2000bfbf, 0x2808bfbf, 0x0, 0x0, 0x0,
                0x800, 0x0, 0x0, 0x800, 0x0, 0x0, 0x800, 0x0,};
    }

    final private JJCalls[] jj_2_rtns = new JJCalls[2];

    private boolean jj_rescan = false;

    private int jj_gc = 0;

    public CueryParser(java.io.InputStream stream) {
        this(stream, null);
    }

    public CueryParser(java.io.InputStream stream, String encoding) {
        try {
            jj_input_stream = new JavaCharStream(stream, encoding, 1, 1);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        token_source = new CueryParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    public void ReInit(java.io.InputStream stream) {
        ReInit(stream);
    }

    public void ReInit(java.io.InputStream stream, String encoding) {
        try {
            jj_input_stream.ReInit(stream, encoding, 1, 1);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    public CueryParser(java.io.Reader stream) {
        jj_input_stream = new JavaCharStream(stream, 1, 1);
        token_source = new CueryParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    public void ReInit(java.io.Reader stream) {
        jj_input_stream.ReInit(stream, 1, 1);
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    public CueryParser(CueryParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    public void ReInit(CueryParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 103; i++)
            jj_la1[i] = -1;
        for (int i = 0; i < jj_2_rtns.length; i++)
            jj_2_rtns[i] = new JJCalls();
    }

    final private Token jj_consume_token(int kind) throws ParseException {
        Token oldToken;
        if ((oldToken = token).next != null)
            token = token.next;
        else
            token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        if (token.kind == kind) {
            jj_gen++;
            if (++jj_gc > 100) {
                jj_gc = 0;
                for (int i = 0; i < jj_2_rtns.length; i++) {
                    JJCalls c = jj_2_rtns[i];
                    while (c != null) {
                        if (c.gen < jj_gen) c.first = null;
                        c = c.next;
                    }
                }
            }
            return token;
        }
        token = oldToken;
        jj_kind = kind;
        throw generateParseException();
    }

    static private final class LookaheadSuccess extends java.lang.Error {
    }

    final private LookaheadSuccess jj_ls = new LookaheadSuccess();

    final private boolean jj_scan_token(int kind) {
        if (jj_scanpos == jj_lastpos) {
            jj_la--;
            if (jj_scanpos.next == null) {
                jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
            } else {
                jj_lastpos = jj_scanpos = jj_scanpos.next;
            }
        } else {
            jj_scanpos = jj_scanpos.next;
        }
        if (jj_rescan) {
            int i = 0;
            Token tok = token;
            while (tok != null && tok != jj_scanpos) {
                i++;
                tok = tok.next;
            }
            if (tok != null) jj_add_error_token(kind, i);
        }
        if (jj_scanpos.kind != kind) return true;
        if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
        return false;
    }

    final public Token getNextToken() {
        if (token.next != null)
            token = token.next;
        else
            token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        jj_gen++;
        return token;
    }

    final public Token getToken(int index) {
        Token t = lookingAhead ? jj_scanpos : token;
        for (int i = 0; i < index; i++) {
            if (t.next != null)
                t = t.next;
            else
                t = t.next = token_source.getNextToken();
        }
        return t;
    }

    final private int jj_ntk() {
        if ((jj_nt = token.next) == null)
            return (jj_ntk = (token.next = token_source.getNextToken()).kind);
        else
            return (jj_ntk = jj_nt.kind);
    }

    private java.util.Vector<int[]> jj_expentries = new java.util.Vector<int[]>();

    private int[] jj_expentry;

    private int jj_kind = -1;

    private int[] jj_lasttokens = new int[100];

    private int jj_endpos;

    private void jj_add_error_token(int kind, int pos) {
        if (pos >= 100) return;
        if (pos == jj_endpos + 1) {
            jj_lasttokens[jj_endpos++] = kind;
        } else if (jj_endpos != 0) {
            jj_expentry = new int[jj_endpos];
            for (int i = 0; i < jj_endpos; i++) {
                jj_expentry[i] = jj_lasttokens[i];
            }
            boolean exists = false;
            for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
                int[] oldentry = (int[]) (e.nextElement());
                if (oldentry.length == jj_expentry.length) {
                    exists = true;
                    for (int i = 0; i < jj_expentry.length; i++) {
                        if (oldentry[i] != jj_expentry[i]) {
                            exists = false;
                            break;
                        }
                    }
                    if (exists) break;
                }
            }
            if (!exists) jj_expentries.addElement(jj_expentry);
            if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
        }
    }

    public ParseException generateParseException() {
        jj_expentries.removeAllElements();
        boolean[] la1tokens = new boolean[95];
        for (int i = 0; i < 95; i++) {
            la1tokens[i] = false;
        }
        if (jj_kind >= 0) {
            la1tokens[jj_kind] = true;
            jj_kind = -1;
        }
        for (int i = 0; i < 103; i++) {
            if (jj_la1[i] == jj_gen) {
                for (int j = 0; j < 32; j++) {
                    if ((jj_la1_0[i] & (1 << j)) != 0) {
                        la1tokens[j] = true;
                    }
                    if ((jj_la1_1[i] & (1 << j)) != 0) {
                        la1tokens[32 + j] = true;
                    }
                    if ((jj_la1_2[i] & (1 << j)) != 0) {
                        la1tokens[64 + j] = true;
                    }
                }
            }
        }
        for (int i = 0; i < 95; i++) {
            if (la1tokens[i]) {
                jj_expentry = new int[1];
                jj_expentry[0] = i;
                jj_expentries.addElement(jj_expentry);
            }
        }
        jj_endpos = 0;
        jj_rescan_token();
        jj_add_error_token(0, 0);
        int[][] exptokseq = new int[jj_expentries.size()][];
        for (int i = 0; i < jj_expentries.size(); i++) {
            exptokseq[i] = (int[]) jj_expentries.elementAt(i);
        }
        return new ParseException(token, exptokseq, tokenImage);
    }

    final public void enable_tracing() {
    }

    final public void disable_tracing() {
    }

    final private void jj_rescan_token() {
        jj_rescan = true;
        for (int i = 0; i < 2; i++) {
            try {
                JJCalls p = jj_2_rtns[i];
                do {
                    if (p.gen > jj_gen) {
                        jj_la = p.arg;
                        jj_lastpos = jj_scanpos = p.first;
                        switch (i) {
                        case 0:
                            jj_3_1();
                            break;
                        case 1:
                            jj_3_2();
                            break;
                        }
                    }
                    p = p.next;
                } while (p != null);
            } catch (LookaheadSuccess ls) {
            }
        }
        jj_rescan = false;
    }

    final private void jj_save(int index, int xla) {
        JJCalls p = jj_2_rtns[index];
        while (p.gen > jj_gen) {
            if (p.next == null) {
                p = p.next = new JJCalls();
                break;
            }
            p = p.next;
        }
        p.gen = jj_gen + xla - jj_la;
        p.first = token;
        p.arg = xla;
    }

    static final class JJCalls {

        int gen;

        Token first;

        int arg;

        JJCalls next;
    }

}
