/**********************************************************************
 * Copyright (c) 2002,2003 Rational Software Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: 
 * Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.cdt.core.parser.BacktrackException;
import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ScannerException;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
import org.eclipse.cdt.core.parser.ast.ASTSemanticException;
import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
import org.eclipse.cdt.core.parser.ast.IASTArrayModifier;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTDesignator;
import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTExpression;
import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTOffsetableElement;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTTemplate;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter;
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.core.parser.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
import org.eclipse.cdt.internal.core.parser.KeywordSets.Key;

/**
 * This is our first implementation of the IParser interface, serving as a parser for
 * ANSI C and C++.
 * 
 * From time to time we will make reference to the ANSI ISO specifications.
 * 
 * @author jcamelon
 */
public abstract class Parser implements IParser
{
    protected final IParserLogService log;
	private static final List EMPTY_LIST = new ArrayList();
    private static int FIRST_ERROR_OFFSET_UNSET = -1;
    // sentinel initial value for offsets 
    protected int firstErrorOffset = FIRST_ERROR_OFFSET_UNSET;
    // offset where the first parse error occurred
   
    // are we doing the high-level parse, or an in depth parse?
    protected boolean parsePassed = true; // did the parse pass?
    protected ParserLanguage language = ParserLanguage.CPP; // C or CPP
    protected ISourceElementRequestor requestor = null;
    // new callback mechanism
    protected IASTFactory astFactory = null; // ast factory
    /**
     * This is the single entry point for setting parsePassed to 
     * false, and also making note what token offset we failed upon. 
     * 
     * @throws EndOfFileException
     */
    protected void failParse()
    {
    	try
    	{
	        if (firstErrorOffset == FIRST_ERROR_OFFSET_UNSET )
	            firstErrorOffset = LA(1).getOffset();
    	} catch( EndOfFileException eof )
    	{
    		// do nothing
    	}
    	finally
    	{
	        parsePassed = false;
    	}
    }
    /**
     * This is the standard cosntructor that we expect the Parser to be instantiated 
     * with.  
     * 
     * @param s				IScanner instance that has been initialized to the code input 
     * @param c				IParserCallback instance that will receive callbacks as we parse
     * @param quick			Are we asking for a high level parse or not? 
     */
    public Parser(
        IScanner scanner,
        ISourceElementRequestor callback,
        ParserLanguage language,
        IParserLogService log )
    {
        this.scanner = scanner;
        this.requestor = callback;
        this.language = language;
        this.log = log;
    }
    
    // counter that keeps track of the number of times Parser.parse() is called
    private static int parseCount = 0;
    
