@Override
	public ASTNode parse(Token token) throws Exception {
	    Token startingToken = token;
		token = nextToken();  // consume the CASE

		Expr conditionNode = null;
		Expr elseExpr = null;
		List<Pair<Expr, Expr>> whenExprs = new ArrayList<Pair<Expr,Expr>>();

		// if { or WHEN, put in a TRUE
		LeolaTokenType type = token.getType();
		if ( CASE_SET.contains(type) ) {
			conditionNode = new BooleanExpr(true);
		}
		else {
	        // Parse the expression.
	        // The CASE node adopts the expression subtree as its first child.
	        conditionNode = parseExpr(token);
		}

        boolean hasOpeningBrace = false;

        // expect either the { or WHEN.
        token = expectedTokens(CASE_SET);
        type = token.getType();

        if ( type.equals(WHEN) ) {
            token = nextToken(); // eat the token ({ or WHEN)

            Pair<Expr, Expr> whenExpr = parseWhen(token);
            whenExprs.add(whenExpr);

            eatOptionalStmtEnd(currentToken());

            token = currentToken();

            if ( token.getType().equals(ELSE) ) {
                token = nextToken(); // eat ELSE
                elseExpr = parseExpr(token);
            }

        }
        else if ( type.equals(LEFT_BRACE) ) {
            hasOpeningBrace = true;

            token = nextToken(); // eat the token {
            type = token.getType();

            while( type.equals(WHEN)) {
                token = nextToken(); // eat the token WHEN

                Pair<Expr, Expr> whenExpr = parseWhen(token);
                whenExprs.add(whenExpr);

                eatOptionalStmtEnd(currentToken());
                type = currentToken().getType();

            }

            token = currentToken();

            if ( token.getType().equals(ELSE) ) {
                token = nextToken(); // eat ELSE
                elseExpr = parseExpr(token);
            }

        }
        else {
            throwParseError(token, LeolaErrorCode.MISSING_LEFT_BRACE);
        }

        token = currentToken();
        if ( token.getType().equals(RIGHT_BRACE) && hasOpeningBrace) {
            nextToken();
        }
        else if ( hasOpeningBrace ) {
            throwParseError(token, LeolaErrorCode.MISSING_RIGHT_BRACE);
        }

        CaseExpr caseExpr = new CaseExpr(conditionNode, whenExprs, elseExpr);
        setLineNumber(caseExpr, startingToken);

        return caseExpr;
	}