    /* (non-Javadoc)
     * @see org.eclipse.cdt.internal.core.parser.IParser#parse()
     */
    public boolean parse()
    {
        long startTime = System.currentTimeMillis();
        translationUnit();
        // For the debuglog to take place, you have to call
        // Util.setDebugging(true);
        // Or set debug to true in the core plugin preference 
        log.traceLog(
            "Parse "
                + (++parseCount)
                + ": "
                + (System.currentTimeMillis() - startTime)
                + "ms"
                + (parsePassed ? "" : " - parse failure") );
        return parsePassed;
    }
        
    
    /**
     * This is the top-level entry point into the ANSI C++ grammar.  
     * 
     * translationUnit  : (declaration)*
     */
    protected void translationUnit()
    {
        IASTCompilationUnit compilationUnit;
        try
        {
            compilationUnit = astFactory.createCompilationUnit();
        }
        catch (Exception e2)
        {
            return;
        }

		compilationUnit.enterScope( requestor );            
        IToken lastBacktrack = null;
        IToken checkToken = null;
        while (true)
        {
            try
            {
                checkToken = LA(1);
                declaration(compilationUnit, null);
                if (LA(1) == checkToken)
                    errorHandling();
            }
            catch (EndOfFileException e)
            {
                // Good
                break;
            }
            catch (BacktrackException b)
            {
                try
                {
                    // Mark as failure and try to reach a recovery point
                    failParse();
                    if (lastBacktrack != null && lastBacktrack == LA(1))
                    {
                        // we haven't progressed from the last backtrack
                        // try and find tne next definition
                        errorHandling();
                    }
                    else
                    {
                        // start again from here
                        lastBacktrack = LA(1);
                    }
                }
                catch (EndOfFileException e)
                {
                    break;
                }
            }
            catch (Exception e)
            {
				failParse();
                break;
            }
        }
        compilationUnit.exitScope( requestor );
    }
    /**
     * This function is called whenever we encounter and error that we cannot backtrack out of and we 
     * still wish to try and continue on with the parse to do a best-effort parse for our client. 
     * 
     * @throws EndOfFileException  	We can potentially hit EndOfFile here as we are skipping ahead.  
     */
    protected void errorHandling() throws EndOfFileException
    {
        failParse();
        consume();
        int depth = 0;
        while (!((LT(1) == IToken.tSEMI && depth == 0)
            || (LT(1) == IToken.tRBRACE && depth == 1)))
        {
            switch (LT(1))
            {
                case IToken.tLBRACE :
                    ++depth;
                    break;
                case IToken.tRBRACE :
                    --depth;
                    break;
            }
            consume();
        }
        // eat the SEMI/RBRACE as well
        consume();
    }
    /**
     * The merger of using-declaration and using-directive in ANSI C++ grammar.  
     * 
     * using-declaration:
     *	using typename? ::? nested-name-specifier unqualified-id ;
     *	using :: unqualified-id ;
     * using-directive:
     *  using namespace ::? nested-name-specifier? namespace-name ;
     * 
     * @param container		Callback object representing the scope these definitions fall into. 
     * @throws BacktrackException	request for a backtrack
     */
    protected void usingClause(IASTScope scope)
        throws EndOfFileException, BacktrackException
    {
        IToken firstToken = consume(IToken.t_using);
        if (LT(1) == IToken.t_namespace)
        {
            // using-directive
            consume(IToken.t_namespace);
            // optional :: and nested classes handled in name
            TokenDuple duple = null;
            if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON)
                duple = name();
            else
                throw backtrack;
            if (LT(1) == IToken.tSEMI)
            {
                IToken last = consume(IToken.tSEMI);
                IASTUsingDirective astUD = null; 
                
                try
                {
                    astUD = astFactory.createUsingDirective(scope, duple, firstToken.getOffset(), last.getEndOffset());
                }
                catch (Exception e1)
                {
                    throw backtrack;
                }
                astUD.acceptElement(requestor);
                return;
            }
            else
            {
                throw backtrack;
            }
        }
        else
        {
            boolean typeName = false;
            if (LT(1) == IToken.t_typename)
            {
                typeName = true;
                consume(IToken.t_typename);
            }
            TokenDuple name = null;
            if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON)
            {
                //	optional :: and nested classes handled in name
                name = name();
            }
            else
            {
                throw backtrack;
            }
            if (LT(1) == IToken.tSEMI)
            {
                IToken last = consume(IToken.tSEMI);
                IASTUsingDeclaration declaration = null;
                try
                {
                    declaration =
                        astFactory.createUsingDeclaration(
                            scope,
                            typeName,
                            name,
                            firstToken.getOffset(),
                            last.getEndOffset());
                }
                catch (Exception e1)
                {
                    throw backtrack;
                }
                declaration.acceptElement( requestor );
            }
            else
            {
                throw backtrack;
            }
        }
    }
    /**
     * Implements Linkage specification in the ANSI C++ grammar. 
     * 
     * linkageSpecification
     * : extern "string literal" declaration
     * | extern "string literal" { declaration-seq } 
     * 
     * @param container Callback object representing the scope these definitions fall into.
     * @throws BacktrackException	request for a backtrack
     */
    protected void linkageSpecification(IASTScope scope)
        throws EndOfFileException, BacktrackException
    {
        IToken firstToken = consume(IToken.t_extern);
        if (LT(1) != IToken.tSTRING)
            throw backtrack;
        IToken spec = consume(IToken.tSTRING);
  
        if (LT(1) == IToken.tLBRACE)
        {
            consume(IToken.tLBRACE);
            IASTLinkageSpecification linkage;
            try
            {
                linkage =
                    astFactory.createLinkageSpecification(
                        scope,
                        spec.getImage(),
                        firstToken.getOffset());
            }
            catch (Exception e)
            {
                throw backtrack;
            }
            
            linkage.enterScope( requestor );    
            linkageDeclarationLoop : while (LT(1) != IToken.tRBRACE)
            {
                IToken checkToken = LA(1);
                switch (LT(1))
                {
                    case IToken.tRBRACE :
                        consume(IToken.tRBRACE);
                        break linkageDeclarationLoop;
                    default :
                        try
                        {
                            declaration(linkage, null);
                        }
                        catch (BacktrackException bt)
                        {
                            failParse();
                            if (checkToken == LA(1))
                                errorHandling();
                        }
                }
                if (checkToken == LA(1))
                    errorHandling();
            }
            // consume the }
            IToken lastToken = consume();
            linkage.setEndingOffset(lastToken.getEndOffset());
            linkage.exitScope( requestor );
        }
        else // single declaration
            {
            IASTLinkageSpecification linkage;
            try
            {
                linkage =
                    astFactory.createLinkageSpecification(
                        scope,
                        spec.getImage(),
                        firstToken.getOffset());
            }
            catch (Exception e)
            {
                throw backtrack;
            }
			linkage.enterScope( requestor );
            declaration(linkage, null);
			linkage.exitScope( requestor );
        }
    }
    /**
     * 
     * Represents the emalgamation of template declarations, template instantiations and 
     * specializations in the ANSI C++ grammar.  
     * 
     * template-declaration:	export? template < template-parameter-list > declaration
     * explicit-instantiation:	template declaration
     * explicit-specialization:	template <> declaration
     *  
     * @param container			Callback object representing the scope these definitions fall into.
     * @throws BacktrackException		request for a backtrack
     */
    protected void templateDeclaration(IASTScope scope)
        throws EndOfFileException, BacktrackException
    {
        IToken firstToken = null;
        boolean exported = false; 
        if (LT(1) == IToken.t_export)
        {
        	exported = true;
            firstToken = consume(IToken.t_export);
            consume(IToken.t_template);
        }
        else
            firstToken = consume(IToken.t_template);
        if (LT(1) != IToken.tLT)
        {
            // explicit-instantiation
            IASTTemplateInstantiation templateInstantiation;
            try
            {
                templateInstantiation =
                    astFactory.createTemplateInstantiation(
                        scope,
                        firstToken.getOffset());
            }
            catch (Exception e)
            {
                throw backtrack;
            }
            templateInstantiation.enterScope( requestor );
            declaration(scope, templateInstantiation);
            templateInstantiation.setEndingOffset(lastToken.getEndOffset());
			templateInstantiation.exitScope( requestor );
 
            return;
        }
        else
        {
            consume(IToken.tLT);
            if (LT(1) == IToken.tGT)
            {
                consume(IToken.tGT);
                // explicit-specialization
                
                IASTTemplateSpecialization templateSpecialization;
                try
                {
                    templateSpecialization =
                        astFactory.createTemplateSpecialization(
                            scope,
                            firstToken.getOffset());
                }
                catch (Exception e)
                {
                    throw backtrack;
                }
				templateSpecialization.enterScope(requestor);
                declaration(scope, templateSpecialization);
                templateSpecialization.setEndingOffset(
                    lastToken.getEndOffset());
                templateSpecialization.exitScope(requestor);
                return;
            }
        }
        
        try
        {
            List parms = templateParameterList(scope);
            consume(IToken.tGT);
            IASTTemplateDeclaration templateDecl;
            try
            {
                templateDecl =
                    astFactory.createTemplateDeclaration(
                        scope,
                        parms,
                        exported,
                        firstToken.getOffset());
            }
            catch (Exception e)
            {
                throw backtrack;
            }
            templateDecl.enterScope( requestor );
            declaration(scope, templateDecl );
			templateDecl.setEndingOffset(
				lastToken.getEndOffset() );
			templateDecl.exitScope( requestor );
            
        }
        catch (BacktrackException bt)
        {
            throw bt;
        }
    }
    /**
     * 
     * 
     * 
    	 * template-parameter-list:	template-parameter
     *							template-parameter-list , template-parameter
     * template-parameter:		type-parameter
     *							parameter-declaration
     * type-parameter:			class identifier?
     *							class identifier? = type-id
     * 							typename identifier?
     * 							typename identifier? = type-id
     *							template < template-parameter-list > class identifier?
     *							template < template-parameter-list > class identifier? = id-expression
     * template-id:				template-name < template-argument-list?>
     * template-name:			identifier
     * template-argument-list:	template-argument
     *							template-argument-list , template-argument
     * template-argument:		assignment-expression
     *							type-id
     *							id-expression
     *
     * @param templateDeclaration		Callback's templateDeclaration which serves as a scope to this list.  
     * @throws BacktrackException				request for a backtrack
     */
    protected List templateParameterList(IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        // if we have gotten this far then we have a true template-declaration
        // iterate through the template parameter list
        List returnValue = new ArrayList();
 
        for (;;)
        {
            if (LT(1) == IToken.tGT)
                return returnValue;
            if (LT(1) == IToken.t_class || LT(1) == IToken.t_typename)
            {
                IASTTemplateParameter.ParamKind kind =
                    (consume().getType() == IToken.t_class)
                        ? IASTTemplateParameter.ParamKind.CLASS
                        : IASTTemplateParameter.ParamKind.TYPENAME;
				
				IToken id = null;
				IASTTypeId typeId = null;
                try
                {
                    if (LT(1) == IToken.tIDENTIFIER) // optional identifier
                    {
                        id = identifier();
                        
                        if (LT(1) == IToken.tASSIGN) // optional = type-id
                        {
                            consume(IToken.tASSIGN);
                            typeId = typeId(scope, false); // type-id
                        }
                    }

                }
                catch (BacktrackException bt)
                {
                    throw bt;
                }
				try
                {
                    returnValue.add(
                    	astFactory.createTemplateParameter(
                    		kind,
                    		( id == null )? "" : id.getImage(),
                    		(typeId == null) ? null : typeId.getTypeOrClassName(),
                    		null,
                    		null));
                }
                catch (Exception e)
                {
                    throw backtrack;
                }

            }
            else if (LT(1) == IToken.t_template)
            {
                consume(IToken.t_template);
                consume(IToken.tLT);

                List subResult = templateParameterList(scope);
                consume(IToken.tGT);
                consume(IToken.t_class);
                IToken optionalId = null;
                IASTTypeId optionalTypeId = null;
                if (LT(1) == IToken.tIDENTIFIER) // optional identifier
                {
                    optionalId = identifier();
   
                    if (LT(1) == IToken.tASSIGN) // optional = type-id
                    {
                        consume(IToken.tASSIGN);
                        optionalTypeId = typeId(scope, false);
    
                    }
                }
 
                try
                {
                    returnValue.add(
                        astFactory.createTemplateParameter(
                            IASTTemplateParameter.ParamKind.TEMPLATE_LIST,
                            ( optionalId == null )? "" : optionalId.getImage(),
                            ( optionalTypeId == null )  ? "" : optionalTypeId.toString(),
                            null,
                            subResult));
                }
                catch (Exception e)
                {
                    throw backtrack;
                }
            }
            else if (LT(1) == IToken.tCOMMA)
            {
                consume(IToken.tCOMMA);
                continue;
            }
            else
            {
                ParameterCollection c = new ParameterCollection();
                parameterDeclaration(c, scope);
                DeclarationWrapper wrapper =
                    (DeclarationWrapper)c.getParameters().get(0);
                Declarator declarator =
                    (Declarator)wrapper.getDeclarators().next();
                try
                {
                    returnValue.add(
                        astFactory.createTemplateParameter(
                            IASTTemplateParameter.ParamKind.PARAMETER,
                            null,
                            null,
                            astFactory.createParameterDeclaration(
                                wrapper.isConst(),
                                wrapper.isVolatile(),
                                wrapper.getTypeSpecifier(),
                                declarator.getPointerOperators(),
                                declarator.getArrayModifiers(),
                                null, null, declarator.getName() == null
                                                ? ""
                                                : declarator.getName(), declarator.getInitializerClause(), wrapper.getStartingOffset(), declarator.getNameStartOffset(), declarator.getNameEndOffset(), wrapper.getEndOffset()),
                            null));
                }
                catch (Exception e)
                {
                    throw backtrack;
                }
            }
        }
    }
    /**
     * The most abstract construct within a translationUnit : a declaration.  
     * 
     * declaration
     * : {"asm"} asmDefinition
     * | {"namespace"} namespaceDefinition
     * | {"using"} usingDeclaration
     * | {"export"|"template"} templateDeclaration
     * | {"extern"} linkageSpecification
     * | simpleDeclaration
     * 
     * Notes:
     * - folded in blockDeclaration
     * - merged alternatives that required same LA
     *   - functionDefinition into simpleDeclaration
     *   - namespaceAliasDefinition into namespaceDefinition
     *   - usingDirective into usingDeclaration
     *   - explicitInstantiation and explicitSpecialization into
     *       templateDeclaration
     * 
     * @param container		IParserCallback object which serves as the owner scope for this declaration.  
     * @throws BacktrackException	request a backtrack
     */
    protected void declaration(
        IASTScope scope,
        IASTTemplate ownerTemplate)
        throws EndOfFileException, BacktrackException
    {
    	setCurrentScope(scope);
    	setCompletionKeywords( Key.DECLARATION );
        switch (LT(1))
        {
            case IToken.t_asm :
                IToken first = consume(IToken.t_asm);
                setCompletionKind( CompletionKind.NO_SUCH_KIND );
                consume(IToken.tLPAREN);
                String assembly = consume(IToken.tSTRING).getImage();
                consume(IToken.tRPAREN);
                IToken last = consume(IToken.tSEMI);
                IASTASMDefinition asmDefinition;
                try
                {
                    asmDefinition =
                        astFactory.createASMDefinition(
                            scope,
                            assembly,
                            first.getOffset(),
                            last.getEndOffset());
                }
                catch (Exception e)
                {
                    throw backtrack;
                }
                // if we made it this far, then we have all we need 
                // do the callback
 				asmDefinition.acceptElement(requestor);
                return;
            case IToken.t_namespace :
                namespaceDefinition(scope);
                return;
            case IToken.t_using :
                usingClause(scope);
                return;
            case IToken.t_export :
            case IToken.t_template :
                templateDeclaration(scope);
                return;
            case IToken.t_extern :
                if (LT(2) == IToken.tSTRING)
                {
                    linkageSpecification(scope);
                    return;
                }
            default :
                simpleDeclarationStrategyUnion(scope, ownerTemplate);
        }
        setCurrentScope(scope);
        setCompletionKeywords( Key.DECLARATION );
        
    }
    protected void simpleDeclarationStrategyUnion(
        IASTScope scope,
        IASTTemplate ownerTemplate)
        throws EndOfFileException, BacktrackException
    {
        IToken mark = mark();
        
        if( scope instanceof IASTClassSpecifier )
        	setCompletionKind( CompletionKind.FIELD_TYPE );
        else if (scope instanceof IASTCodeScope)
        	setCompletionKind( CompletionKind.SINGLE_NAME_REFERENCE);
        else
        	setCompletionKind( CompletionKind.VARIABLE_TYPE );
        try
        {
            simpleDeclaration(
                SimpleDeclarationStrategy.TRY_CONSTRUCTOR,
                scope,
                ownerTemplate);
            // try it first with the original strategy
        }
        catch (BacktrackException bt)
        {
            // did not work 
            backup(mark);
            
            try
            {  
            	simpleDeclaration(
                	SimpleDeclarationStrategy.TRY_FUNCTION,
	                scope,
    	            ownerTemplate);
            }
            catch( BacktrackException bt2 )
            {
            	backup( mark ); 

				try
				{
					simpleDeclaration(
						SimpleDeclarationStrategy.TRY_VARIABLE,
						scope,
						ownerTemplate);
				}
				catch( BacktrackException b3 )
				{
					backup( mark );
					throw b3;
				}
            }
        }
    }
    /**
     *  Serves as the namespace declaration portion of the ANSI C++ grammar.  
     * 
     * 	namespace-definition:
     *		namespace identifier { namespace-body } | namespace { namespace-body }
     *	 namespace-body:
     *		declaration-seq?
     * @param container		IParserCallback object which serves as the owner scope for this declaration.  
     * @throws BacktrackException	request a backtrack
    
     */
    protected void namespaceDefinition(IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        IToken first = consume(IToken.t_namespace);
 
        IToken identifier = null;
        // optional name 		
        if (LT(1) == IToken.tIDENTIFIER)
            identifier = identifier();
        
        if (LT(1) == IToken.tLBRACE)
        {
            consume();
            IASTNamespaceDefinition namespaceDefinition = null;
            try
            {
                namespaceDefinition = 
                    astFactory.createNamespaceDefinition(
                        scope,
                        (identifier == null ? "" : identifier.getImage()),
                        first.getOffset(),
                        (identifier == null ? first.getOffset() : identifier.getOffset()), 
                        (identifier == null ? first.getEndOffset() : identifier.getEndOffset() ));
            }
            catch (Exception e1)
            {
                throw backtrack;
            }
            namespaceDefinition.enterScope( requestor );
            namepsaceDeclarationLoop : while (LT(1) != IToken.tRBRACE)
            {
                IToken checkToken = LA(1);
                switch (LT(1))
                {
                    case IToken.tRBRACE :
                        //consume(Token.tRBRACE);
                        break namepsaceDeclarationLoop;
                    default :
                        try
                        {
                            declaration(namespaceDefinition, null);
                        }
                        catch (BacktrackException bt)
                        {
                            failParse();
                            if (checkToken == LA(1))
                                errorHandling();
                        }
                }
                if (checkToken == LA(1))
                    errorHandling();
            }
            // consume the }
            IToken last = consume(IToken.tRBRACE);
 
            namespaceDefinition.setEndingOffset(
                last.getOffset() + last.getLength());
            namespaceDefinition.exitScope( requestor );
        }
        else if( LT(1) == IToken.tASSIGN )
        {
        	consume( IToken.tASSIGN );
        	
			if( identifier == null )
				throw backtrack;

        	ITokenDuple duple = name();
        	consume( IToken.tSEMI );
        	try
            {
                astFactory.createNamespaceAlias( 
                	scope, identifier.getImage(), duple, first.getOffset(), 
                	identifier.getOffset(), identifier.getEndOffset(), duple.getLastToken().getEndOffset() );
            }
            catch (Exception e1)
            {
                throw backtrack;
            }
        }
        else
        {
            throw backtrack;
        }
    }
    /**
     * Serves as the catch-all for all complicated declarations, including function-definitions.  
     * 
     * simpleDeclaration
     * : (declSpecifier)* (initDeclarator ("," initDeclarator)*)? 
     *     (";" | { functionBody }
     * 
     * Notes:
     * - append functionDefinition stuff to end of this rule
     * 
     * To do:
     * - work in functionTryBlock
     * 
     * @param container			IParserCallback object which serves as the owner scope for this declaration.
     * @param tryConstructor	true == take strategy1 (constructor ) : false == take strategy 2 ( pointer to function) 
     * @throws BacktrackException		request a backtrack
     */
    protected void simpleDeclaration(
        SimpleDeclarationStrategy strategy,
        IASTScope scope,
        IASTTemplate ownerTemplate)
        throws BacktrackException, EndOfFileException
    {
    	IToken firstToken = LA(1);
        DeclarationWrapper sdw =
            new DeclarationWrapper(scope, firstToken.getOffset(), ownerTemplate);

        setCompletionKeywords( Key.DECL_SPECIFIER_SEQUENCE );
        declSpecifierSeq(sdw, false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR );
        if (sdw.getTypeSpecifier() == null && sdw.getSimpleType() != IASTSimpleTypeSpecifier.Type.UNSPECIFIED )
            try
            {
                sdw.setTypeSpecifier(
                    astFactory.createSimpleTypeSpecifier(
                        scope,
                        sdw.getSimpleType(),
                        sdw.getName(),
                        sdw.isShort(),
                        sdw.isLong(),
                        sdw.isSigned(),
                        sdw.isUnsigned(), sdw.isTypeNamed(), sdw.isComplex(), sdw.isImaginary()));
            }
            catch (Exception e1)
            {
                throw backtrack;
            }
        
        Declarator declarator = null;
        if (LT(1) != IToken.tSEMI)
        {
            declarator = initDeclarator(sdw, strategy);
                
            while (LT(1) == IToken.tCOMMA)
            {
                consume();
                initDeclarator(sdw, strategy);
            }
        }

        boolean hasFunctionBody = false;
        boolean hasFunctionTryBlock = false;
        boolean consumedSemi = false;
        
        switch (LT(1))
        {
            case IToken.tSEMI :
                consume(IToken.tSEMI);
                consumedSemi = true;
                break;
            case IToken.t_try : 
            	consume( IToken.t_try );
            	if( LT(1) == IToken.tCOLON )
            		ctorInitializer( declarator );
        		hasFunctionTryBlock = true;
        		declarator.setFunctionTryBlock( true );    	
            	break;       	
            case IToken.tCOLON :
                ctorInitializer(declarator);
                break;
            case IToken.tLBRACE: 
            	break;
            default: 
            	throw backtrack;
        }
        
        if( ! consumedSemi )
		{        
	        if( LT(1) == IToken.tLBRACE )
	        {
	        	if( firstToken == LA(1) )
					throw backtrack;
	            declarator.setHasFunctionBody(true);
	            hasFunctionBody = true;
	        }
	        
	        if( hasFunctionTryBlock && ! hasFunctionBody )
	        	throw backtrack;
		}
		        
        List l = null; 
        try
        {
            l = sdw.createASTNodes(astFactory);
        }
        catch (ASTSemanticException e)
        {
			throw backtrack;
        }
        Iterator i = l.iterator();
        if (hasFunctionBody && l.size() != 1)
        {
            throw backtrack; //TODO Should be an IProblem
        }
        if (i.hasNext()) // no need to do this unless we have a declarator
        {
            if (!hasFunctionBody)
            {
                while (i.hasNext())
                {
                    IASTDeclaration declaration = (IASTDeclaration)i.next();
                    ((IASTOffsetableElement)declaration).setEndingOffset(
                        lastToken.getEndOffset());
                    declaration.acceptElement( requestor );
                }
            }
            else
            {
                IASTDeclaration declaration = (IASTDeclaration)i.next();
                declaration.enterScope( requestor );
   			
   				if ( !( declaration instanceof IASTScope ) ) 
   					throw backtrack;
   					
                handleFunctionBody((IASTScope)declaration, 
                	sdw.isInline() );
				((IASTOffsetableElement)declaration).setEndingOffset(
					lastToken.getEndOffset());
  
  				declaration.exitScope( requestor );
  				
  				if( hasFunctionTryBlock )
					catchHandlerSequence( scope );
  				
            }
        }
        else
        {
            try
            {
                astFactory
                    .createTypeSpecDeclaration(
                        sdw.getScope(),
                        sdw.getTypeSpecifier(),
                        ownerTemplate,
                        sdw.getStartingOffset(),
                        lastToken.getEndOffset())
                    .acceptElement(requestor);
            }
            catch (Exception e1)
            {
                throw backtrack;
            }
        }
        
    }
    protected abstract void handleFunctionBody(IASTScope scope, boolean isInlineFunction) throws BacktrackException, EndOfFileException;

    protected void skipOverCompoundStatement() throws BacktrackException, EndOfFileException
    {
        // speed up the parser by skiping the body
        // simply look for matching brace and return
        consume(IToken.tLBRACE);
        int depth = 1;
        while (depth > 0)
        {
            switch (consume().getType())
            {
                case IToken.tRBRACE :
                    --depth;
                    break;
                case IToken.tLBRACE :
                    ++depth;
                    break;
            }
        }
    }
    /**
     * This method parses a constructor chain 
     * ctorinitializer:	 : meminitializerlist
     * meminitializerlist: meminitializer | meminitializer , meminitializerlist
     * meminitializer: meminitializerid | ( expressionlist? ) 
     * meminitializerid:	::? nestednamespecifier?
     * 						classname
     * 						identifier
     * @param declarator	IParserCallback object that represents the declarator (constructor) that owns this initializer
     * @throws BacktrackException	request a backtrack
     */
    protected void ctorInitializer(Declarator d )
        throws EndOfFileException, BacktrackException
    {
        consume(IToken.tCOLON);

        try
        {
            for (;;)
            {
                if (LT(1) == IToken.tLBRACE)
                    break;


                ITokenDuple duple = name();

                consume(IToken.tLPAREN);
                IASTExpression expressionList = null;

                expressionList = expression(d.getDeclarationWrapper().getScope());

                consume(IToken.tRPAREN);

                try
                {
                    d.addConstructorMemberInitializer(
                        astFactory.createConstructorMemberInitializer(
                            d.getDeclarationWrapper().getScope(),
                            duple, expressionList));
                }
                catch (Exception e1)
                {
                    throw backtrack;
                }
                if (LT(1) == IToken.tLBRACE)
                    break;
                consume(IToken.tCOMMA);
            }
        }
        catch (BacktrackException bt)
        {
 
            throw backtrack;
        }

    }
    /**
     * This routine parses a parameter declaration 
     * 
     * @param containerObject	The IParserCallback object representing the parameterDeclarationClause owning the parm. 
     * @throws BacktrackException		request a backtrack
     */
    protected void parameterDeclaration(
        IParameterCollection collection, IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        IToken current = LA(1);
 
        DeclarationWrapper sdw =
            new DeclarationWrapper(scope, current.getOffset(), null);
        declSpecifierSeq(sdw, true, false);
        if (sdw.getTypeSpecifier() == null
            && sdw.getSimpleType()
                != IASTSimpleTypeSpecifier.Type.UNSPECIFIED)
            try
            {
                sdw.setTypeSpecifier(
                    astFactory.createSimpleTypeSpecifier(
                        scope,
                        sdw.getSimpleType(),
                        sdw.getName(),
                        sdw.isShort(),
                        sdw.isLong(),
                        sdw.isSigned(),
                        sdw.isUnsigned(), sdw.isTypeNamed(), sdw.isComplex(), sdw.isImaginary()));
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            }
            catch (Exception e)
            {
                throw backtrack;
            }
        
        if (LT(1) != IToken.tSEMI)
           initDeclarator(sdw, SimpleDeclarationStrategy.TRY_FUNCTION );
 
 		if( lastToken != null )
 			sdw.setEndingOffset( lastToken.getEndOffset() );
 			
        if (current == LA(1))
            throw backtrack;
        collection.addParameter(sdw);
    }
    /**
     * This class represents the state and strategy for parsing declarationSpecifierSequences
     */
    private class Flags
    {
        private boolean encounteredTypename = false;
        // have we encountered a typeName yet?
        private boolean encounteredRawType = false;
        // have we encountered a raw type yet?
        private final boolean parm;
        // is this for a simpleDeclaration or parameterDeclaration?
        private final boolean constructor;
        // are we attempting the constructor strategy?
        public Flags(boolean parm, boolean c)
        {
            this.parm = parm;
            constructor = c;
        }
        /**
         * @return	true if we have encountered a simple type up to this point, false otherwise
         */
        public boolean haveEncounteredRawType()
        {
            return encounteredRawType;
        }
        /**
         * @return  true if we have encountered a typename up to this point, false otherwise
         */
        public boolean haveEncounteredTypename()
        {
            return encounteredTypename;
        }
        /**
         * @param b - set to true if we encounter a raw type (int, short, etc.)
         */
        public void setEncounteredRawType(boolean b)
        {
            encounteredRawType = b;
        }
        /**
         * @param b - set to true if we encounter a typename
         */
        public void setEncounteredTypename(boolean b)
        {
            encounteredTypename = b;
        }
        /**
         * @return true if we are parsing for a ParameterDeclaration
         */
        public boolean isForParameterDeclaration()
        {
            return parm;
        }
        /**
         * @return whether or not we are attempting the constructor strategy or not 
         */
        public boolean isForConstructor()
        {
            return constructor;
        }
    }
    /**
     * @param flags            input flags that are used to make our decision 
     * @return                 whether or not this looks like a constructor (true or false)
     * @throws EndOfFileException       we could encounter EOF while looking ahead
     */
    private boolean lookAheadForConstructorOrConversion(Flags flags, DeclarationWrapper sdw )
        throws EndOfFileException
    {
        if (flags.isForParameterDeclaration())
            return false;
        if (LT(2) == IToken.tLPAREN && flags.isForConstructor())
            return true;
        
        IToken mark = mark(); 
        Declarator d = new Declarator( sdw );
        try
        {
            consumeTemplatedOperatorName( d );
        }
        catch (BacktrackException e)
        {
            backup( mark ); 
            return false;
        }
        
        ITokenDuple duple = d.getNameDuple(); 
       	if( duple == null )
       	{
       		backup( mark ); 
       		return false; 
       	} 
       	
       	int lastColon = duple.findLastTokenType(IToken.tCOLON);
       	if( lastColon == -1  ) 
       	{
       		int lt1 = LT(1);
       		backup( mark );
       		return flags.isForConstructor() && (lt1 == IToken.tLPAREN);
       	} 
       	
       	IToken className = null;
       	int index = lastColon - 1;
        if( duple.getToken( index ).getType() == IToken.tGT )
       	{
       		int depth = -1; 
       		while( depth == -1 )
       		{
       			if( duple.getToken( --index ).getType() == IToken.tLT )
       				++depth;
       		}
       		className = duple.getToken( index );
       	}
       	
       	boolean result = className.getImage().equals( duple.getLastToken());
       	backup( mark );
       	return result;
    }
    /**
     * @param flags			input flags that are used to make our decision 
     * @return				whether or not this looks like a a declarator follows
     * @throws EndOfFileException	we could encounter EOF while looking ahead
     */
    private boolean lookAheadForDeclarator(Flags flags) throws EndOfFileException
    {
        return flags.haveEncounteredTypename()
            && ((LT(2) != IToken.tIDENTIFIER
                || (LT(3) != IToken.tLPAREN && LT(3) != IToken.tASSIGN))
                && !LA(2).isPointer());
    }
    private void callbackSimpleDeclToken(Flags flags) throws BacktrackException, EndOfFileException
    {
        flags.setEncounteredRawType(true);
        consume(); 
    }
    /**
     * This function parses a declaration specifier sequence, as according to the ANSI C++ spec. 
     * 
     * declSpecifier
     * : "auto" | "register" | "static" | "extern" | "mutable"
     * | "inline" | "virtual" | "explicit"
     * | "char" | "wchar_t" | "bool" | "short" | "int" | "long"
     * | "signed" | "unsigned" | "float" | "double" | "void"
     * | "const" | "volatile"
     * | "friend" | "typedef"
     * | ("typename")? name
     * | {"class"|"struct"|"union"} classSpecifier
     * | {"enum"} enumSpecifier
     * 
     * Notes:
     * - folded in storageClassSpecifier, typeSpecifier, functionSpecifier
     * - folded elaboratedTypeSpecifier into classSpecifier and enumSpecifier
     * - find template names in name
     * 
     * @param decl				IParserCallback object representing the declaration that owns this specifier sequence
     * @param parm				Is this for a parameter declaration (true) or simple declaration (false)
     * @param tryConstructor	true for constructor, false for pointer to function strategy
     * @throws BacktrackException		request a backtrack
     */
    protected void declSpecifierSeq(
        DeclarationWrapper sdw,
        boolean parm,
        boolean tryConstructor )
        throws BacktrackException, EndOfFileException
    {
        Flags flags = new Flags(parm, tryConstructor);
        IToken typeNameBegin = null;
        IToken typeNameEnd = null;
        declSpecifiers : for (;;)
        {
            switch (LT(1))
            {
                case IToken.t_inline :
                	consume(); 
                    sdw.setInline(true);
                    break;
                case IToken.t_auto :
					consume(); 
                    sdw.setAuto(true);
                    break;
                case IToken.t_register :
                    sdw.setRegister(true);
					consume(); 
    	            break;
                case IToken.t_static :
                    sdw.setStatic(true);
					consume(); 
    		        break;
                case IToken.t_extern :
                    sdw.setExtern(true);
					consume(); 
                    break;
                case IToken.t_mutable :
                    sdw.setMutable(true);
					consume(); 
                    break;
                case IToken.t_virtual :
                    sdw.setVirtual(true);
					consume(); 
                    break;
                case IToken.t_explicit :
                    sdw.setExplicit(true);
					consume(); 
                    break;
                case IToken.t_typedef :
                    sdw.setTypedef(true);
					consume(); 
                    break;
                case IToken.t_friend :
                    sdw.setFriend(true);
					consume(); 
                    break;
                case IToken.t_const :
                    sdw.setConst(true);
					consume(); 
                    break;
                case IToken.t_volatile :
                    sdw.setVolatile(true);
					consume(); 
                    break;
                case IToken.t_signed :
                    sdw.setSigned(true);
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
					sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT);
                    break;
                case IToken.t_unsigned :
                    sdw.setUnsigned(true);
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
					sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT);
                    break;
                case IToken.t_short :
                    sdw.setShort(true);
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
					sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT);
                    break;
                case IToken.t_long :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
					sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT);
                    sdw.setLong(true);
                    break;
                case IToken.t__Complex :
					consume( IToken.t__Complex );
					if (typeNameBegin == null)
						typeNameBegin = LA(1);
					typeNameEnd = LA(1);
					sdw.setComplex( true );
					break;
				case IToken.t__Imaginary :
					consume( IToken.t__Imaginary );
					if (typeNameBegin == null)
						typeNameBegin = LA(1);
					typeNameEnd = LA(1);
					sdw.setImaginary( true );
					break;                
                case IToken.t_char :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.CHAR);
                    break;
                case IToken.t_wchar_t :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(
                        IASTSimpleTypeSpecifier.Type.WCHAR_T);
                    break;
                case IToken.t_bool :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.BOOL);
                    break;
                case IToken.t__Bool: 
					if (typeNameBegin == null)
						typeNameBegin = LA(1);
					typeNameEnd = LA(1);
					callbackSimpleDeclToken(flags);
					sdw.setSimpleType(IASTSimpleTypeSpecifier.Type._BOOL);
					break;                
                case IToken.t_int :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT);
                    break;					
                case IToken.t_float :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.FLOAT);
                    break;
                case IToken.t_double :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(
                        IASTSimpleTypeSpecifier.Type.DOUBLE);
                    break;
                case IToken.t_void :
                    if (typeNameBegin == null)
                        typeNameBegin = LA(1);
                    typeNameEnd = LA(1);
                    callbackSimpleDeclToken(flags);
                    sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.VOID);
                    break;
                case IToken.t_typename :
                    sdw.setTypenamed(true);
                    consume(IToken.t_typename ); 
                    IToken first = LA(1);
                    IToken last = null;
                    last = name().getLastToken();
                    if (LT(1) == IToken.t_template)
                    {
                        consume(IToken.t_template);
                        last = templateId();
                    }
                    ITokenDuple duple = new TokenDuple(first, last);
                    sdw.setTypeName(duple);
      
                    break;
                case IToken.tCOLONCOLON :
                    consume(IToken.tCOLONCOLON);
                case IToken.tIDENTIFIER :
                    // TODO - Kludgy way to handle constructors/destructors
                    if (flags.haveEncounteredRawType())
                    {
                        if (typeNameBegin != null)
                            sdw.setTypeName(
                                new TokenDuple(typeNameBegin, typeNameEnd));
                        return;
                    }
                    if (parm && flags.haveEncounteredTypename())
                    {
                        if (typeNameBegin != null)
                            sdw.setTypeName(
                                new TokenDuple(typeNameBegin, typeNameEnd));
                        return;
                    }
                    if (lookAheadForConstructorOrConversion(flags, sdw))
                    {
                        if (typeNameBegin != null)
                            sdw.setTypeName(
                                new TokenDuple(typeNameBegin, typeNameEnd));
                        return;
                    }
                    if (lookAheadForDeclarator(flags))
                    {
                        if (typeNameBegin != null)
                            sdw.setTypeName(
                                new TokenDuple(typeNameBegin, typeNameEnd));
 
                        return;
                    }
 
                    ITokenDuple d = name();
                    sdw.setTypeName(d);
                    sdw.setSimpleType( IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME ); 
                    flags.setEncounteredTypename(true);
                    break;
                case IToken.t_class :
                case IToken.t_struct :
                case IToken.t_union :
                    try
                    {
                        classSpecifier(sdw);
						flags.setEncounteredTypename(true);
                        break;
                    }
                    catch (BacktrackException bt)
                    {
                        elaboratedTypeSpecifier(sdw);
                        flags.setEncounteredTypename(true);
                        break;
                    }
                case IToken.t_enum :
                    try
                    {
                        enumSpecifier(sdw);
   					    flags.setEncounteredTypename(true);
                        break;
                    }
                    catch (BacktrackException bt)
                    {
                        // this is an elaborated class specifier
                        elaboratedTypeSpecifier(sdw);
                        flags.setEncounteredTypename(true);
                        break;
                    }
                default :
                    break declSpecifiers;
            }
        }
        if (typeNameBegin != null)
            sdw.setTypeName(new TokenDuple(typeNameBegin, typeNameEnd));
    }
    /**
     * Parse an elaborated type specifier.  
     * 
     * @param decl			Declaration which owns the elaborated type 
     * @throws BacktrackException	request a backtrack
     */
    protected void elaboratedTypeSpecifier(DeclarationWrapper sdw)
        throws BacktrackException, EndOfFileException
    {
        // this is an elaborated class specifier
        IToken t = consume();
        ASTClassKind eck = null;
        switch (t.getType())
        {
            case Token.t_class :
                eck = ASTClassKind.CLASS;
                break;
            case Token.t_struct :
                eck = ASTClassKind.STRUCT;
                break;
            case Token.t_union :
                eck = ASTClassKind.UNION;
                break;
            case Token.t_enum :
                eck = ASTClassKind.ENUM;
                break;
            default :
                break;
        }
 
        ITokenDuple d = name();
		IASTTypeSpecifier elaboratedTypeSpec = null;
		final boolean isForewardDecl = ( LT(1) == IToken.tSEMI );
		
        try
        {
            elaboratedTypeSpec =
                astFactory.createElaboratedTypeSpecifier(
                    sdw.getScope(),
                    eck,
                    d,
                    t.getOffset(),
                    d.getLastToken().getEndOffset(), 
                    isForewardDecl, sdw.isFriend() );
        }
        catch (ASTSemanticException e)
        {
			failParse();
			throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
        sdw.setTypeSpecifier(elaboratedTypeSpec);
        
        if( isForewardDecl )
        	((IASTElaboratedTypeSpecifier)elaboratedTypeSpec).acceptElement( requestor );
    }
    /**
     * Consumes template parameters.  
     *
     * @param previousLast	Previous "last" token (returned if nothing was consumed)
     * @return				Last consumed token, or <code>previousLast</code> if nothing was consumed
     * @throws BacktrackException	request a backtrack
     */
    protected IToken consumeTemplateParameters(IToken previousLast)
        throws EndOfFileException, BacktrackException
    {
        IToken last = previousLast;
        if (LT(1) == IToken.tLT)
        {
            last = consume(IToken.tLT);
            // until we get all the names sorted out
            Stack scopes = new Stack();
            scopes.push(new Integer(IToken.tLT));
            
            while (!scopes.empty())
            {
				int top;
                last = consume();
                
                switch (last.getType()) {
                    case IToken.tGT :
                        if (((Integer)scopes.peek()).intValue() == IToken.tLT) {
							scopes.pop();
						}
                        break;
					case IToken.tRBRACKET :
						do {
							top = ((Integer)scopes.pop()).intValue();
						} while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT));
						if (top != IToken.tLBRACKET) throw backtrack;
						
						break;
					case IToken.tRPAREN :
						do {
							top = ((Integer)scopes.pop()).intValue();
						} while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT));
						if (top != IToken.tLPAREN) throw backtrack;
							
						break;
                    case IToken.tLT :
					case IToken.tLBRACKET:
					case IToken.tLPAREN:
						scopes.push(new Integer(last.getType()));
                        break;
                }
            }
        }
        return last;
    }
    /**
     * Parse an identifier.  
     * 
     * @throws BacktrackException	request a backtrack
     */
    protected IToken identifier() throws EndOfFileException, BacktrackException
    {
        IToken first = consume(IToken.tIDENTIFIER); // throws backtrack if its not that
        return first;
    }
    /**
     * Parses a className.  
     * 
     * class-name: identifier | template-id
     * 
     * @throws BacktrackException
     */
    protected ITokenDuple className() throws EndOfFileException, BacktrackException
    {
		ITokenDuple duple = name();
		IToken last = duple.getLastToken(); 
        if (LT(1) == IToken.tLT) {
			last = consumeTemplateParameters(duple.getLastToken());
        }
        
		return new TokenDuple(duple.getFirstToken(), last);
    }
    
    /**
     * Parse a template-id, according to the ANSI C++ spec.  
     * 
     * template-id: template-name < template-argument-list opt >
     * template-name : identifier
     * 
     * @return		the last token that we consumed in a successful parse 
     * 
     * @throws BacktrackException	request a backtrack
     */
    protected IToken templateId() throws EndOfFileException, BacktrackException
    {
        ITokenDuple duple = name();
        IToken last = consumeTemplateParameters(duple.getLastToken());
        return last;
    }
    /**
     * Parse a name.
     * 
     * name
     * : ("::")? name2 ("::" name2)*
     * 
     * name2
     * : IDENTIFER
     * 
     * @throws BacktrackException	request a backtrack
     */
    protected TokenDuple name() throws BacktrackException, EndOfFileException
    {
        IToken first = LA(1);
        IToken last = null;
        IToken mark = mark();
 
        try
		{
	        if (LT(1) == IToken.tCOLONCOLON)
	            last = consume( IToken.tCOLONCOLON );
	        // TODO - whacky way to deal with destructors, please revisit
	        if (LT(1) == IToken.tCOMPL)
	            consume();
	        switch (LT(1))
	        {
	            case IToken.tIDENTIFIER :
	                last = consume(IToken.tIDENTIFIER);
	                IToken secondMark = null;
	                try
					{
	                	secondMark = mark();
	                }
	                catch( OffsetLimitReachedException olre )
					{
	                	return new TokenDuple(last, last);
	                }
	                try
	                {
	                	last = consumeTemplateParameters(last);
	                } catch( BacktrackException bt )
	                {
	                	backup( secondMark );
	                }
	                break;
	            default :
	                backup(mark);
	                throw backtrack;
	        }
	        while (LT(1) == IToken.tCOLONCOLON)
	        {
	            last = consume();
	            if (LT(1) == IToken.t_template)
	                consume();
	            if (LT(1) == IToken.tCOMPL)
	                consume();
	            switch (LT(1))
	            {
	                case IToken.t_operator :
	                    backup(mark);
	                    throw backtrack;
	                case IToken.tIDENTIFIER :
	                    last = consume();
	                    last = consumeTemplateParameters(last);
	            }
	        }
	
	        return new TokenDuple(first, last);
        } catch( OffsetLimitReachedException olre )
		{
        	backup(mark);
        	throw backtrack;
        }
    }
    /**
     * Parse a const-volatile qualifier.  
     * 
     * cvQualifier
     * : "const" | "volatile"
     * 
     * TODO: fix this 
     * @param ptrOp		Pointer Operator that const-volatile applies to. 		  		
     * @return			Returns the same object sent in.
     * @throws BacktrackException
     */
    protected IToken cvQualifier(
        IDeclarator declarator)
        throws EndOfFileException, BacktrackException
    {
    	IToken result = null; 
        switch (LT(1))
        {
            case IToken.t_const :
            	result = consume( IToken.t_const ); 
                declarator.addPointerOperator(ASTPointerOperator.CONST_POINTER);
                break;
            case IToken.t_volatile :
            	result = consume( IToken.t_volatile ); 
				declarator.addPointerOperator(ASTPointerOperator.VOLATILE_POINTER);
                break;
            case IToken.t_restrict : 
            	if( language == ParserLanguage.C )
            	{
            		result = consume( IToken.t_restrict );
					declarator.addPointerOperator(ASTPointerOperator.RESTRICT_POINTER);
					break;
            	}
            	else 
            		throw backtrack;
            default :
                
        }
        return result;
    }
    /**
     * Parses the initDeclarator construct of the ANSI C++ spec.
     * 
     * initDeclarator
     * : declarator ("=" initializerClause | "(" expressionList ")")?
     * @param owner			IParserCallback object that represents the owner declaration object.  
     * @return				declarator that this parsing produced.  
     * @throws BacktrackException	request a backtrack
     */
    protected Declarator initDeclarator(
        DeclarationWrapper sdw, SimpleDeclarationStrategy strategy )
        throws EndOfFileException, BacktrackException
    {
        Declarator d = declarator(sdw, sdw.getScope(), strategy );
        if( language == ParserLanguage.CPP )
        	optionalCPPInitializer(d);
        else if( language == ParserLanguage.C )
        	optionalCInitializer(d);
        sdw.addDeclarator(d);
        return d;
    }
    
    protected void optionalCPPInitializer(Declarator d)
        throws EndOfFileException, BacktrackException
    {
        // handle initializer
        if (LT(1) == IToken.tASSIGN)
        {
            consume(IToken.tASSIGN);
            d.setInitializerClause(initializerClause(d.getDeclarationWrapper().getScope()));
        }
        else if (LT(1) == IToken.tLPAREN )
        {
        	IToken mark = mark(); 
            // initializer in constructor
            try
            {
                consume(IToken.tLPAREN); // EAT IT!
                IASTExpression astExpression = null;
                astExpression = expression(d.getDeclarationWrapper().getScope());
                consume(IToken.tRPAREN);
                d.setConstructorExpression(astExpression);
            } catch( BacktrackException bt )
            {
            	backup( mark ); 
            	throw bt;
            }
        }
    }
    
    protected void optionalCInitializer( Declarator d ) throws EndOfFileException, BacktrackException
    {
    	if( LT(1) == IToken.tASSIGN )
    	{
    		consume( IToken.tASSIGN );
    		d.setInitializerClause( cInitializerClause(d.getDeclarationWrapper().getScope(), EMPTY_LIST ) );
    	}
    }
    /**
     * @param scope
     * @return
     */
    protected IASTInitializerClause cInitializerClause(
        IASTScope scope,
        List designators)
        throws EndOfFileException, BacktrackException
    {    	
        if (LT(1) == IToken.tLBRACE)
        {
            consume(IToken.tLBRACE);
            List initializerList = new ArrayList();
            for (;;)
            {
                // required at least one initializer list
                // get designator list
                List newDesignators = designatorList(scope);
                if( newDesignators.size() != 0 )
                	consume( IToken.tASSIGN );
                IASTInitializerClause initializer =
                    cInitializerClause(scope, newDesignators );
                initializerList.add(initializer);
                // can end with just a '}'
                if (LT(1) == IToken.tRBRACE)
                    break;
                // can end with ", }"
                if (LT(1) == IToken.tCOMMA)
                    consume(IToken.tCOMMA);
                if (LT(1) == IToken.tRBRACE)
                    break;
                // otherwise, its another initializer in the list
            }
            // consume the closing brace
            consume(IToken.tRBRACE);
            return astFactory.createInitializerClause(
                scope,
                (
				( designators.size() == 0 ) ? 
					IASTInitializerClause.Kind.INITIALIZER_LIST : 
					IASTInitializerClause.Kind.DESIGNATED_INITIALIZER_LIST ),
                null, initializerList, designators );
        }
        // if we get this far, it means that we have not yet succeeded
        // try this now instead
        // assignmentExpression 
        try
        {
            IASTExpression assignmentExpression = assignmentExpression(scope);
            try
            {
                return astFactory.createInitializerClause(
                    scope,
                    (
				( designators.size() == 0 ) ? 
					IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION : 
					IASTInitializerClause.Kind.DESIGNATED_ASSIGNMENT_EXPRESSION ),
                    assignmentExpression, null, designators );
            }
            catch (Exception e)
            {
                throw backtrack;
            }
        }
        catch (BacktrackException b)
        {
            // do nothing
        }
        throw backtrack;
    }
    /**
     * 
     */
    protected IASTInitializerClause initializerClause(IASTScope scope)
        throws EndOfFileException, BacktrackException
    {
        if (LT(1) == IToken.tLBRACE)
        {
            consume(IToken.tLBRACE);
            if (LT(1) == (IToken.tRBRACE))
            {
                consume(IToken.tRBRACE);
                try
                {
                    return astFactory.createInitializerClause(
                        scope,
                        IASTInitializerClause.Kind.EMPTY,
                        null, null, EMPTY_LIST );
                }
                catch (Exception e)
                {
                    throw backtrack;
                }
            }
            
            // otherwise it is a list of initializer clauses
            List initializerClauses = new ArrayList();
            for (;;)
            {
                IASTInitializerClause clause = initializerClause(scope);
                initializerClauses.add(clause);
                if (LT(1) == IToken.tRBRACE)
                    break;
                consume(IToken.tCOMMA);
            }
            consume(IToken.tRBRACE);
            try
            {
                return astFactory.createInitializerClause(
                    scope,
                    IASTInitializerClause.Kind.INITIALIZER_LIST,
                    null, initializerClauses, EMPTY_LIST );
            }
            catch (Exception e)
            {
                throw backtrack;
            }
        }
        
        // if we get this far, it means that we did not 
        // try this now instead
        // assignmentExpression 
        try
        {
            IASTExpression assignmentExpression =
                assignmentExpression(scope);
   
            try
            {
                return astFactory.createInitializerClause(
                    scope,
                    IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION,
                    assignmentExpression, null, EMPTY_LIST );
            }
            catch (Exception e)
            {
                throw backtrack;
            }
        }
        catch (BacktrackException b)
        {
			// do nothing
        }
        catch ( EndOfFileException eof )
        {

        }
        throw backtrack;
    }
    
    protected List designatorList(IASTScope scope) throws EndOfFileException, BacktrackException
    {
        List designatorList = new ArrayList();
        // designated initializers for C
        
    	if( LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET )
    	{
    
    		while( LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET )
    		{
    			IToken id = null; 
    			IASTExpression constantExpression = null;
    			IASTDesignator.DesignatorKind kind = null;
    			
    			if( LT(1) == IToken.tDOT )
    			{
    				consume( IToken.tDOT );
    				id = identifier();
    				kind = IASTDesignator.DesignatorKind.FIELD;
    			}
    			else if( LT(1) == IToken.tLBRACKET )
    			{
    				consume( IToken.tLBRACKET );
    				constantExpression = expression( scope );
    				consume( IToken.tRBRACKET );
					kind = IASTDesignator.DesignatorKind.SUBSCRIPT; 	
    			}
    			
    			IASTDesignator d = 
    				astFactory.createDesignator( kind, constantExpression, id );
    			designatorList.add( d );
    				
    		}
    	}
		return designatorList;
    }
    /**
     * Parse a declarator, as according to the ANSI C++ specification. 
     * 
     * declarator
     * : (ptrOperator)* directDeclarator
     * 
     * directDeclarator
     * : declaratorId
     * | directDeclarator "(" parameterDeclarationClause ")" (cvQualifier)*
     *     (exceptionSpecification)*
     * | directDeclarator "[" (constantExpression)? "]"
     * | "(" declarator")"
     * | directDeclarator "(" parameterDeclarationClause ")" (oldKRParameterDeclaration)*
     * 
     * declaratorId
     * : name
     * 
    	 * @param container		IParserCallback object that represents the owner declaration.  
     * @return				declarator that this parsing produced.
     * @throws BacktrackException	request a backtrack
     */
    protected Declarator declarator(
        IDeclaratorOwner owner, IASTScope scope, SimpleDeclarationStrategy strategy )
        throws EndOfFileException, BacktrackException
    {
        Declarator d = null;
        DeclarationWrapper sdw = owner.getDeclarationWrapper();
        overallLoop : do
        {
            d = new Declarator(owner);
 
            consumePointerOperators(d);
 
            if (LT(1) == IToken.tLPAREN)
            {
                consume();
                declarator(d, scope, strategy );
                consume(IToken.tRPAREN);
            }
            else
	            consumeTemplatedOperatorName(d);
            
            for (;;)
            {
                switch (LT(1))
                {
                    case IToken.tLPAREN :
                    	
                        // temporary fix for initializer/function declaration ambiguity
                        if (!LA(2).looksLikeExpression() && strategy != SimpleDeclarationStrategy.TRY_VARIABLE  )
                        {
							boolean failed = false;
                        	if( LT(2) == IToken.tIDENTIFIER )
                        	{
								IToken newMark = mark();
								consume( IToken.tLPAREN );

	                        	try
	                        	{
	                        		try
                                    {
                                        if( ! astFactory.queryIsTypeName( scope, name() ) )
                                        	failed = true;
                                    }
                                    catch (Exception e)
                                    {
                                        throw backtrack;
                                    }
	                        	} catch( BacktrackException b )
	                        	{ 
	                        		failed = true; 
	                        	}
	                        	
								backup( newMark );
                        	}
							if( !failed )
							{  									
	                            // parameterDeclarationClause
	                            d.setIsFunction(true);
								// TODO need to create a temporary scope object here 
	                            consume(IToken.tLPAREN);
	                            boolean seenParameter = false;
	                            parameterDeclarationLoop : for (;;)
	                            {
	                                switch (LT(1))
	                                {
	                                    case IToken.tRPAREN :
	                                        consume();
	                                        break parameterDeclarationLoop;
	                                    case IToken.tELLIPSIS :
	                                        consume();
	                                        d.setIsVarArgs( true );
	                                        break;
	                                    case IToken.tCOMMA :
	                                        consume();
	                                        seenParameter = false;
	                                        break;
	                                    default :
	                                        if (seenParameter)
	                                            throw backtrack;
	                                        parameterDeclaration(d, scope);
	                                        seenParameter = true;
	                                }
	                            }
							}

                            if (LT(1) == IToken.tCOLON || LT(1) == IToken.t_try )
                                break overallLoop;
                            
                            IToken beforeCVModifier = mark();
                            IToken cvModifier = null;
                            IToken afterCVModifier = beforeCVModifier;
                            // const-volatile
                            // 2 options: either this is a marker for the method,
                            // or it might be the beginning of old K&R style parameter declaration, see
                            //      void getenv(name) const char * name; {}
                            // This will be determined further below
                            if (LT(1) == IToken.t_const
                                || LT(1) == IToken.t_volatile)
                            {
                                cvModifier = consume();
                                afterCVModifier = mark();
                            }
                            //check for throws clause here 
                            List exceptionSpecIds = null;
                            if (LT(1) == IToken.t_throw)
                            {
                                exceptionSpecIds = new ArrayList();
                                consume(); // throw
                                consume(IToken.tLPAREN); // (
                                boolean done = false;
                                IASTTypeId duple = null;
                                while (!done)
                                {
                                    switch (LT(1))
                                    {
                                        case IToken.tRPAREN :
                                            consume();
                                            done = true;
                                            break;
                                        case IToken.tCOMMA :
                                            consume();
                                            break;
                                        default :
                                            String image = LA(1).getImage();
                                            try
                                            {
                                                duple = typeId(scope, false);
                                                exceptionSpecIds.add(duple);
                                            }
                                            catch (BacktrackException e)
                                            {
                                                failParse();
                                                log.traceLog(
                                                    "Unexpected Token ="
                                                        + image );
                                                consume();
                                                // eat this token anyway
                                                continue;
                                            }
                                            break;
                                    }
                                }
                                if (exceptionSpecIds != null)
                                    try
                                    {
                                        d.setExceptionSpecification(
                                            astFactory
                                                .createExceptionSpecification(
                                                d.getDeclarationWrapper().getScope(), exceptionSpecIds));
                                    }
                                    catch (ASTSemanticException e)
                                    {
                                        failParse();
                                        throw backtrack;
                                    } catch (Exception e)
                                    {
                                        throw backtrack;
                                    }
                            }
                            // check for optional pure virtual							
                            if (LT(1) == IToken.tASSIGN
                                && LT(2) == IToken.tINTEGER
                                && LA(2).getImage().equals("0"))
                            {
                                consume(IToken.tASSIGN);
                                consume(IToken.tINTEGER);
                                d.setPureVirtual(true);
                            }
                            if (afterCVModifier != LA(1)
                                || LT(1) == IToken.tSEMI)
                            {
                                // There were C++-specific clauses after const/volatile modifier
                                // Then it is a marker for the method
                                if (cvModifier != null)
                                {
               
                                    if (cvModifier.getType() == IToken.t_const)
                                        d.setConst(true);
                                    if (cvModifier.getType()
                                        == IToken.t_volatile)
                                        d.setVolatile(true);
                                }
                                afterCVModifier = mark();
                                // In this case (method) we can't expect K&R parameter declarations,
                                // but we'll check anyway, for errorhandling
                            }
                        }
                        break;
                    case IToken.tLBRACKET :
                        consumeArrayModifiers(d, sdw.getScope());
                        continue;
                    case IToken.tCOLON :
                        consume(IToken.tCOLON);
                        IASTExpression exp = null;
                        exp = constantExpression(scope);
                        d.setBitFieldExpression(exp);
                    default :
                        break;
                }
                break;
            }
            if (LA(1).getType() != IToken.tIDENTIFIER)
                break;

        }
        while (true);
        if (d.getOwner() instanceof IDeclarator)
             ((Declarator)d.getOwner()).setOwnedDeclarator(d);
        return d;
    }
    protected void consumeTemplatedOperatorName(Declarator d)
        throws EndOfFileException, BacktrackException
    {
        if (LT(1) == IToken.t_operator)
            operatorId(d, null);
        else
        {
            try
            {
                ITokenDuple duple = name();
                d.setName(duple);
        
            }
            catch (BacktrackException bt)
            {
                Declarator d1 = d;
                Declarator d11 = d1;
                IToken start = null;
                IToken mark = mark();
                if (LT(1) == IToken.tCOLONCOLON
                    || LT(1) == IToken.tIDENTIFIER)
                {
                    start = consume();
                    IToken end = null;
                    if (start.getType() == IToken.tIDENTIFIER)
                        end = consumeTemplateParameters(end);
                        while (LT(1) == IToken.tCOLONCOLON
                            || LT(1) == IToken.tIDENTIFIER)
                        {
                            end = consume();
                            if (end.getType() == IToken.tIDENTIFIER)
                                end = consumeTemplateParameters(end);
                        }
                    if (LT(1) == IToken.t_operator)
                        operatorId(d11, start);
                    else
                    {
                        backup(mark);
                        throw backtrack;
                    }
                }
            }
        }
    }
    protected void consumeArrayModifiers( IDeclarator d, IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
        while (LT(1) == IToken.tLBRACKET)
        {
            consume( IToken.tLBRACKET ); // eat the '['
        
            IASTExpression exp = null;
            if (LT(1) != IToken.tRBRACKET)
            {
                exp = constantExpression(scope);
            }
            consume(IToken.tRBRACKET);
            IASTArrayModifier arrayMod;
            try
            {
                arrayMod = astFactory.createArrayModifier(exp);
            }
            catch (Exception e)
            {
                throw backtrack;
            }
            d.addArrayModifier(arrayMod);
        }
    }
    
    protected void operatorId(
        Declarator d,
        IToken originalToken)
        throws BacktrackException, EndOfFileException
    {
        // we know this is an operator
        IToken operatorToken = consume(IToken.t_operator);
        IToken toSend = null;
        if (LA(1).isOperator()
            || LT(1) == IToken.tLPAREN
            || LT(1) == IToken.tLBRACKET)
        {
            if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
                && LT(2) == IToken.tLBRACKET
                && LT(3) == IToken.tRBRACKET)
            {
                consume();
                consume(IToken.tLBRACKET);
                toSend = consume(IToken.tRBRACKET);
                // vector new and delete operators
            }
            else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN)
            {
                // operator ()
                consume(IToken.tLPAREN);
                toSend = consume(IToken.tRPAREN);
            }
            else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET)
            {
                consume(IToken.tLBRACKET);
                toSend = consume(IToken.tRBRACKET);
            }
            else if (LA(1).isOperator())
                toSend = consume();
            else
                throw backtrack;
        }
        else
        {
            // must be a conversion function
            typeId(d.getDeclarationWrapper().getScope(), true );
            toSend = lastToken;
        }
        ITokenDuple duple =
            new TokenDuple(
                originalToken == null ? operatorToken : originalToken,
                toSend);
   
        d.setName(duple);
    }
    /**
     * Parse a Pointer Operator.   
     * 
     * ptrOperator
     * : "*" (cvQualifier)*
     * | "&"
     * | ::? nestedNameSpecifier "*" (cvQualifier)*
     * 
     * @param owner 		Declarator that this pointer operator corresponds to.  
     * @throws BacktrackException 	request a backtrack
     */
    protected IToken consumePointerOperators(IDeclarator d) throws EndOfFileException, BacktrackException
    {
    	IToken result = null;
    	for( ; ; )
    	{
	        if (LT(1) == IToken.tAMPER)
	        {
	        	result = consume( IToken.tAMPER ); 
	            d.addPointerOperator(ASTPointerOperator.REFERENCE);
	            return result;
	            
	        }
	        IToken mark = mark();

	        ITokenDuple nameDuple = null;
	        if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON)
	        {
	        	try
	        	{
		            nameDuple = name();
	        	}
	        	catch( BacktrackException bt )
	        	{
	        		backup( mark ); 
	        		return null;
	        	}
	        }
	        if ( LT(1) == IToken.tSTAR)
	        {
	            result = consume(Token.tSTAR); // tokenType = "*"
	
				d.setPointerOperatorName(nameDuple);
	
				IToken successful = null;
	            for (;;)
	            {
                    IToken newSuccess = cvQualifier(d);
                    if( newSuccess != null ) successful = newSuccess; 
                    else break;
                    
	            }
	            
				if( successful == null )
				{
					d.addPointerOperator( ASTPointerOperator.POINTER );
				}
				continue;	            
	        }
	        backup(mark);
	        return result;
    	}
    }
    /**
     * Parse an enumeration specifier, as according to the ANSI specs in C & C++.  
     * 
     * enumSpecifier:
     * 		"enum" (name)? "{" (enumerator-list) "}"
     * enumerator-list:
     * 	enumerator-definition
     *	enumerator-list , enumerator-definition
     * enumerator-definition:
     * 	enumerator
     *  enumerator = constant-expression
     * enumerator: identifier 
     * 
     * @param	owner		IParserCallback object that represents the declaration that owns this type specifier. 
     * @throws	BacktrackException	request a backtrack
     */
    protected void enumSpecifier(DeclarationWrapper sdw)
        throws BacktrackException, EndOfFileException
    {
        IToken mark = mark();
        IToken identifier = null;
        consume( IToken.t_enum );
        if (LT(1) == IToken.tIDENTIFIER)
        {
            identifier = identifier();
        }
        if (LT(1) == IToken.tLBRACE)
        {
            IASTEnumerationSpecifier enumeration = null;
            try
            {
                enumeration = astFactory.createEnumerationSpecifier(
                        sdw.getScope(),
                        ((identifier == null) ? "" : identifier.getImage()),
                        mark.getOffset(), 
                        ((identifier == null)
                            ? mark.getOffset()
                            : identifier.getOffset()), 
                         ((identifier == null)? mark.getEndOffset()
				: identifier.getEndOffset()));
            }
            catch (ASTSemanticException e)
            {
				failParse();
				throw backtrack;               
            } catch (Exception e)
            {
                throw backtrack;
            }
            consume(IToken.tLBRACE);
            while (LT(1) != IToken.tRBRACE)
            {
                IToken enumeratorIdentifier = null;
                if (LT(1) == IToken.tIDENTIFIER)
                {
                    enumeratorIdentifier = identifier();
                }
                else
                {
                    throw backtrack;
                }
                IASTExpression initialValue = null;
                if (LT(1) == IToken.tASSIGN)
                {
                    consume(IToken.tASSIGN);
                    initialValue = constantExpression(sdw.getScope());
                }
  
                if (LT(1) == IToken.tRBRACE)
                {
                    try
                    {
                        astFactory.addEnumerator(
                            enumeration,
                            enumeratorIdentifier.getImage(),
                            enumeratorIdentifier.getOffset(),
							enumeratorIdentifier.getOffset(),
                            enumeratorIdentifier.getEndOffset(), enumeratorIdentifier.getEndOffset(), initialValue);
                    }
                    catch (ASTSemanticException e1)
                    {
						failParse();
						throw backtrack;                   
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                }
                if (LT(1) != IToken.tCOMMA)
                {
                    throw backtrack;
                }
                try
                {
                    astFactory.addEnumerator(
                        enumeration,
                        enumeratorIdentifier.getImage(),
                        enumeratorIdentifier.getOffset(),
						enumeratorIdentifier.getOffset(),
						enumeratorIdentifier.getEndOffset(), enumeratorIdentifier.getEndOffset(), initialValue);
                }
                catch (ASTSemanticException e1)
                {
					failParse();
					throw backtrack; 
                } catch (Exception e)
                {
                    throw backtrack;
                }
                consume(IToken.tCOMMA);
            }
            IToken t = consume(IToken.tRBRACE);
            enumeration.setEndingOffset(t.getEndOffset());
            enumeration.acceptElement( requestor );
            sdw.setTypeSpecifier(enumeration);
        }
        else
        {
            // enumSpecifierAbort
            backup(mark);
            throw backtrack;
        }
    }
    /**
     * Parse a class/struct/union definition. 
     * 
     * classSpecifier
     * : classKey name (baseClause)? "{" (memberSpecification)* "}"
     * 
     * @param	owner		IParserCallback object that represents the declaration that owns this classSpecifier
     * @throws	BacktrackException	request a backtrack
     */
    protected void classSpecifier(DeclarationWrapper sdw)
        throws BacktrackException, EndOfFileException
    {
        ClassNameType nameType = ClassNameType.IDENTIFIER;
        ASTClassKind classKind = null;
        ASTAccessVisibility access = ASTAccessVisibility.PUBLIC;
        IToken classKey = null;
        IToken mark = mark();
        
		// class key
        switch (LT(1))
        {
            case IToken.t_class :
                classKey = consume();
                classKind = ASTClassKind.CLASS;
                access = ASTAccessVisibility.PRIVATE;
                break;
            case IToken.t_struct :
                classKey = consume();
                classKind = ASTClassKind.STRUCT;
                break;
            case IToken.t_union :
                classKey = consume();
                classKind = ASTClassKind.UNION;
                break;
            default :
                throw backtrack;
        }

        
        ITokenDuple duple = null;
        
        setCompletionKind( CompletionKind.USER_SPECIFIED_NAME );
        setCompletionKeywords( Key.EMPTY );
        // class name
        if (LT(1) == IToken.tIDENTIFIER)
            duple = className();
        if (duple != null && !duple.isIdentifier())
            nameType = ClassNameType.TEMPLATE;
        if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE)
        {
            backup(mark);
            throw backtrack;
        }
        IASTClassSpecifier astClassSpecifier = null;
        
        try
        {
            astClassSpecifier = 
                astFactory
                    .createClassSpecifier(
                        sdw.getScope(),
                        duple, 
                        classKind,
                        nameType,
                        access,
                        classKey.getOffset(),
            			duple == null ?  classKey.getOffset() : duple.getFirstToken().getOffset(), 
						duple == null ?  classKey.getEndOffset() : duple.getFirstToken().getEndOffset() );
        }
        catch (ASTSemanticException e)
        {
			failParse();
			throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
        sdw.setTypeSpecifier(astClassSpecifier);
        // base clause
        if (LT(1) == IToken.tCOLON)
        {
            baseSpecifier(astClassSpecifier);
        }
        if (LT(1) == IToken.tLBRACE)
        {
            consume(IToken.tLBRACE);
            astClassSpecifier.enterScope( requestor );
            memberDeclarationLoop : while (LT(1) != IToken.tRBRACE)
            {
                IToken checkToken = LA(1);
                switch (LT(1))
                {
                    case IToken.t_public :
						consume(); 
						consume(IToken.tCOLON);
						astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PUBLIC );
						break;                    
                    case IToken.t_protected :
						consume(); 
						consume(IToken.tCOLON);
					astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PROTECTED);
						break;

                    case IToken.t_private :
                    	consume(); 
                        consume(IToken.tCOLON);
						astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PRIVATE);
                        break;
                    case IToken.tRBRACE :
                        consume(IToken.tRBRACE);
                        break memberDeclarationLoop;
                    default :
                        try
                        {
                            declaration(astClassSpecifier, null);
                        }
                        catch (BacktrackException bt)
                        {
                            failParse();
                            if (checkToken == LA(1))
                                errorHandling();
                        }
                }
                if (checkToken == LA(1))
                    errorHandling();
            }
            // consume the }
            IToken lt = consume(IToken.tRBRACE);
            astClassSpecifier.setEndingOffset(lt.getEndOffset());
            
            try
            {
                astFactory.signalEndOfClassSpecifier( astClassSpecifier );
            }
            catch (Exception e1)
            {
                throw backtrack;
            }
            
            astClassSpecifier.exitScope( requestor );
            
        }
    }
    /**
     * Parse the subclass-baseclauses for a class specification.  
     * 
     * baseclause:	: basespecifierlist
     * basespecifierlist: 	basespecifier
     * 						basespecifierlist, basespecifier
     * basespecifier:	::? nestednamespecifier? classname
     * 					virtual accessspecifier? ::? nestednamespecifier? classname
     * 					accessspecifier virtual? ::? nestednamespecifier? classname
     * accessspecifier:	private | protected | public
     * @param classSpecOwner
     * @throws BacktrackException
     */
    protected void baseSpecifier(
        IASTClassSpecifier astClassSpec)
        throws EndOfFileException, BacktrackException
    {
        consume(IToken.tCOLON);
        boolean isVirtual = false;
        ASTAccessVisibility visibility = ASTAccessVisibility.PUBLIC;
        ITokenDuple nameDuple = null;
        baseSpecifierLoop : for (;;)
        {
            switch (LT(1))
            {
                case IToken.t_virtual :
                    consume(IToken.t_virtual);
                    isVirtual = true;
                    break;
                case IToken.t_public :
                	consume(); 
                    break;
                case IToken.t_protected :
					consume();
				    visibility = ASTAccessVisibility.PROTECTED;
                    break;
                case IToken.t_private :
                    visibility = ASTAccessVisibility.PRIVATE;
					consume();
           			break;
                case IToken.tCOLONCOLON :
                case IToken.tIDENTIFIER :
                    nameDuple = name();
                    break;
                case IToken.tCOMMA :
                    try
                    {
                        astFactory.addBaseSpecifier(
                            astClassSpec,
                            isVirtual,
                            visibility,
                            nameDuple );
                    }
                    catch (ASTSemanticException e)
                    {
						failParse();
						throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    isVirtual = false;
                    visibility = ASTAccessVisibility.PUBLIC;
                    nameDuple = null;                        
                    consume();
                    continue baseSpecifierLoop;
                default :
                    break baseSpecifierLoop;
            }
        }

        try
        {
            astFactory.addBaseSpecifier(
                astClassSpec,
                isVirtual,
                visibility,
                nameDuple );
        }
        catch (ASTSemanticException e)
        {
			failParse();
			throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * Parses a function body. 
     * 
     * @throws BacktrackException	request a backtrack
     */
    protected void functionBody( IASTScope scope ) throws EndOfFileException, BacktrackException
    {
        compoundStatement( scope, false );
    }
    /**
     * Parses a statement. 
     * 
     * @throws BacktrackException	request a backtrack
     */
    protected void statement(IASTScope scope) throws EndOfFileException, BacktrackException
    {
    	setCurrentScope(scope);
    	
    	setCompletionKind( CompletionKind.STATEMENT_START );
    	setCompletionKeywords( Key.STATEMENT );
    	
        switch (LT(1))
        {
            case IToken.t_case :
                consume(IToken.t_case);
                IASTExpression constant_expression = constantExpression(scope);
				constant_expression.acceptElement(requestor);
                consume(IToken.tCOLON);
                statement(scope);
                return;
            case IToken.t_default :
                consume(IToken.t_default);
                consume(IToken.tCOLON);
                statement(scope);
                return;
            case IToken.tLBRACE :
                compoundStatement(scope, true);
                return;
            case IToken.t_if :
                consume( IToken.t_if );
                consume(IToken.tLPAREN);
                condition( scope );
                consume(IToken.tRPAREN);
                if( LT(1) != IToken.tLBRACE )
                    singleStatementScope(scope);
                else
                	statement( scope );
                if (LT(1) == IToken.t_else)
                {
                    consume( IToken.t_else );
                    if( LT(1) != IToken.tLBRACE )
						singleStatementScope(scope);
                    else
                    	statement( scope );
                }
                return;
            case IToken.t_switch :
                consume();
                consume(IToken.tLPAREN);
                condition(scope);
                consume(IToken.tRPAREN);
                statement(scope);
                return;
            case IToken.t_while :
                consume(IToken.t_while);
                consume(IToken.tLPAREN);
                condition(scope);
                consume(IToken.tRPAREN);
                if( LT(1) != IToken.tLBRACE )
					singleStatementScope(scope);
                else
                	statement(scope);
                return;
            case IToken.t_do :
                consume(IToken.t_do);
				if( LT(1) != IToken.tLBRACE )
					singleStatementScope(scope);
				else
					statement(scope);
                consume(IToken.t_while);
                consume(IToken.tLPAREN);
                condition(scope);
                consume(IToken.tRPAREN);
                return;
            case IToken.t_for :
                consume();
                consume(IToken.tLPAREN);
                forInitStatement(scope);
                if (LT(1) != IToken.tSEMI)
                    condition(scope);
                consume(IToken.tSEMI);
                if (LT(1) != IToken.tRPAREN)
                {  
                    IASTExpression finalExpression = expression(scope);
                    finalExpression.acceptElement(requestor);
                }
                consume(IToken.tRPAREN);
                statement(scope);
                return;
            case IToken.t_break :
                consume();
                consume(IToken.tSEMI);
                return;
            case IToken.t_continue :
                consume();
                consume(IToken.tSEMI);
                return;
            case IToken.t_return :
                consume();
                if (LT(1) != IToken.tSEMI)
                {
                    IASTExpression retVal = expression(scope);
                    retVal.acceptElement(requestor);
                }
                consume(IToken.tSEMI);
                return;
            case IToken.t_goto :
                consume();
                consume(IToken.tIDENTIFIER);
                consume(IToken.tSEMI);
                return;
            case IToken.t_try :
                consume();
                compoundStatement(scope,true);
                catchHandlerSequence(scope);
                return;
            case IToken.tSEMI :
                consume();
                return;
            default :
                // can be many things:
                // label
            	
            	try
				{
	                if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON)
	                {
	                    consume(IToken.tIDENTIFIER);
	                    consume(IToken.tCOLON);
	                    statement(scope);
	                    return;
	                }
            	}catch( OffsetLimitReachedException olre )
				{
            		// ok
            	}
                // expressionStatement
                // Note: the function style cast ambiguity is handled in expression
                // Since it only happens when we are in a statement
                IToken mark = mark();
                try
                {
                    IASTExpression thisExpression = expression(scope);
                    if( queryLookaheadCapability() )
                    	consume(IToken.tSEMI);
                    else
                    	throw new EndOfFileException();
                    thisExpression.acceptElement( requestor );
                    return;
                }
                catch (BacktrackException b)
                {
                	backup( mark );
                }
                catch( OffsetLimitReachedException olre )
				{
                	backup(mark);
                }

                // declarationStatement
                declaration(scope, null);
        }        

    }
    protected void catchHandlerSequence(IASTScope scope)
        throws EndOfFileException, BacktrackException
    {
    	if( LT(1) != IToken.t_catch )
    		throw backtrack; // error, need at least one of these
        while (LT(1) == IToken.t_catch)
        {
            consume(IToken.t_catch);
            consume(IToken.tLPAREN);
            if( LT(1) == IToken.tELLIPSIS )
            	consume( IToken.tELLIPSIS );
            else 
            	declaration(scope, null); // was exceptionDeclaration
            consume(IToken.tRPAREN);
            
            catchBlockCompoundStatement(scope);
        }
    }
    
    protected abstract void catchBlockCompoundStatement(IASTScope scope) throws BacktrackException, EndOfFileException; 
    
	protected void singleStatementScope(IASTScope scope) throws EndOfFileException, BacktrackException
    {
        IASTCodeScope newScope;
        try
        {
            newScope = astFactory.createNewCodeBlock(scope);
        }
        catch (Exception e)
        {
            throw backtrack;
        }
        newScope.enterScope( requestor );
        try
        {
			statement( newScope );
        }
        finally
        {
			newScope.exitScope( requestor );
        }
    }

    /**
     * @throws BacktrackException
     */
    protected void condition( IASTScope scope ) throws BacktrackException, EndOfFileException
    {
        IASTExpression someExpression = expression( scope );
        someExpression.acceptElement(requestor);
        //TODO type-specifier-seq declarator = assignment expression 
    }
    
    /**
     * @throws BacktrackException
     */
    protected void forInitStatement( IASTScope scope ) throws BacktrackException, EndOfFileException
    {
    	try
    	{
        	simpleDeclarationStrategyUnion(scope,null);
    	}
    	catch( BacktrackException bt )
    	{
    		try
    		{
    			IASTExpression e = expression( scope );
    			e.acceptElement(requestor);
    		}
    		catch( BacktrackException b )
    		{
    			failParse(); 
    			throw b;
    		}
    	}
        
    }
    /**
     * @throws BacktrackException
     */
    protected void compoundStatement( IASTScope scope, boolean createNewScope ) throws EndOfFileException, BacktrackException
    {
        consume(IToken.tLBRACE);
        
		IASTCodeScope newScope = null;
        if( createNewScope )
        {
        	try
            {
                newScope = astFactory.createNewCodeBlock(scope);
            }
            catch (Exception e)
            {
                throw backtrack;
            }        
        	newScope.enterScope( requestor );
        }
        IToken checkToken = null;
        setCurrentScope(createNewScope ? newScope : scope);
        setCompletionKind( CompletionKind.STATEMENT_START );
        while (queryLookaheadCapability() && LT(1) != IToken.tRBRACE)
        {
        	checkToken = LA(1);
        	setCurrentScope(createNewScope ? newScope : scope);
        	try
        	{
            	statement(createNewScope ? newScope : scope );
        	}
        	catch( BacktrackException b )
        	{
        		failParse(); 
        		if( LA(1) == checkToken )
        			errorHandling();
        	}
        	setCurrentScope(createNewScope ? newScope : scope);
        	
        	setCompletionKind( CompletionKind.STATEMENT_START );
        	setCompletionKeywords( Key.STATEMENT );
        }
            
        if( queryLookaheadCapability() ) consume(IToken.tRBRACE);
        else throw new EndOfFileException();
        if( createNewScope )
        	newScope.exitScope( requestor );
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression constantExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        return conditionalExpression(scope);
    }
    /* (non-Javadoc)
     * @see org.eclipse.cdt.internal.core.parser.IParser#expression(java.lang.Object)
     */
    public IASTExpression expression(IASTScope scope) throws BacktrackException, EndOfFileException
    {
        IASTExpression assignmentExpression = assignmentExpression(scope);
        if( !queryLookaheadCapability() ) return assignmentExpression;
        while (LT(1) == IToken.tCOMMA)
        {
            consume();
            IASTExpression secondExpression = assignmentExpression(scope);
            try
            {
                assignmentExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.EXPRESSIONLIST,
                        assignmentExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return assignmentExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
	protected IASTExpression assignmentExpression(IASTScope scope)
		throws EndOfFileException, BacktrackException {
		if (LT(1) == IToken.t_throw) {
			return throwExpression(scope);
		}
		IASTExpression conditionalExpression = conditionalExpression(scope);
		// if the condition not taken, try assignment operators
		if (conditionalExpression != null
			&& conditionalExpression.getExpressionKind()
				== IASTExpression.Kind.CONDITIONALEXPRESSION)
			return conditionalExpression;
		if( !queryLookaheadCapability() ) return conditionalExpression;
		switch (LT(1)) {
			case IToken.tASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL,
					conditionalExpression);
			case IToken.tSTARASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT,
					conditionalExpression);
			case IToken.tDIVASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV,
					conditionalExpression);
			case IToken.tMODASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD,
					conditionalExpression);
			case IToken.tPLUSASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS,
					conditionalExpression);
			case IToken.tMINUSASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS,
					conditionalExpression);
			case IToken.tSHIFTRASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT,
					conditionalExpression);
			case IToken.tSHIFTLASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT,
					conditionalExpression);
			case IToken.tAMPERASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND,
					conditionalExpression);
			case IToken.tXORASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR,
					conditionalExpression);
			case IToken.tBITORASSIGN :
				return assignmentOperatorExpression(
					scope,
					IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR,
					conditionalExpression);
		}
		return conditionalExpression;
	}
    protected IASTExpression assignmentOperatorExpression(
    	IASTScope scope,
        IASTExpression.Kind kind, IASTExpression lhs )
        throws EndOfFileException, BacktrackException
    {
        consume();
        IASTExpression assignmentExpression = assignmentExpression(scope);
 
        try
        {
            return astFactory.createExpression(
                scope,
                kind,
                lhs,
				assignmentExpression,
                null,
                null,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression throwExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
        consume(IToken.t_throw);
        IASTExpression throwExpression = null;
        try
        {
            throwExpression = expression(scope);
        }
        catch (BacktrackException b)
        {
        }
        try
        {
            return astFactory.createExpression(
                scope,
                IASTExpression.Kind.THROWEXPRESSION,
                throwExpression,
                null,
                null,
                null,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * @param expression
     * @return
     * @throws BacktrackException
     */
    protected IASTExpression conditionalExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = logicalOrExpression(scope);
        if( !queryLookaheadCapability() ) return firstExpression;
        if (LT(1) == IToken.tQUESTION)
        {
            consume();
            IASTExpression secondExpression = expression(scope);
            consume(IToken.tCOLON);
            IASTExpression thirdExpression = assignmentExpression(scope);
            try
            {
                return astFactory.createExpression(
                    scope,
                    IASTExpression.Kind.CONDITIONALEXPRESSION,
                    firstExpression,
                    secondExpression,
                    thirdExpression,
                    null,
                    null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        else
            return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression logicalOrExpression(IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = logicalAndExpression(scope);
        if( !queryLookaheadCapability() ) return firstExpression;
        while (LT(1) == IToken.tOR)
        {
            consume();
            IASTExpression secondExpression = logicalAndExpression(scope);

            try
            {
                firstExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.LOGICALOREXPRESSION,
                        firstExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression logicalAndExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = inclusiveOrExpression( scope );
        if( !queryLookaheadCapability() ) return firstExpression;
        while (LT(1) == IToken.tAND)
        {
            consume();
            IASTExpression secondExpression = inclusiveOrExpression( scope );
            try
            {
                firstExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.LOGICALANDEXPRESSION,
                        firstExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression inclusiveOrExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = exclusiveOrExpression(scope);
        if( !queryLookaheadCapability() ) return firstExpression;
        while (LT(1) == IToken.tBITOR)
        {
            consume();
            IASTExpression secondExpression = exclusiveOrExpression(scope);
  
            try
            {
                firstExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.INCLUSIVEOREXPRESSION,
                        firstExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression exclusiveOrExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = andExpression( scope );
        if( !queryLookaheadCapability() ) return firstExpression;
        while (LT(1) == IToken.tXOR)
        {
            consume();
            
            IASTExpression secondExpression = andExpression( scope );

            try
            {
                firstExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.EXCLUSIVEOREXPRESSION,
                        firstExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression andExpression(IASTScope scope) throws EndOfFileException, BacktrackException
    {
        IASTExpression firstExpression = equalityExpression(scope);
        if( !queryLookaheadCapability() ) return firstExpression;
        while (LT(1) == IToken.tAMPER)
        {
            consume();
            IASTExpression secondExpression = equalityExpression(scope);
 
            try
            {
                firstExpression =
                    astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.ANDEXPRESSION,
                        firstExpression,
                        secondExpression,
                        null,
                        null,
                        null, "", null);
            }
            catch (ASTSemanticException e)
            {
                throw backtrack;
            } catch (Exception e)
            {
                throw backtrack;
            }
        }
        return firstExpression;
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression equalityExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
        IASTExpression firstExpression = relationalExpression(scope);
        for (;;)
        {
        	if( !queryLookaheadCapability() ) return firstExpression;
            switch (LT(1))
            {
                case IToken.tEQUAL :
                case IToken.tNOTEQUAL :
                    IToken t = consume();
                    IASTExpression secondExpression =
                        relationalExpression(scope);

                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                (t.getType() == IToken.tEQUAL)
                                    ? IASTExpression.Kind.EQUALITY_EQUALS
                                    : IASTExpression.Kind.EQUALITY_NOTEQUALS,
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression relationalExpression(IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = shiftExpression(scope);
        for (;;)
        {
        	if( !queryLookaheadCapability() ) return firstExpression;
            switch (LT(1))
            {
                case IToken.tGT :
                case IToken.tLT :
                case IToken.tLTEQUAL :
                case IToken.tGTEQUAL :
                    IToken mark = mark();
                    IToken t = consume();
                    IToken next = LA(1);
                    IASTExpression secondExpression =
                        shiftExpression(scope);
                    if (next == LA(1))
                    {
                        // we did not consume anything
                        // this is most likely an error
                        backup(mark);
                        return firstExpression;
                    }
                    else
                    {
                        IASTExpression.Kind kind = null;
                        switch (t.getType())
                        {
                            case IToken.tGT :
                                kind =
                                    IASTExpression.Kind.RELATIONAL_GREATERTHAN;
                                break;
                            case IToken.tLT :
                                kind = IASTExpression.Kind.RELATIONAL_LESSTHAN;
                                break;
                            case IToken.tLTEQUAL :
                                kind =
                                    IASTExpression
                                        .Kind
                                        .RELATIONAL_LESSTHANEQUALTO;
                                break;
                            case IToken.tGTEQUAL :
                                kind =
                                    IASTExpression
                                        .Kind
                                        .RELATIONAL_GREATERTHANEQUALTO;
                                break;
                        }
                        try
                        {
                            firstExpression =
                                astFactory.createExpression(
                                    scope,
                                    kind,
                                    firstExpression,
                                    secondExpression,
                                    null,
                                    null,
                                    null, "", null);
                        }
                        catch (ASTSemanticException e)
                        {
                            throw backtrack;
                        } catch (Exception e)
                        {
                            throw backtrack;
                        }
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression shiftExpression(IASTScope scope)
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = additiveExpression(scope);
        for (;;)
        {
        	if( !queryLookaheadCapability() ) return firstExpression;
            switch (LT(1))
            {
                case IToken.tSHIFTL :
                case IToken.tSHIFTR :
                    IToken t = consume();
                    IASTExpression secondExpression =
                        additiveExpression(scope);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                ((t.getType() == IToken.tSHIFTL)
                                    ? IASTExpression.Kind.SHIFT_LEFT
                                    : IASTExpression.Kind.SHIFT_RIGHT),
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression additiveExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = multiplicativeExpression( scope );
        for (;;)
        {
        	if( !queryLookaheadCapability() ) return firstExpression;
            switch (LT(1))
            {
                case IToken.tPLUS :
                case IToken.tMINUS :
                    IToken t = consume();
                    IASTExpression secondExpression =
                        multiplicativeExpression(scope);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                ((t.getType() == IToken.tPLUS)
                                    ? IASTExpression.Kind.ADDITIVE_PLUS
                                    : IASTExpression.Kind.ADDITIVE_MINUS),
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression multiplicativeExpression( IASTScope scope )
        throws BacktrackException, EndOfFileException
    {
        IASTExpression firstExpression = pmExpression(scope);
        for (;;)
        {
        	if( !queryLookaheadCapability() ) return firstExpression;
            switch (LT(1))
            {
                case IToken.tSTAR :
                case IToken.tDIV :
                case IToken.tMOD :
                    IToken t = consume();
                    IASTExpression secondExpression = pmExpression(scope);
                    IASTExpression.Kind kind = null;
                    switch (t.getType())
                    {
                        case IToken.tSTAR :
                            kind = IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY;
                            break;
                        case IToken.tDIV :
                            kind = IASTExpression.Kind.MULTIPLICATIVE_DIVIDE;
                            break;
                        case IToken.tMOD :
                            kind = IASTExpression.Kind.MULTIPLICATIVE_MODULUS;
                            break;
                    }
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                kind,
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression pmExpression( IASTScope scope ) throws EndOfFileException, BacktrackException
    {
        IASTExpression firstExpression = castExpression(scope);
        for (;;)
        {
        	if( ! queryLookaheadCapability() ) return firstExpression; 
            switch (LT(1))
            {
                case IToken.tDOTSTAR :
                case IToken.tARROWSTAR :
                    IToken t = consume();
                    IASTExpression secondExpression =
                        castExpression(scope);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                ((t.getType() == IToken.tDOTSTAR)
                                    ? IASTExpression.Kind.PM_DOTSTAR
                                    : IASTExpression.Kind.PM_ARROWSTAR),
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    /**
     * castExpression
     * : unaryExpression
     * | "(" typeId ")" castExpression
     */
    protected IASTExpression castExpression( IASTScope scope ) throws EndOfFileException, BacktrackException
    {
        // TO DO: we need proper symbol checkint to ensure type name
    	if( ! queryLookaheadCapability() ) return unaryExpression(scope);
        if (LT(1) == IToken.tLPAREN)
        {
            IToken mark = mark();
            consume();
            IASTTypeId typeId = null;
            // If this isn't a type name, then we shouldn't be here
            try
            {
                typeId = typeId(scope, false);
                consume(IToken.tRPAREN);
                IASTExpression castExpression = castExpression(scope);
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.CASTEXPRESSION,
                        castExpression,
                        null,
                        null,
                        typeId,
                        null, "", null);
                }
                catch (ASTSemanticException e)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            }
            catch (BacktrackException b)
            {
                backup(mark);
            }
        }
        return unaryExpression(scope);
        
    }
    
    /**
     * @throws BacktrackException
     */
    protected IASTTypeId typeId(IASTScope scope, boolean skipArrayModifiers ) throws EndOfFileException, BacktrackException
    {
    	IToken mark = mark();
    	ITokenDuple name = null;
    	boolean isConst = false, isVolatile = false; 
    	boolean isSigned = false, isUnsigned = false; 
    	boolean isShort = false, isLong = false;
    	boolean isTypename = false; 
    	
    	IASTSimpleTypeSpecifier.Type kind = null;
    	do
    	{
	        try
	        {
	            name  = name();
	            kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
	            break;
	        }
	        catch (BacktrackException b)
	        {
	        	// do nothing
	        }
	        
	        boolean encounteredType = false;
            simpleMods : for (;;)
            {
                switch (LT(1))
                {
					 case IToken.t_signed :
					 	consume(); 
					 	isSigned = true; 
					 	break;
					 	
					 case IToken.t_unsigned :
					 	consume(); 
					 	isUnsigned = true; 
					 	break;
					 	
					 case IToken.t_short :
					 	consume(); 
					 	isShort = true; 
					 	break;
					 	
					 case IToken.t_long :
					 	consume(); 
					 	isLong = true; 
					 	break;
					 
					 case IToken.t_const :
					 	consume(); 
					 	isConst = true; 
					 	break; 
					 	
					 case IToken.t_volatile :
					 	consume(); 
					 	isVolatile = true;
                        break;
                        
                    case IToken.tIDENTIFIER :
                    	if( encounteredType ) break simpleMods;
                    	encounteredType = true;
                        name = name();
						kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
                        break;
                        
                    case IToken.t_int :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
                    	kind = IASTSimpleTypeSpecifier.Type.INT;
						consume();
                    	break;
                    	
                    case IToken.t_char :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.CHAR;
						consume();
						break;

                    case IToken.t_bool :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.BOOL;
						consume();
						break;
                    
                    case IToken.t_double :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.DOUBLE;
						consume();
						break;
                    
                    case IToken.t_float :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.FLOAT;
						consume();
						break;
                    
                    case IToken.t_wchar_t :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.WCHAR_T;
						consume();
						break;

                    
                    case IToken.t_void :
						if( encounteredType ) break simpleMods;
						encounteredType = true;                    
						kind = IASTSimpleTypeSpecifier.Type.VOID;
						consume();
						break;

                        
                    default :
                        break simpleMods;
                }
            }

			if( kind != null ) break;
			
			if( isShort || isLong || isUnsigned || isSigned )
			{
				kind = IASTSimpleTypeSpecifier.Type.INT;
				break;
			}
			
            if (
                LT(1) == IToken.t_typename
                    || LT(1) == IToken.t_struct
                    || LT(1) == IToken.t_class
                    || LT(1) == IToken.t_enum
                    || LT(1) == IToken.t_union)
            {
                consume();
                try
                {
                	name = name();
                	kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME;
                } catch( BacktrackException b )
                {
                	backup( mark );
                	throw backtrack; 
                }
            }
        
    	} while( false );
    	
    	if( kind == null )
    		throw backtrack;
    	
    	TypeId id = new TypeId(); 
    	IToken last = lastToken;
    	
		lastToken = consumeTemplateParameters( last );
		if( lastToken == null ) lastToken = last;
		
    	consumePointerOperators( id );
    	if( lastToken == null ) lastToken = last;
		
		if( ! skipArrayModifiers  )
		{
			last = lastToken; 
	    	consumeArrayModifiers( id, scope );
			if( lastToken == null ) lastToken = last;
		}
		
    	try
        {
            return astFactory.createTypeId( scope, kind, isConst, isVolatile, isShort, isLong, isSigned, isUnsigned, isTypename, name, id.getPointerOperators(), id.getArrayModifiers());
        }
        catch (ASTSemanticException e)
        {
            backup( mark );
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression deleteExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {    	
        if (LT(1) == IToken.tCOLONCOLON)
        {
            // global scope
            consume();
        }
        consume(IToken.t_delete);
        boolean vectored = false;
        if (LT(1) == IToken.tLBRACKET)
        {
            // array delete
            consume();
            consume(IToken.tRBRACKET);
            vectored = true;
        }
        IASTExpression castExpression = castExpression(scope);
        try
        {
            return astFactory.createExpression(
                scope,
                (vectored
                    ? IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION
                    : IASTExpression.Kind.DELETE_CASTEXPRESSION),
                castExpression,
                null,
                null,
                null,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * Pazse a new-expression.  
     * 
     * @param expression
     * @throws BacktrackException
     * 
     * 
     * newexpression: 	::? new newplacement? newtypeid newinitializer?
     *					::? new newplacement? ( typeid ) newinitializer?
     * newplacement:	( expressionlist )
     * newtypeid:		typespecifierseq newdeclarator?
     * newdeclarator:	ptroperator newdeclarator? | directnewdeclarator
     * directnewdeclarator:		[ expression ]
     *							directnewdeclarator [ constantexpression ]
     * newinitializer:	( expressionlist? )
     */
    protected IASTExpression newExpression( IASTScope scope ) throws BacktrackException, EndOfFileException
    {
        if (LT(1) == IToken.tCOLONCOLON)
        {
            // global scope
            consume();
        }
        consume(IToken.t_new);
        boolean typeIdInParen = false;
        boolean placementParseFailure = true;
        IToken beforeSecondParen = null;
        IToken backtrackMarker = null;
        IASTTypeId typeId = null;
		ArrayList newPlacementExpressions = new ArrayList();
		ArrayList newTypeIdExpressions = new ArrayList();
		ArrayList newInitializerExpressions = new ArrayList();
				
        if (LT(1) == IToken.tLPAREN)
        {
            consume(IToken.tLPAREN);
            try
            {
                // Try to consume placement list
                // Note: since expressionList and expression are the same...
                backtrackMarker = mark();
				newPlacementExpressions.add(expression(scope));
                consume(IToken.tRPAREN);
                placementParseFailure = false;
                if (LT(1) == IToken.tLPAREN)
                {
                    beforeSecondParen = mark();
                    consume(IToken.tLPAREN);
                    typeIdInParen = true;
                }
            }
            catch (BacktrackException e)
            {
                backup(backtrackMarker);
            }
            if (placementParseFailure)
            {
                // CASE: new (typeid-not-looking-as-placement) ...
                // the first expression in () is not a placement
                // - then it has to be typeId
                typeId = typeId(scope, true );
                consume(IToken.tRPAREN);
            }
            else
            {
                if (!typeIdInParen)
                {
                    if (LT(1) == IToken.tLBRACKET)
                    {
                        // CASE: new (typeid-looking-as-placement) [expr]...
                        // the first expression in () has been parsed as a placement;
                        // however, we assume that it was in fact typeId, and this 
                        // new statement creates an array.
                        // Do nothing, fallback to array/initializer processing
                    }
                    else
                    {
                        // CASE: new (placement) typeid ...
                        // the first expression in () is parsed as a placement,
                        // and the next expression doesn't start with '(' or '['
                        // - then it has to be typeId
                        try
                        {
                            backtrackMarker = mark();
                            typeId = typeId(scope, true);
                        }
                        catch (BacktrackException e)
                        {
                            // Hmmm, so it wasn't typeId after all... Then it is
                            // CASE: new (typeid-looking-as-placement)
                            backup(backtrackMarker);
							// TODO fix this
                            return null; 
                        }
                    }
                }
                else
                {
                    // Tricky cases: first expression in () is parsed as a placement,
                    // and the next expression starts with '('.
                    // The problem is, the first expression might as well be a typeid
                    try
                    {
                        typeId = typeId(scope, true);
                        consume(IToken.tRPAREN);
                        if (LT(1) == IToken.tLPAREN
                            || LT(1) == IToken.tLBRACKET)
                        {
                            // CASE: new (placement)(typeid)(initializer)
                            // CASE: new (placement)(typeid)[] ...
                            // Great, so far all our assumptions have been correct
                            // Do nothing, fallback to array/initializer processing
                        }
                        else
                        {
                            // CASE: new (placement)(typeid)
                            // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid)
                            // Worst-case scenario - this cannot be resolved w/o more semantic information.
                            // Luckily, we don't need to know what was that - we only know that 
                            // new-expression ends here.
							try
							{
								return astFactory.createExpression(
									scope, IASTExpression.Kind.NEW_TYPEID, 
									null, null, null, typeId, null, 
									"", astFactory.createNewDescriptor(newPlacementExpressions, newTypeIdExpressions, newInitializerExpressions));
							}
							catch (ASTSemanticException e)
							{
								throw backtrack;
							} catch (Exception e)
                            {
                                throw backtrack;
                            }
                        }
                    }
                    catch (BacktrackException e)
                    {
                        // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
                        // Fallback to initializer processing
                        backup(beforeSecondParen);
                    }
                }
            }
        }
        else
        {
            // CASE: new typeid ...
            // new parameters do not start with '('
            // i.e it has to be a plain typeId
            typeId = typeId(scope, true);
        }
        while (LT(1) == IToken.tLBRACKET)
        {
            // array new
            consume();
			newTypeIdExpressions.add(assignmentExpression(scope));
            consume(IToken.tRBRACKET);
        }
        // newinitializer
        if (LT(1) == IToken.tLPAREN)
        {
            consume(IToken.tLPAREN);
            if (LT(1) != IToken.tRPAREN)
			newInitializerExpressions.add(expression(scope));
            consume(IToken.tRPAREN);
        }
		try
		{
        return astFactory.createExpression(
        	scope, IASTExpression.Kind.NEW_TYPEID, 
			null, null, null, typeId, null, 
			"", astFactory.createNewDescriptor(newPlacementExpressions, newTypeIdExpressions, newInitializerExpressions));
		}
		catch (ASTSemanticException e)
		{
			return null;
		} catch (Exception e)
        {
            throw backtrack;
        }
    }
    protected IASTExpression unaryOperatorCastExpression( IASTScope scope,
        IASTExpression.Kind kind)
        throws EndOfFileException, BacktrackException
    {
        IASTExpression castExpression = castExpression(scope);
        try
        {
            return astFactory.createExpression(
                scope,
                kind,
                castExpression,
                null,
                null,
                null,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression unaryExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
    	if( ! queryLookaheadCapability() ) return postfixExpression( scope );
        switch (LT(1))
        {
            case IToken.tSTAR :
            	consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION);
            case IToken.tAMPER :
				consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION);
            case IToken.tPLUS :
				consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION);
            case IToken.tMINUS :
				consume();        
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION);
            case IToken.tNOT :
            	consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION);
            case IToken.tCOMPL :
            	consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION);
            case IToken.tINCR :
            	consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_INCREMENT);
            case IToken.tDECR :
            	consume();
                return unaryOperatorCastExpression(scope,
                    IASTExpression.Kind.UNARY_DECREMENT);
            case IToken.t_sizeof :
                consume(IToken.t_sizeof);
                IToken mark = LA(1);
                IASTTypeId d = null;
                IASTExpression unaryExpression = null;
                if (LT(1) == IToken.tLPAREN)
                {
                    try
                    {
                        consume(IToken.tLPAREN);
                        d = typeId(scope, false);
                        consume(IToken.tRPAREN);
                    }
                    catch (BacktrackException bt)
                    {
                        backup(mark);
                        unaryExpression = unaryExpression(scope);
                    }
                }
                else
                {
                    unaryExpression = unaryExpression(scope);
                }
                if (d != null & unaryExpression == null)
                    try
                    {
                        return astFactory.createExpression(
                            scope,
                            IASTExpression.Kind.UNARY_SIZEOF_TYPEID,
                            null,
                            null,
                            null,
                            d,
                            null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                else if (unaryExpression != null && d == null)
                    try
                    {
                        return astFactory.createExpression(
                            scope,
                            IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION,
                            unaryExpression,
                            null,
                            null,
                            null,
                            null, "", null);
                    }
                    catch (ASTSemanticException e1)
                    {
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                else
                    throw backtrack;
            case IToken.t_new :
                return newExpression(scope);
            case IToken.t_delete :
                return deleteExpression(scope);
            case IToken.tCOLONCOLON :
                switch (LT(2))
                {
                    case IToken.t_new :
                        return newExpression(scope);
                    case IToken.t_delete :
                        return deleteExpression(scope);
                    default :
                        return postfixExpression(scope);
                }
            default :
                return postfixExpression(scope);
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression postfixExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
        IASTExpression firstExpression = null;
        boolean isTemplate = false;
        
        if( ! queryLookaheadCapability() ) return primaryExpression(scope);
        switch (LT(1))
        {
            case IToken.t_typename :
                consume(IToken.t_typename);
                ITokenDuple nestedName = name();
				boolean templateTokenConsumed = false;
				if( LT(1) == IToken.t_template )
				{
				  consume( IToken.t_template ); 
				  templateTokenConsumed = true;
				}
				IToken current = mark(); 
				ITokenDuple templateId = null;
				try
				{
					templateId = new TokenDuple( current, templateId() ); 
				}
				catch( BacktrackException bt )
				{
					if( templateTokenConsumed )
						throw bt;
					backup( current );
				}
                consume( IToken.tLPAREN ); 
                IASTExpression expressionList = expression( scope ); 
                consume( IToken.tRPAREN );
                try {
					firstExpression = 
						astFactory.createExpression( scope, 
													(( templateId != null )? IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID : IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER ), 
													expressionList, 
													null, 
													null, 
													null, 
													nestedName,
													"", 
													null );
				} catch (ASTSemanticException ase ) {
					throw backtrack;
				} catch (Exception e)
                {
                    throw backtrack;
                }
                break;                
                // simple-type-specifier ( assignment-expression , .. )
            case IToken.t_char :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR);
                break;
            case IToken.t_wchar_t :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART);
                break;
            case IToken.t_bool :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL);
                break;
            case IToken.t_short :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT);
                break;
            case IToken.t_int :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT);
                break;
            case IToken.t_long :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG);
                break;
            case IToken.t_signed :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED);
                break;
            case IToken.t_unsigned :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED);
                break;
            case IToken.t_float :
                firstExpression =
                    simpleTypeConstructorExpression(scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT);
                break;
            case IToken.t_double :
                firstExpression =
                    simpleTypeConstructorExpression( scope,
                        IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE);
                break;
            case IToken.t_dynamic_cast :
                firstExpression =
                    specialCastExpression(scope,
                        IASTExpression.Kind.POSTFIX_DYNAMIC_CAST);
                break;
            case IToken.t_static_cast :
                firstExpression =
                    specialCastExpression(scope,
                        IASTExpression.Kind.POSTFIX_STATIC_CAST);
                break;
            case IToken.t_reinterpret_cast :
                firstExpression =
                    specialCastExpression(scope,
                        IASTExpression.Kind.POSTFIX_REINTERPRET_CAST);
                break;
            case IToken.t_const_cast :
                firstExpression =
                    specialCastExpression(scope,
                        IASTExpression.Kind.POSTFIX_CONST_CAST);
                break;
            case IToken.t_typeid :
                consume();
                consume(IToken.tLPAREN);
                boolean isTypeId = true;
                IASTExpression lhs = null;
                IASTTypeId typeId = null;
                try
                {
                    typeId = typeId(scope, false);
                }
                catch (BacktrackException b)
                {
                    isTypeId = false;
                    lhs = expression(scope);
                }
                consume(IToken.tRPAREN);
                try
                {
                    firstExpression =
                        astFactory.createExpression(
                            scope,
                            (isTypeId
                                ? IASTExpression.Kind.POSTFIX_TYPEID_TYPEID
                                : IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION),
                            lhs,
                            null,
                            null,
                            typeId,
                            null, "", null);
                }
                catch (ASTSemanticException e6)
                {
                    failParse();
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
                break;
            default :
                firstExpression = primaryExpression(scope);
        }
        IASTExpression secondExpression = null;
        for (;;)
        {
        	if( ! queryLookaheadCapability() )return firstExpression;
            switch (LT(1))
            {
                case IToken.tLBRACKET :
                    // array access
                    consume();
                    secondExpression = expression(scope);
                    consume(IToken.tRBRACKET);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                IASTExpression.Kind.POSTFIX_SUBSCRIPT,
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e2)
                    {
                        failParse();
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                case IToken.tLPAREN :
                    // function call
                    consume(IToken.tLPAREN);
                    secondExpression = expression(scope);
                    consume(IToken.tRPAREN);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                IASTExpression.Kind.POSTFIX_FUNCTIONCALL,
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e3)
                    {
                        failParse();
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                case IToken.tINCR :
                    consume();
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                IASTExpression.Kind.POSTFIX_INCREMENT,
                                firstExpression,
                                null,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e1)
                    {
                        failParse();
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                case IToken.tDECR :
                    consume();
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                IASTExpression.Kind.POSTFIX_DECREMENT,
                                firstExpression,
                                null,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e4)
                    {
                        failParse();
                        throw backtrack;
                    } catch (Exception e)
                    {
                        throw backtrack;
                    }
                    break;
                case IToken.tDOT :
                    // member access
                    consume(IToken.tDOT);
                	
                    try
					{
	                    if (LT(1) == IToken.t_template)
	                    {
	                        consume(IToken.t_template);
	                        isTemplate = true;
	                    }
		            } catch( OffsetLimitReachedException olre )
					{
		            	setCompletionToken( null );
		            }
            
                    IASTNode context = astFactory.getCompletionContext( (isTemplate
                                                                            ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS
                                                                            : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION), 
                                                                        firstExpression );
                    setCompletionContext( context );
                    setCompletionKind( IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
                    															
                    secondExpression = primaryExpression(scope);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                (isTemplate
                                    ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS
                                    : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION),
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e5)
                    {
                        failParse();
                        setCompletionContext( null );
                        throw backtrack;
                    } catch (Exception e)
                    {
                    	setCompletionContext( null );
                        throw backtrack;
                    } 	

                    break;
                case IToken.tARROW :
                    // member access
                    consume(IToken.tARROW);
                    
                    try
					{
	                    if (LT(1) == IToken.t_template)
	                    {
	                        consume(IToken.t_template);
	                        isTemplate = true;
	                    }
                    } catch( OffsetLimitReachedException olre )
					{
                    	setCompletionToken( null );
                    }
                    
                    context = astFactory.getCompletionContext( (isTemplate
                                                                    ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP
                                                                    : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION), 
                                                               firstExpression );
                    setCompletionContext( context );
                    setCompletionKind( IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
                    
                    secondExpression = primaryExpression(scope);
                    try
                    {
                        firstExpression =
                            astFactory.createExpression(
                                scope,
                                (isTemplate
                                    ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP
                                    : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION),
                                firstExpression,
                                secondExpression,
                                null,
                                null,
                                null, "", null);
                    }
                    catch (ASTSemanticException e)
                    {
                        failParse();
                        setCompletionContext( null );
                        throw backtrack;
                    } catch (Exception e)
                    {
                    	setCompletionContext( null );
                        throw backtrack;
                    }
                    break;
                default :
                    return firstExpression;
            }
        }
    }
    
    

    /**
	 * @return
	 * @throws EndOfFileException
	 */
	protected boolean queryLookaheadCapability() throws EndOfFileException {
		//make sure we can look ahead one before doing this
		boolean result = true;
		try
		{
			LA(1);
		}
		catch( OffsetLimitReachedException olre )
		{
			result = false;
		}
		return result;
	}
	protected IASTExpression specialCastExpression( IASTScope scope,
        IASTExpression.Kind kind)
        throws EndOfFileException, BacktrackException
    {
        consume();
        consume(IToken.tLT);
        IASTTypeId duple = typeId(scope, false);
        consume(IToken.tGT);
        consume(IToken.tLPAREN);
        IASTExpression lhs = expression(scope);
        consume(IToken.tRPAREN);
        try
        {
            return astFactory.createExpression(
                scope,
                kind,
                lhs,
                null,
                null,
                duple,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    protected IASTExpression simpleTypeConstructorExpression( IASTScope scope,
        Kind type)
        throws EndOfFileException, BacktrackException
    {
        consume();
        consume(IToken.tLPAREN);
        IASTExpression inside = expression(scope);
        consume(IToken.tRPAREN);
        try
        {
            return astFactory.createExpression(
                scope,
                type,
                inside,
                null,
                null,
                null,
                null, "", null);
        }
        catch (ASTSemanticException e)
        {
            failParse();
            throw backtrack;
        } catch (Exception e)
        {
            throw backtrack;
        }
    }
    /**
     * @param expression
     * @throws BacktrackException
     */
    protected IASTExpression primaryExpression( IASTScope scope )
        throws EndOfFileException, BacktrackException
    {
        IToken t = null;
        IASTExpression emptyExpression = null;
		try {
			emptyExpression = astFactory.createExpression(
					scope,
					IASTExpression.Kind.PRIMARY_EMPTY,
					null,
					null,
					null,
					null,
					null, "", null);
		} catch (ASTSemanticException e9) {
			// TODO Auto-generated catch block
			e9.printStackTrace();
		}
		if( !queryLookaheadCapability() ) return emptyExpression;
        switch (LT(1))
        {
            // TO DO: we need more literals...
            case IToken.tINTEGER :
                t = consume();
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_INTEGER_LITERAL,
                        null,
                        null,
                        null,
                        null,
                        null, t.getImage(), null);
                }
                catch (ASTSemanticException e1)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            case IToken.tFLOATINGPT :
                t = consume();
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_FLOAT_LITERAL,
                        null,
                        null,
                        null,
                        null,
                        null, t.getImage(), null);
                }
                catch (ASTSemanticException e2)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            case IToken.tSTRING :
            case IToken.tLSTRING :
				t = consume();
				try
                {
                    return astFactory.createExpression( scope, IASTExpression.Kind.PRIMARY_STRING_LITERAL, null, null, null, null, null, t.getImage(), null );
                }
                catch (ASTSemanticException e5)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            
            case IToken.t_false :
            case IToken.t_true :
                t = consume();
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL,
                        null,
                        null,
                    	null,
                        null,
                        null, t.getImage(), null);
                }
                catch (ASTSemanticException e3)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
                  
            case IToken.tCHAR :
			case IToken.tLCHAR :

                t = consume();
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_CHAR_LITERAL,
                        null,
                        null,
                        null,
                        null,
                        null, t.getImage(), null);
                }
                catch (ASTSemanticException e4)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
                    
            case IToken.t_this :
                consume(IToken.t_this);
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_THIS,
                        null,
                        null,
                        null,
                        null,
                        null, "", null);
                }
                catch (ASTSemanticException e7)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            case IToken.tLPAREN :
                consume();
                IASTExpression lhs = expression(scope);
                consume(IToken.tRPAREN);
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION,
                        lhs,
                        null,
                        null,
                        null,
                        null, "", null);
                }
                catch (ASTSemanticException e6)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            case IToken.tIDENTIFIER :
            case IToken.tCOLONCOLON :
            case IToken.t_operator : 
                ITokenDuple duple = null; 
                
                IToken mark = mark();
                try
                {
					duple = name();
                }
                catch( BacktrackException bt )
                {
                	Declarator d = new Declarator( new DeclarationWrapper(scope, 0, null) );

					if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER)
					{
						IToken start = consume();
						IToken end = null;
						if (start.getType() == IToken.tIDENTIFIER)
							 end = consumeTemplateParameters(end);
						while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER)
						{
						   end = consume();
						   if (end.getType() == IToken.tIDENTIFIER)
						      end = consumeTemplateParameters(end);
						}
						if (LT(1) == IToken.t_operator)
							operatorId(d, start);
						else
						{
						   backup(mark);
						   throw backtrack;
						}
					 }
					 else if( LT(1) == IToken.t_operator )
					 	 operatorId( d, null);
					 
					 duple = d.getNameDuple();
                }
                catch(OffsetLimitReachedException olre )
				{
                	backup(mark);
                	throw backtrack;
                }
                                
                
                try
                {
                    return astFactory.createExpression(
                        scope,
                        IASTExpression.Kind.ID_EXPRESSION,
                        null,
                        null,
                    	null,
						null,
                        duple, "", null);
                }
                catch (ASTSemanticException e8)
                {
                    throw backtrack;
                } catch (Exception e)
                {
                    throw backtrack;
                }
            default :
				return emptyExpression;
        }
    }
    /**
     * @throws Exception
     */
    protected void varName() throws Exception
    {
        if (LT(1) == IToken.tCOLONCOLON)
            consume();
        for (;;)
        {
            switch (LT(1))
            {
                case IToken.tIDENTIFIER :
                    consume();
                    //if (isTemplateArgs()) {
                    //	rTemplateArgs();
                    //}
                    if (LT(1) == IToken.tCOLONCOLON)
                    {
                        switch (LT(2))
                        {
                            case IToken.tIDENTIFIER :
                            case IToken.tCOMPL :
                            case IToken.t_operator :
                                consume();
                                break;
                            default :
                                return;
                        }
                    }
                    else
                        return;
                    break;
                case IToken.tCOMPL :
                    consume();
                    consume(IToken.tIDENTIFIER);
                    return;
                case IToken.t_operator :
                    consume();
                    //rOperatorName();
                    return;
                default :
                    throw backtrack;
            }
        }
    }

    // the static instance we always use
    private static BacktrackException backtrack = new BacktrackException();

    // Token management    
    protected IScanner scanner;
    protected IToken currToken, // current token we plan to consume next 
    lastToken; // last token we consumed
	private boolean limitReached = false;
    
    protected void setCurrentScope( IASTScope scope )
    {
    }
    
    /**
     * Fetches a token from the scanner. 
     * 
     * @return				the next token from the scanner
     * @throws EndOfFileException	thrown when the scanner.nextToken() yields no tokens
     */
    protected IToken fetchToken() throws EndOfFileException
    {
    	if(limitReached) throw new OffsetLimitReachedException(getCompletionToken());
    	
        try
        {
            return scanner.nextToken();
        }
        catch( OffsetLimitReachedException olre )
        {
        	limitReached = true;
        	handleOffsetLimitException(olre);
        	return null;
        }
        catch (ScannerException e)
        {
            log.traceLog( "ScannerException thrown : " + e.getProblem().getMessage() );
			log.errorLog( "Scanner Exception: " + e.getProblem().getMessage()); //$NON-NLS-1$h
            failParse(); 
            return fetchToken();
        }
    }

    protected void handleOffsetLimitException(OffsetLimitReachedException exception) throws EndOfFileException {
		// unexpected, throw EOF instead (equivalent)
		throw new EndOfFileException();
	}
	/**
     * Look Ahead in the token list to see what is coming.  
     * 
     * @param i		How far ahead do you wish to peek?
     * @return		the token you wish to observe
     * @throws EndOfFileException	if looking ahead encounters EOF, throw EndOfFile 
     */
    protected IToken LA(int i) throws EndOfFileException
    {
        if (i < 1) // can't go backwards
            return null;
        if (currToken == null)
            currToken = fetchToken();
        IToken retToken = currToken;
        for (; i > 1; --i)
        {
            retToken = retToken.getNext();
            if (retToken == null)
                retToken = fetchToken();
        }
        return retToken;
    }
    /**
     * Look ahead in the token list and return the token type.  
     * 
     * @param i				How far ahead do you wish to peek?
     * @return				The type of that token
     * @throws EndOfFileException	if looking ahead encounters EOF, throw EndOfFile
     */
    protected int LT(int i) throws EndOfFileException
    {
        return LA(i).getType();
    }
    /**
     * Consume the next token available, regardless of the type.  
     * 
     * @return				The token that was consumed and removed from our buffer.  
     * @throws EndOfFileException	If there is no token to consume.  
     */
    protected IToken consume() throws EndOfFileException
    {
        if (currToken == null)
            currToken = fetchToken();
        if (currToken != null)
            lastToken = currToken;
        currToken = currToken.getNext();
        return lastToken;
    }
    /**
     * Consume the next token available only if the type is as specified.  
     * 
     * @param type			The type of token that you are expecting.  	
     * @return				the token that was consumed and removed from our buffer. 
     * @throws BacktrackException	If LT(1) != type 
     */
    protected IToken consume(int type) throws EndOfFileException, BacktrackException
    {
        if (LT(1) == type)
            return consume();
        else
            throw backtrack;
    }
    /**
     * Mark our place in the buffer so that we could return to it should we have to.  
     * 
     * @return				The current token. 
     * @throws EndOfFileException	If there are no more tokens.
     */
    protected IToken mark() throws EndOfFileException
    {
        if (currToken == null)
            currToken = fetchToken();
        return currToken;
    }
    /**
     * Rollback to a previous point, reseting the queue of tokens.  
     * 
     * @param mark		The point that we wish to restore to.  
     *  
     */
    protected void backup(IToken mark)
    {
        currToken = (Token)mark;
        lastToken = null; // this is not entirely right ... 
    }
    /* (non-Javadoc)
     * @see org.eclipse.cdt.internal.core.parser.IParser#getLanguage()
     */
    public ParserLanguage getLanguage()
    {
        return language;
    }
    /* (non-Javadoc)
     * @see org.eclipse.cdt.internal.core.parser.IParser#setLanguage(Language)
     */
    public void setLanguage( ParserLanguage l )
    {
        language = l;
    }
    /* (non-Javadoc)
     * @see org.eclipse.cdt.internal.core.parser.IParser#getLastErrorOffset()
     */
    public int getLastErrorOffset()
    {
        return firstErrorOffset;
    }
    
    protected void setCompletionContext( IASTNode node )
    {
    }
    
    protected void setCompletionKind( IASTCompletionNode.CompletionKind kind )
    {
    }
    
    protected void setCompletionKeywords(KeywordSets.Key key )
    {
    }

    protected void setCompletionToken( IToken token )
	{
    }
    
    protected IToken getCompletionToken()
	{
    	return null;
    }
}
