diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 7089bbbd3bc..282f93ed143 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -484,7 +484,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
 
         IASTCompoundStatement result = createCompoundStatement();
         ((ASTNode) result).setOffset(startingOffset);
-        result.setParent(mostRelevantScopeNode);
         result.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY);
         while (LT(1) != IToken.tRBRACE && LT(1) != IToken.tCOMPLETION && LT(1) != IToken.tEOC) {
             int checkToken = LA(1).hashCode();
@@ -2087,6 +2086,5 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
         throwBacktrack(token.getOffset(), token.getLength());
     }
 
-    protected IASTNode mostRelevantScopeNode;
 
 }
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
index d9e6a2d42f3..68078bb2dc0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
@@ -559,7 +559,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
         }
 
         translationUnit.setLocationResolver(scanner.getLocationResolver());
-        mostRelevantScopeNode = translationUnit;
 
         int lastBacktrack = -1;
         while (true) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index e81e3259c35..5d24707c044 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -152,4927 +152,4913 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
  */
 public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
 
-    private static final String COMPL = "~"; //$NON-NLS-1$
-
-    private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
-
-    private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
-
-    private static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
-
-    private static final String DYNAMIC_CAST = "dynamic_cast"; //$NON-NLS-1$
-
-    private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE = 4;
-
-    private ScopeStack templateIdScopes = new ScopeStack();
-
-    protected CPPASTTranslationUnit translationUnit;
-
-    private static class ScopeStack {
-        private int[] stack;
-
-        private int index = -1;
-
-        public ScopeStack() {
-            stack = new int[8];
-        }
-
-        private void grow() {
-            int[] newStack = new int[stack.length << 1];
-            System.arraycopy(stack, 0, newStack, 0, stack.length);
-            stack = newStack;
-        }
-
-        final public void push(int i) {
-            if (++index == stack.length)
-                grow();
-            stack[index] = i;
-        }
-
-        final public int pop() {
-            if (index >= 0)
-                return stack[index--];
-            return -1;
-        }
-
-        final public int peek() {
-            if (index >= 0)
-                return stack[index];
-            return -1;
-        }
-
-        final public int size() {
-            return index + 1;
-        }
-    }
-
-    /**
-     * 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 {
-        int startingOffset = previousLast == null ? LA(1).getOffset()
-                : previousLast.getOffset();
-        IToken last = previousLast;
-        if (LT(1) == IToken.tLT) {
-            last = consume(IToken.tLT);
-            // until we get all the names sorted out
-            ScopeStack scopes = new ScopeStack();
-            scopes.push(IToken.tLT);
-
-            while (scopes.size() > 0) {
-                int top;
-                last = consume();
-
-                switch (last.getType()) {
-                case IToken.tGT:
-                    if (scopes.peek() == IToken.tLT) {
-                        scopes.pop();
-                    }
-                    break;
-                case IToken.tRBRACKET:
-                    do {
-                        top = scopes.pop();
-                    } while (scopes.size() > 0
-                            && (top == IToken.tGT || top == IToken.tLT));
-                    if (top != IToken.tLBRACKET)
-                        throwBacktrack(startingOffset, last.getEndOffset()
-                                - startingOffset);
-
-                    break;
-                case IToken.tRPAREN:
-                    do {
-                        top = scopes.pop();
-                    } while (scopes.size() > 0
-                            && (top == IToken.tGT || top == IToken.tLT));
-                    if (top != IToken.tLPAREN)
-                        throwBacktrack(startingOffset, last.getEndOffset()
-                                - startingOffset);
-
-                    break;
-                case IToken.tLT:
-                case IToken.tLBRACKET:
-                case IToken.tLPAREN:
-                    scopes.push(last.getType());
-                    break;
-                }
-            }
-        }
-        return last;
-    }
-
-    protected List templateArgumentList() throws EndOfFileException,
-            BacktrackException {
-        IToken start = LA(1);
-        int startingOffset = start.getOffset();
-        int endOffset = 0;
-        start = null;
-        List list = new ArrayList();
-
-        boolean completedArg = false;
-        boolean failed = false;
-
-        templateIdScopes.push(IToken.tLT);
-
-        while (LT(1) != IToken.tGT) {
-            completedArg = false;
-
-            IToken mark = mark();
-
-            try {
-                IASTTypeId typeId = typeId(false, false);
-                list.add(typeId);
-                completedArg = true;
-            } catch (BacktrackException e) {
-                backup(mark);
-            } /*
-                 * catch (ASTSemanticException e) { backup(mark); }
-                 */
-
-            if (!completedArg) {
-                try {
-                    IASTExpression expression = assignmentExpression();
-                    list.add(expression);
-                    completedArg = true;
-                } catch (BacktrackException e) {
-                    backup(mark);
-                }
-            }
-
-            if (LT(1) == IToken.tCOMMA) {
-                consume();
-            } else if (LT(1) != IToken.tGT) {
-                failed = true;
-                endOffset = LA(1).getEndOffset();
-                break;
-            }
-        }
-
-        templateIdScopes.pop();
-
-        if (failed)
-            throwBacktrack(startingOffset, endOffset - startingOffset);
-
-        return list;
-    }
-
-    /**
-     * Parse a name. name : ("::")? name2 ("::" name2)* name2 : IDENTIFER :
-     * template-id
-     * 
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected ITokenDuple name() throws BacktrackException, EndOfFileException {
-
-        TemplateParameterManager argumentList = TemplateParameterManager
-                .getInstance();
-
-        try {
-            IToken first = LA(1);
-            IToken last = null;
-            IToken mark = mark();
-
-            boolean hasTemplateId = false;
-
-            if (LT(1) == IToken.tCOLONCOLON) {
-                argumentList.addSegment(null);
-                last = consume(IToken.tCOLONCOLON);
-            }
-
-            if (LT(1) == IToken.tCOMPL)
-                consume();
-
-            switch (LT(1)) {
-            case IToken.tIDENTIFIER:
-            case IToken.tCOMPLETION:
-            case IToken.tEOC:
-                last = consume();
-                last = consumeTemplateArguments(last, argumentList);
-                if (last.getType() == IToken.tGT)
-                    hasTemplateId = true;
-                break;
-
-            default:
-                IToken l = LA(1);
-                backup(mark);
-                throwBacktrack(first.getOffset(), l.getEndOffset()
-                        - first.getOffset());
-            }
-
-            while (LT(1) == IToken.tCOLONCOLON) {
-                last = consume(IToken.tCOLONCOLON);
-
-                if (LT(1) == IToken.t_template)
-                    consume();
-
-                if (LT(1) == IToken.tCOMPL)
-                    consume();
-
-                switch (LT(1)) {
-                case IToken.t_operator:
-                    IToken l = LA(1);
-                    backup(mark);
-                    throwBacktrack(first.getOffset(), l.getEndOffset()
-                            - first.getOffset());
-                case IToken.tIDENTIFIER:
-                case IToken.tCOMPLETION:
-                case IToken.tEOC:
-                    last = consume();
-                    last = consumeTemplateArguments(last, argumentList);
-                    if (last.getType() == IToken.tGT)
-                        hasTemplateId = true;
-                }
-            }
-
-            ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last,
-                    (hasTemplateId ? argumentList.getTemplateArgumentsList()
-                            : null));
-            return tokenDuple;
-        } finally {
-            TemplateParameterManager.returnInstance(argumentList);
-        }
-
-    }
-
-    /**
-     * @param last
-     * @param argumentList
-     * @return
-     * @throws EndOfFileException
-     * @throws BacktrackException
-     */
-    protected IToken consumeTemplateArguments(IToken last,
-            TemplateParameterManager argumentList) throws EndOfFileException,
-            BacktrackException {
-        // if (language != ParserLanguage.CPP)
-        // return last;
-        if (LT(1) == IToken.tLT) {
-            IToken secondMark = mark();
-            consume(IToken.tLT);
-            try {
-                List list = templateArgumentList();
-                argumentList.addSegment(list);
-                last = consume(IToken.tGT);
-            } catch (BacktrackException bt) {
-                argumentList.addSegment(null);
-                backup(secondMark);
-            }
-        } else {
-            argumentList.addSegment(null);
-        }
-        return last;
-    }
-
-    protected IASTName operatorId(IToken originalToken,
-            TemplateParameterManager templateArgs) throws BacktrackException,
-            EndOfFileException {
-        // we know this is an operator
-        IToken operatorToken = consume(IToken.t_operator);
-        IToken toSend = null;
-        IASTTypeId typeId = 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
-                throwBacktrack(operatorToken.getOffset(),
-                        toSend != null ? toSend.getEndOffset()
-                                - operatorToken.getOffset() : 0);
-        } else {
-            // must be a conversion function
-            IToken t = LA(1);
-            typeId = typeId(true, false);
-            if (t != LA(1)) {
-                while (t.getNext() != LA(1)) {
-                    t = t.getNext();
-                }
-                toSend = t;
-            }
-        }
-
-        boolean hasTemplateId = (templateArgs != null);
-        boolean grabbedNewInstance = false;
-        if (templateArgs == null) {
-            templateArgs = TemplateParameterManager.getInstance();
-            grabbedNewInstance = true;
-        }
-
-        try {
-            toSend = consumeTemplateArguments(toSend, templateArgs);
-            if (toSend.getType() == IToken.tGT) {
-                hasTemplateId = true;
-            }
-
-            ITokenDuple duple = TokenFactory.createTokenDuple(
-                    originalToken == null ? operatorToken : originalToken,
-                    toSend, (hasTemplateId ? templateArgs
-                            .getTemplateArgumentsList() : null));
-
-            OperatorTokenDuple operator = new OperatorTokenDuple(duple);
-            if (typeId != null) { // if it's a conversion operator
-                operator.setConversionOperator(true);
-                operator.setTypeId(typeId);
-            }
-
-            return createName(operator);
-        } finally {
-            if (grabbedNewInstance)
-                TemplateParameterManager.returnInstance(templateArgs);
-        }
-    }
-
-    /**
-     * Parse a Pointer Operator. ptrOperator : "*" (cvQualifier)* | "&" | ::?
-     * nestedNameSpecifier "*" (cvQualifier)*
-     * 
-     * @param owner
-     *            Declarator that this pointer operator corresponds to.
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected void consumePointerOperators(List collection)
-            throws EndOfFileException, BacktrackException {
-
-        for (;;) {
-            if (LT(1) == IToken.tAMPER) {
-                int length = LA(1).getEndOffset() - LA(1).getOffset();
-                int o = consume(IToken.tAMPER).getOffset();
-                ICPPASTReferenceOperator refOp = createReferenceOperator();
-                ((ASTNode) refOp).setOffsetAndLength(o, length);
-                collection.add(refOp);
-                return;
-            }
-            IToken last = null;
-            IToken mark = mark();
-            ITokenDuple nameDuple = null;
-            boolean isConst = false, isVolatile = false, isRestrict = false;
-            if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) {
-                try {
-                    nameDuple = name();
-                    last = nameDuple.getLastToken();
-                } catch (BacktrackException bt) {
-                    backup(mark);
-                    return;
-                }
-            }
-            if (LT(1) == IToken.tSTAR) {
-                last = consume(IToken.tSTAR);
-                int starOffset = last.getOffset();
-
-                for (;;) {
-                    IToken t = LA(1);
-                    int startingOffset = LA(1).getOffset();
-                    switch (LT(1)) {
-                    case IToken.t_const:
-                        last = consume(IToken.t_const);
-                        isConst = true;
-                        break;
-                    case IToken.t_volatile:
-                        last = consume(IToken.t_volatile);
-                        isVolatile = true;
-                        break;
-                    case IToken.t_restrict:
-                        if (allowCPPRestrict) {
-                            last = consume(IToken.t_restrict);
-                            isRestrict = true;
-                            break;
-                        }
-                        IToken la = LA(1);
-                        throwBacktrack(startingOffset, la.getEndOffset()
-                                - startingOffset);
-
-                    }
-                    if (t == LA(1))
-                        break;
-                }
-
-                IASTPointerOperator po = null;
-                if (nameDuple != null) {
-                    IASTName name = createName(nameDuple);
-                    ICPPASTPointerToMember p2m = createPointerToMember(isRestrict);
-                    ((ASTNode) p2m).setOffsetAndLength(nameDuple
-                            .getFirstToken().getOffset(), last.getEndOffset()
-                            - nameDuple.getFirstToken().getOffset());
-                    p2m.setConst(isConst);
-                    p2m.setVolatile(isVolatile);
-                    p2m.setName(name);
-                    name.setParent(p2m);
-                    name.setPropertyInParent(ICPPASTPointerToMember.NAME);
-                    if (isRestrict) {
-                        IGPPASTPointerToMember newPo = (IGPPASTPointerToMember) p2m;
-                        newPo.setRestrict(isRestrict);
-                        p2m = newPo;
-                    }
-                    po = p2m;
-
-                } else {
-                    po = createPointer(isRestrict);
-                    ((ASTNode) po).setOffsetAndLength(starOffset, last
-                            .getEndOffset()
-                            - starOffset);
-                    ((IASTPointer) po).setConst(isConst);
-                    ((IASTPointer) po).setVolatile(isVolatile);
-                    if (isRestrict) {
-                        IGPPASTPointer newPo = (IGPPASTPointer) po;
-                        newPo.setRestrict(isRestrict);
-                        po = newPo;
-                    }
-                }
-                if (po != null)
-                    collection.add(po);
-
-                continue;
-            }
-
-            backup(mark);
-            return;
-        }
-    }
-
-    /**
-     * @param isRestrict
-     * @return
-     */
-    protected ICPPASTPointerToMember createPointerToMember(boolean gnu) {
-        if (gnu)
-            return new GPPASTPointerToMember();
-        return new CPPASTPointerToMember();
-    }
-
-    /**
-     * @param isRestrict
-     * @return
-     */
-    protected IASTPointerOperator createPointer(boolean gnu) {
-        if (gnu)
-            return new GPPASTPointer();
-        return new CPPASTPointer();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTReferenceOperator createReferenceOperator() {
-        return new CPPASTReferenceOperator();
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression assignmentExpression() throws EndOfFileException,
-            BacktrackException {
-        if (LT(1) == IToken.t_throw) {
-            return throwExpression();
-        }
-
-        if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tLBRACE
-                && supportStatementsInExpressions) {
-            IASTExpression resultExpression = compoundStatementExpression();
-            if (resultExpression != null)
-                return resultExpression;
-        }
-
-        IASTExpression conditionalExpression = conditionalExpression();
-        // if the condition not taken, try assignment operators
-        if (conditionalExpression != null
-                && conditionalExpression instanceof IASTConditionalExpression) // &&
-            return conditionalExpression;
-
-        switch (LT(1)) {
-        case IToken.tASSIGN:
-            return assignmentOperatorExpression(IASTBinaryExpression.op_assign,
-                    conditionalExpression);
-        case IToken.tSTARASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_multiplyAssign,
-                    conditionalExpression);
-        case IToken.tDIVASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_divideAssign, conditionalExpression);
-        case IToken.tMODASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_moduloAssign, conditionalExpression);
-        case IToken.tPLUSASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_plusAssign, conditionalExpression);
-        case IToken.tMINUSASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_minusAssign, conditionalExpression);
-        case IToken.tSHIFTRASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_shiftRightAssign,
-                    conditionalExpression);
-        case IToken.tSHIFTLASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_shiftLeftAssign,
-                    conditionalExpression);
-        case IToken.tAMPERASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_binaryAndAssign,
-                    conditionalExpression);
-        case IToken.tXORASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_binaryXorAssign,
-                    conditionalExpression);
-        case IToken.tBITORASSIGN:
-            return assignmentOperatorExpression(
-                    IASTBinaryExpression.op_binaryOrAssign,
-                    conditionalExpression);
-        }
-        return conditionalExpression;
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression throwExpression() throws EndOfFileException,
-            BacktrackException {
-        IToken throwToken = consume(IToken.t_throw);
-        IASTExpression throwExpression = null;
-        try {
-            throwExpression = expression();
-        } catch (BacktrackException bte) {
-        }
-        int o = throwExpression != null ? calculateEndOffset(throwExpression)
-                : throwToken.getEndOffset();
-        return buildUnaryExpression(ICPPASTUnaryExpression.op_throw,
-                throwExpression, throwToken.getOffset(), o
-                        - throwToken.getOffset());
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression relationalExpression() throws BacktrackException,
-            EndOfFileException {
-
-        IASTExpression firstExpression = shiftExpression();
-        for (;;) {
-            switch (LT(1)) {
-            case IToken.tGT:
-                if (templateIdScopes.size() > 0
-                        && templateIdScopes.peek() == IToken.tLT) {
-                    return firstExpression;
-                }
-            case IToken.tLT:
-            case IToken.tLTEQUAL:
-            case IToken.tGTEQUAL:
-                IToken m = mark();
-                int t = consume().getType();
-
-                IASTExpression secondExpression = null;
-                try {
-                    secondExpression = shiftExpression();
-                } catch (BacktrackException bte) {
-                    backup(m);
-                    return firstExpression;
-                }
-                int expressionKind = 0;
-                switch (t) {
-                case IToken.tGT:
-                    expressionKind = IASTBinaryExpression.op_greaterThan;
-                    break;
-                case IToken.tLT:
-                    expressionKind = IASTBinaryExpression.op_lessThan;
-                    break;
-                case IToken.tLTEQUAL:
-                    expressionKind = IASTBinaryExpression.op_lessEqual;
-                    break;
-                case IToken.tGTEQUAL:
-                    expressionKind = IASTBinaryExpression.op_greaterEqual;
-                    break;
-                }
-                firstExpression = buildBinaryExpression(expressionKind,
-                        firstExpression, secondExpression,
-                        calculateEndOffset(secondExpression));
-                break;
-            default:
-                if (supportMinAndMaxOperators
-                        && (LT(1) == IGCCToken.tMIN || LT(1) == IGCCToken.tMAX)) {
-                    int new_operator = 0;
-                    switch (LT(1)) {
-                    case IGCCToken.tMAX:
-                        consume();
-                        new_operator = IGPPASTBinaryExpression.op_max;
-                        break;
-                    case IGCCToken.tMIN:
-                        consume();
-                        new_operator = IGPPASTBinaryExpression.op_min;
-                    }
-
-                    secondExpression = shiftExpression();
-
-                    firstExpression = buildBinaryExpression(new_operator,
-                            firstExpression, secondExpression,
-                            calculateEndOffset(secondExpression));
-                    break;
-                }
-                return firstExpression;
-            }
-        }
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression multiplicativeExpression()
-            throws BacktrackException, EndOfFileException {
-        IASTExpression firstExpression = pmExpression();
-        for (;;) {
-            switch (LT(1)) {
-            case IToken.tSTAR:
-            case IToken.tDIV:
-            case IToken.tMOD:
-                IToken t = consume();
-                IASTExpression secondExpression = pmExpression();
-                int operator = 0;
-                switch (t.getType()) {
-                case IToken.tSTAR:
-                    operator = IASTBinaryExpression.op_multiply;
-                    break;
-                case IToken.tDIV:
-                    operator = IASTBinaryExpression.op_divide;
-                    break;
-                case IToken.tMOD:
-                    operator = IASTBinaryExpression.op_modulo;
-                    break;
-                }
-                firstExpression = buildBinaryExpression(operator,
-                        firstExpression, secondExpression,
-                        calculateEndOffset(secondExpression));
-                break;
-            default:
-                return firstExpression;
-            }
-        }
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression pmExpression() throws EndOfFileException,
-            BacktrackException {
-
-        IASTExpression firstExpression = castExpression();
-        for (;;) {
-            switch (LT(1)) {
-            case IToken.tDOTSTAR:
-            case IToken.tARROWSTAR:
-                IToken t = consume();
-                IASTExpression secondExpression = castExpression();
-                int operator = 0;
-                switch (t.getType()) {
-                case IToken.tDOTSTAR:
-                    operator = ICPPASTBinaryExpression.op_pmdot;
-                    break;
-                case IToken.tARROWSTAR:
-                    operator = ICPPASTBinaryExpression.op_pmarrow;
-                    break;
-                }
-                firstExpression = buildBinaryExpression(operator,
-                        firstExpression, secondExpression,
-                        calculateEndOffset(secondExpression));
-                break;
-            default:
-                return firstExpression;
-            }
-        }
-    }
-
-    /**
-     * castExpression : unaryExpression | "(" typeId ")" castExpression
-     */
-    protected IASTExpression castExpression() throws EndOfFileException,
-            BacktrackException {
-        // TO DO: we need proper symbol checkint to ensure type name
-        if (LT(1) == IToken.tLPAREN) {
-            IToken la = LA(1);
-            int startingOffset = la.getOffset();
-            IToken mark = mark();
-            consume();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLPAREN);
-            }
-            boolean popped = false;
-            IASTTypeId typeId = null;
-            // If this isn't a type name, then we shouldn't be here
-            try {
-                try {
-                    typeId = typeId(false, false);
-                    consume(IToken.tRPAREN);
-                } catch (BacktrackException bte) {
-                    backup(mark);
-                    throwBacktrack(bte);
-                }
-
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.pop();
-                    popped = true;
-                }
-                IASTExpression castExpression = castExpression();
-                mark = null; // clean up mark so that we can garbage collect
-                return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
-                        typeId, castExpression, startingOffset,
-                        calculateEndOffset(castExpression));
-            } catch (BacktrackException b) {
-                backup(mark);
-                if (templateIdScopes.size() > 0 && !popped) {
-                    templateIdScopes.pop();
-                }
-            }
-        }
-        return unaryExpression();
-
-    }
-
-    /**
-     * @throws BacktrackException
-     */
-    protected IASTTypeId typeId(boolean skipArrayModifiers,
-            boolean forNewExpression) throws EndOfFileException,
-            BacktrackException {
-        IToken mark = mark();
-        int startingOffset = mark.getOffset();
-        IASTDeclSpecifier declSpecifier = null;
-        IASTDeclarator declarator = null;
-
-        try {
-            declSpecifier = declSpecifierSeq(true, true);
-            declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR,
-                    true, forNewExpression);
-        } catch (BacktrackException bt) {
-            backup(mark);
-            throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
-                    declarator)
-                    - startingOffset);
-        }
-        if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$
-        {
-            backup(mark);
-            throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
-                    declarator)
-                    - startingOffset);
-        }
-        if (declSpecifier instanceof IASTSimpleDeclSpecifier
-                && ((ASTNode) declSpecifier).getLength() == 0) {
-            backup(mark);
-            throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
-                    declarator)
-                    - startingOffset);
-        }
-        if (declarator instanceof IASTArrayDeclarator && skipArrayModifiers) {
-            backup(mark);
-            throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
-                    declarator)
-                    - startingOffset);
-        }
-
-        IASTTypeId result = createTypeId();
-        ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(
-                declSpecifier, declarator)
-                - startingOffset);
-
-        result.setDeclSpecifier(declSpecifier);
-        declSpecifier.setParent(result);
-        declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER);
-
-        result.setAbstractDeclarator(declarator);
-        declarator.setParent(result);
-        declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR);
-
-        return result;
-
-    }
-
-    /**
-     * @return
-     */
-    protected IASTTypeId createTypeId() {
-        return new CPPASTTypeId();
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression deleteExpression() throws EndOfFileException,
-            BacktrackException {
-        int startingOffset = LA(1).getOffset();
-        boolean global = false;
-        if (LT(1) == IToken.tCOLONCOLON) {
-            // global scope
-            consume(IToken.tCOLONCOLON);
-            global = true;
-        }
-
-        consume(IToken.t_delete);
-
-        boolean vectored = false;
-        if (LT(1) == IToken.tLBRACKET) {
-            // array delete
-            consume();
-            consume(IToken.tRBRACKET);
-            vectored = true;
-        }
-        IASTExpression castExpression = castExpression();
-        ICPPASTDeleteExpression deleteExpression = createDeleteExpression();
-        ((ASTNode) deleteExpression).setOffsetAndLength(startingOffset,
-                calculateEndOffset(castExpression) - startingOffset);
-        deleteExpression.setIsGlobal(global);
-        deleteExpression.setIsVectored(vectored);
-        deleteExpression.setOperand(castExpression);
-        castExpression.setParent(deleteExpression);
-        castExpression.setPropertyInParent(ICPPASTDeleteExpression.OPERAND);
-        return deleteExpression;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTDeleteExpression createDeleteExpression() {
-        return new CPPASTDeleteExpression();
-    }
-
-    /**
-     * 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() throws BacktrackException,
-            EndOfFileException {
-        IToken la = LA(1);
-        int startingOffset = la.getOffset();
-        int lastOffset = 0;
-
-        boolean isGlobal = false;
-        if (LT(1) == IToken.tCOLONCOLON) {
-            lastOffset = consume(IToken.tCOLONCOLON).getEndOffset();
-            isGlobal = true;
-        }
-        lastOffset = consume(IToken.t_new).getEndOffset();
-        boolean typeIdInParen = false;
-        boolean placementParseFailure = true;
-        IToken beforeSecondParen = null;
-        IToken backtrackMarker = null;
-        IASTTypeId typeId = null;
-        IASTExpression newPlacementExpressions = null;
-        IASTExpression newInitializerExpressions = null;
-        boolean isNewTypeId = false;
-
-        master_new_loop: for (int i = 0; i < 2; ++i) {
-            IToken loopMark = LA(1);
-            if (LT(1) == IToken.tLPAREN) {
-                lastOffset = consume(IToken.tLPAREN).getEndOffset();
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.push(IToken.tLPAREN);
-                }
-                try {
-                    // Try to consume placement list
-                    if (i == 0) {
-                        backtrackMarker = mark();
-                        newPlacementExpressions = expression();
-                        lastOffset = consume(IToken.tRPAREN).getEndOffset();
-                        if (LT(1) == IToken.tLBRACKET) {
-                            backup(backtrackMarker);
-                            if (templateIdScopes.size() > 0) {
-                                templateIdScopes.pop();
-                            } // pop 1st Parent
-                            placementParseFailure = true;
-                            throwBacktrack(backtrackMarker.getOffset(),
-                                    backtrackMarker.getLength());
-                        } else
-                            placementParseFailure = false;
-                    }
-
-                    if (LT(1) == IToken.tLPAREN) {
-                        beforeSecondParen = mark();
-                        lastOffset = consume(IToken.tLPAREN).getEndOffset();
-                        if (templateIdScopes.size() > 0) {
-                            templateIdScopes.push(IToken.tLPAREN);
-                        } // push 2nd Paren
-                        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(true, false);
-                    lastOffset = consume(IToken.tRPAREN).getEndOffset();
-                    if (templateIdScopes.size() > 0) {
-                        templateIdScopes.pop();
-                    } // pop 1st Paren
-                    break master_new_loop;
-                }
-                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(true, true);
-                            lastOffset = calculateEndOffset(typeId);
-                            break master_new_loop;
-                        } catch (BacktrackException e) {
-                            // Hmmm, so it wasn't typeId after all... Then it is
-                            // CASE: new (typeid-looking-as-placement)
-                            backup(loopMark);
-                            placementParseFailure = true;
-                            continue master_new_loop;
-                        }
-                    }
-                } 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(true, false);
-                        lastOffset = consume(IToken.tRPAREN).getEndOffset();
-                        if (templateIdScopes.size() > 0) {
-                            templateIdScopes.pop();
-                        } // popping the 2nd Paren
-
-                        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.
-                            ICPPASTNewExpression result = createNewExpression();
-                            ((ASTNode) result)
-                                    .setOffsetAndLength(startingOffset,
-                                            lastOffset - startingOffset);
-                            result.setIsGlobal(isGlobal);
-                            result.setIsNewTypeId(isNewTypeId);
-                            result.setTypeId(typeId);
-                            typeId.setParent(result);
-                            typeId
-                                    .setPropertyInParent(ICPPASTNewExpression.TYPE_ID);
-                            if (newPlacementExpressions != null) {
-                                result.setNewPlacement(newPlacementExpressions);
-                                newPlacementExpressions.setParent(result);
-                                newPlacementExpressions
-                                        .setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT);
-                            }
-                            return result;
-                        }
-                        break master_new_loop;
-                    } catch (BacktrackException e) {
-                        // CASE: new
-                        // (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
-                        // Fallback to initializer processing
-                        backup(beforeSecondParen);
-                        if (templateIdScopes.size() > 0) {
-                            templateIdScopes.pop();
-                        }// pop that 2nd paren
-                    }
-                }
-
-            } else {
-                // CASE: new typeid ...
-                // new parameters do not start with '('
-                // i.e it has to be a plain typeId
-                typeId = typeId(true, true);
-                lastOffset = calculateEndOffset(typeId);
-                isNewTypeId = true;
-                break master_new_loop;
-            }
-        }
-        ICPPASTNewExpression result = createNewExpression();
-        ((ASTNode) result).setOffsetAndLength(startingOffset, lastOffset
-                - startingOffset);
-        result.setIsGlobal(isGlobal);
-        if (typeId != null) {
-            result.setIsNewTypeId(isNewTypeId);
-            result.setTypeId(typeId);
-            typeId.setParent(result);
-            typeId.setPropertyInParent(ICPPASTNewExpression.TYPE_ID);
-        }
-        if (newPlacementExpressions != null) {
-            result.setNewPlacement(newPlacementExpressions);
-            newPlacementExpressions.setParent(result);
-            newPlacementExpressions
-                    .setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT);
-        }
-
-        while (LT(1) == IToken.tLBRACKET) {
-            // array new
-            lastOffset = consume().getEndOffset();
-
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLBRACKET);
-            }
-
-            IASTExpression a = assignmentExpression();
-            lastOffset = consume(IToken.tRBRACKET).getEndOffset();
-            result.addNewTypeIdArrayExpression(a);
-            a.setParent(result);
-            a
-                    .setPropertyInParent(ICPPASTNewExpression.NEW_TYPEID_ARRAY_EXPRESSION);
-
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.pop();
-            }
-        }
-        // newinitializer
-        if (LT(1) == IToken.tLPAREN) {
-            lastOffset = consume(IToken.tLPAREN).getEndOffset();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLPAREN);
-            }
-
-            // we want to know the difference between no newInitializer and an
-            // empty new Initializer
-            // if the next token is the RPAREN, then we have an Empty expression
-            // in our list.
-            if (LT(1) != IToken.tRPAREN)
-                newInitializerExpressions = expression();
-
-            lastOffset = consume(IToken.tRPAREN).getEndOffset();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.pop();
-            }
-            if (newInitializerExpressions != null) {
-                result.setNewInitializer(newInitializerExpressions);
-                newInitializerExpressions.setParent(result);
-                newInitializerExpressions
-                        .setPropertyInParent(ICPPASTNewExpression.NEW_INITIALIZER);
-            }
-
-        }
-        ((CPPASTNode) result).setLength(lastOffset - startingOffset);
-        return result;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTNewExpression createNewExpression() {
-        return new CPPASTNewExpression();
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression unaryExpression() throws EndOfFileException,
-            BacktrackException {
-        IToken la = LA(1);
-        int startingOffset = la.getOffset();
-        switch (LT(1)) {
-        case IToken.tSTAR:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_star);// IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION);
-        case IToken.tAMPER:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_amper);// IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION);
-        case IToken.tPLUS:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_plus);// IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION);
-        case IToken.tMINUS:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_minus);// IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION);
-        case IToken.tNOT:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_not);// IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION);
-        case IToken.tCOMPL:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_tilde);// IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION);
-        case IToken.tINCR:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixIncr);// IASTExpression.Kind.UNARY_INCREMENT);
-        case IToken.tDECR:
-            return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr);// IASTExpression.Kind.UNARY_DECREMENT);
-        case IToken.t_sizeof:
-            consume(IToken.t_sizeof);
-            IToken mark = LA(1);
-            IASTTypeId typeId = null;
-            int lastOffset = 0;
-            IASTExpression unaryExpression = null;
-            if (LT(1) == IToken.tLPAREN) {
-                try {
-                    consume(IToken.tLPAREN);
-                    typeId = typeId(true, false);
-                    lastOffset = consume(IToken.tRPAREN).getEndOffset();
-                } catch (BacktrackException bt) {
-                    backup(mark);
-                    unaryExpression = unaryExpression();
-                    lastOffset = calculateEndOffset(unaryExpression);
-                }
-            } else {
-                unaryExpression = unaryExpression();
-                lastOffset = calculateEndOffset(unaryExpression);
-            }
-
-            if (typeId == null && unaryExpression != null)
-                return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
-                        unaryExpression, startingOffset, lastOffset);
-            return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
-                    typeId, startingOffset, lastOffset);
-        case IToken.t_new:
-            return newExpression();
-        case IToken.t_delete:
-            return deleteExpression();
-        case IToken.tCOLONCOLON:
-            switch (LT(2)) {
-            case IToken.t_new:
-                return newExpression();
-            case IToken.t_delete:
-                return deleteExpression();
-            default:
-                return postfixExpression();
-            }
-        default:
-            if (LT(1) == IGCCToken.t_typeof && supportTypeOfUnaries) {
-                IASTExpression unary = unaryTypeofExpression();
-                if (unary != null)
-                    return unary;
-            }
-            if (LT(1) == IGCCToken.t___alignof__ && supportAlignOfUnaries) {
-                IASTExpression align = unaryAlignofExpression();
-                if (align != null)
-                    return align;
-            }
-            return postfixExpression();
-        }
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression postfixExpression() throws EndOfFileException,
-            BacktrackException {
-        IASTExpression firstExpression = null;
-        boolean isTemplate = false;
-
-        switch (LT(1)) {
-        case IToken.t_typename:
-            int o = consume(IToken.t_typename).getOffset();
-
-            boolean templateTokenConsumed = false;
-            if (LT(1) == IToken.t_template) {
-                consume(IToken.t_template);
-                templateTokenConsumed = true;
-            }
-            ITokenDuple nestedName = name();
-            IASTName name = createName(nestedName);
-
-            consume(IToken.tLPAREN);
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLPAREN);
-            }
-            IASTExpression expressionList = expression();
-            int lastOffset = consume(IToken.tRPAREN).getEndOffset();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.pop();
-            }
-
-            ICPPASTTypenameExpression result = createTypenameExpression();
-            ((ASTNode) result).setOffsetAndLength(o, lastOffset - o);
-            result.setIsTemplate(templateTokenConsumed);
-            result.setName(name);
-            name.setParent(result);
-            name.setPropertyInParent(ICPPASTTypenameExpression.TYPENAME);
-            result.setInitialValue(expressionList);
-            expressionList.setParent(result);
-            expressionList
-                    .setPropertyInParent(ICPPASTTypenameExpression.INITIAL_VALUE);
-            firstExpression = result;
-            break;
-        // simple-type-specifier ( assignment-expression , .. )
-        case IToken.t_char:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_char);
-            break;
-        case IToken.t_wchar_t:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_wchar_t);
-            break;
-        case IToken.t_bool:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_bool);
-            break;
-        case IToken.t_short:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_short);
-            break;
-        case IToken.t_int:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_int);
-            break;
-        case IToken.t_long:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_long);
-            break;
-        case IToken.t_signed:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_signed);
-            break;
-        case IToken.t_unsigned:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_unsigned);
-            break;
-        case IToken.t_float:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_float);
-            break;
-        case IToken.t_double:
-            firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_double);
-            break;
-        case IToken.t_dynamic_cast:
-            firstExpression = specialCastExpression(ICPPASTCastExpression.op_dynamic_cast);
-            break;
-        case IToken.t_static_cast:
-            firstExpression = specialCastExpression(ICPPASTCastExpression.op_static_cast);
-            break;
-        case IToken.t_reinterpret_cast:
-            firstExpression = specialCastExpression(ICPPASTCastExpression.op_reinterpret_cast);
-            break;
-        case IToken.t_const_cast:
-            firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast);
-            break;
-        case IToken.t_typeid:
-            int so = consume().getOffset();
-            consume(IToken.tLPAREN);
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLPAREN);
-            }
-            boolean isTypeId = true;
-            IASTExpression lhs = null;
-            IASTTypeId typeId = null;
-            IToken m = mark();
-            try {
-                boolean amb = false;
-                if ( LT(1) == IToken.tIDENTIFIER ) 
-                    amb = true;
-                typeId = typeId(false, false);                
-                if( amb && typeId.getDeclSpecifier() instanceof IASTNamedTypeSpecifier  )
-                {
-                    if( ! queryIsTypeName( ((IASTNamedTypeSpecifier) typeId.getDeclSpecifier()).getName() ) )
-                    {
-                        backup( m );
-                        throwBacktrack( ((CPPASTNode)typeId).getOffset(), ((CPPASTNode)typeId).getLength() );  
-                    }
-                }
-            } catch (BacktrackException b) {
-                typeId = null;
-                isTypeId = false;
-                lhs = expression();
-            }
-            lastOffset = consume(IToken.tRPAREN).getEndOffset();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.pop();
-            }
-            if (isTypeId && typeId != null)
-                firstExpression = buildTypeIdExpression(
-                        ICPPASTTypeIdExpression.op_typeid, typeId, so,
-                        lastOffset);
-            else
-                firstExpression = buildUnaryExpression(
-                        ICPPASTUnaryExpression.op_typeid, lhs, so, lastOffset);
-            break;
-        default:
-            firstExpression = primaryExpression();
-        }
-        IASTExpression secondExpression = null;
-        for (;;) {
-            switch (LT(1)) {
-            case IToken.tLBRACKET:
-                // array access
-                consume(IToken.tLBRACKET);
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.push(IToken.tLBRACKET);
-                }
-                secondExpression = expression();
-                int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.pop();
-                }
-
-                IASTArraySubscriptExpression s = createArraySubscriptExpression();
-                ((ASTNode) s).setOffsetAndLength(((ASTNode) firstExpression)
-                        .getOffset(), lastOffset
-                        - ((ASTNode) firstExpression).getOffset());
-                s.setArrayExpression(firstExpression);
-                firstExpression.setParent(s);
-                firstExpression
-                        .setPropertyInParent(IASTArraySubscriptExpression.ARRAY);
-                s.setSubscriptExpression(secondExpression);
-                secondExpression.setParent(s);
-                secondExpression
-                        .setPropertyInParent(IASTArraySubscriptExpression.SUBSCRIPT);
-                firstExpression = s;
-                break;
-            case IToken.tLPAREN:
-                // function call
-                consume(IToken.tLPAREN);
-
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.push(IToken.tLPAREN);
-                }
-                if (LT(1) != IToken.tRPAREN)
-                    secondExpression = expression();
-                else
-                    secondExpression = null;
-                lastOffset = consume(IToken.tRPAREN).getEndOffset();
-
-                if (templateIdScopes.size() > 0) {
-                    templateIdScopes.pop();
-                }
-
-                IASTFunctionCallExpression fce = createFunctionCallExpression();
-                ((ASTNode) fce).setOffsetAndLength(((ASTNode) firstExpression)
-                        .getOffset(), lastOffset
-                        - ((ASTNode) firstExpression).getOffset());
-                fce.setFunctionNameExpression(firstExpression);
-                firstExpression.setParent(fce);
-                firstExpression
-                        .setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME);
-                if (secondExpression != null) {
-                    fce.setParameterExpression(secondExpression);
-                    secondExpression.setParent(fce);
-                    secondExpression
-                            .setPropertyInParent(IASTFunctionCallExpression.PARAMETERS);
-                }
-                firstExpression = fce;
-                break;
-            case IToken.tINCR:
-                int offset = consume(IToken.tINCR).getEndOffset();
-                firstExpression = buildUnaryExpression(
-                        IASTUnaryExpression.op_postFixIncr, firstExpression,
-                        ((ASTNode) firstExpression).getOffset(), offset);
-                break;
-            case IToken.tDECR:
-                offset = consume().getEndOffset();
-                firstExpression = buildUnaryExpression(
-                        IASTUnaryExpression.op_postFixDecr, firstExpression,
-                        ((ASTNode) firstExpression).getOffset(), offset);
-                break;
-            case IToken.tDOT:
-                // member access
-                consume(IToken.tDOT);
-                if (LT(1) == IToken.t_template) {
-                    consume(IToken.t_template);
-                    isTemplate = true;
-                }
-
-                IASTName name = idExpression();
-
-                ICPPASTFieldReference fieldReference = createFieldReference();
-                ((ASTNode) fieldReference).setOffsetAndLength(
-                        ((ASTNode) firstExpression).getOffset(),
-                        calculateEndOffset(name)
-                                - ((ASTNode) firstExpression).getOffset());
-                fieldReference.setIsTemplate(isTemplate);
-                fieldReference.setIsPointerDereference(false);
-                fieldReference.setFieldName(name);
-                name.setParent(fieldReference);
-                name.setPropertyInParent(IASTFieldReference.FIELD_NAME);
-
-                fieldReference.setFieldOwner(firstExpression);
-                firstExpression.setParent(fieldReference);
-                firstExpression
-                        .setPropertyInParent(IASTFieldReference.FIELD_OWNER);
-                firstExpression = fieldReference;
-                break;
-            case IToken.tARROW:
-                // member access
-                consume(IToken.tARROW);
-
-                if (LT(1) == IToken.t_template) {
-                    consume(IToken.t_template);
-                    isTemplate = true;
-                }
-
-                name = idExpression();
-
-                fieldReference = createFieldReference();
-                ((ASTNode) fieldReference).setOffsetAndLength(
-                        ((ASTNode) firstExpression).getOffset(),
-                        calculateEndOffset(name)
-                                - ((ASTNode) firstExpression).getOffset());
-                fieldReference.setIsTemplate(isTemplate);
-                fieldReference.setIsPointerDereference(true);
-                fieldReference.setFieldName(name);
-                name.setParent(fieldReference);
-                name.setPropertyInParent(IASTFieldReference.FIELD_NAME);
-
-                fieldReference.setFieldOwner(firstExpression);
-                firstExpression.setParent(fieldReference);
-                firstExpression
-                        .setPropertyInParent(IASTFieldReference.FIELD_OWNER);
-                firstExpression = fieldReference;
-                break;
-            default:
-                return firstExpression;
-            }
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected IASTArraySubscriptExpression createArraySubscriptExpression() {
-        return new CPPASTArraySubscriptExpression();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTypenameExpression createTypenameExpression() {
-        return new CPPASTTypenameExpression();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTFunctionCallExpression createFunctionCallExpression() {
-        return new CPPASTFunctionCallExpression();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTFieldReference createFieldReference() {
-        return new CPPASTFieldReference();
-    }
-
-    protected IASTExpression simpleTypeConstructorExpression(int operator)
-            throws EndOfFileException, BacktrackException {
-        int startingOffset = LA(1).getOffset();
-        consume();
-        consume(IToken.tLPAREN);
-        IASTExpression operand = null;
-        if (LT(1) != IToken.tRPAREN)
-            operand = expression();
-        int l = consume(IToken.tRPAREN).getEndOffset();
-        ICPPASTSimpleTypeConstructorExpression result = createSimpleTypeConstructorExpression();
-        ((ASTNode) result).setOffsetAndLength(startingOffset, l
-                - startingOffset);
-        result.setSimpleType(operator);
-        if (operand != null) {
-            result.setInitialValue(operand);
-            operand.setParent(result);
-            operand
-                    .setPropertyInParent(ICPPASTSimpleTypeConstructorExpression.INITIALIZER_VALUE);
-        }
-        return result;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTSimpleTypeConstructorExpression createSimpleTypeConstructorExpression() {
-        return new CPPASTSimpleTypeConstructorExpression();
-    }
-
-    /**
-     * @param expression
-     * @throws BacktrackException
-     */
-    protected IASTExpression primaryExpression() throws EndOfFileException,
-            BacktrackException {
-        IToken t = null;
-        ICPPASTLiteralExpression literalExpression = null;
-        switch (LT(1)) {
-        // TO DO: we need more literals...
-        case IToken.tINTEGER:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression
-                    .setKind(IASTLiteralExpression.lk_integer_constant);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.tFLOATINGPT:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(IASTLiteralExpression.lk_float_constant);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.tSTRING:
-        case IToken.tLSTRING:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(IASTLiteralExpression.lk_string_literal);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.tCHAR:
-        case IToken.tLCHAR:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(IASTLiteralExpression.lk_char_constant);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.t_false:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(ICPPASTLiteralExpression.lk_false);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.t_true:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(ICPPASTLiteralExpression.lk_true);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-
-        case IToken.t_this:
-            t = consume();
-            literalExpression = createLiteralExpression();
-            literalExpression.setKind(ICPPASTLiteralExpression.lk_this);
-            literalExpression.setValue(t.getImage());
-            ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
-                    .getEndOffset()
-                    - t.getOffset());
-            return literalExpression;
-        case IToken.tLPAREN:
-            t = consume();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.push(IToken.tLPAREN);
-            }
-            IASTExpression lhs = expression();
-            int finalOffset = consume(IToken.tRPAREN).getEndOffset();
-            if (templateIdScopes.size() > 0) {
-                templateIdScopes.pop();
-            }
-            return buildUnaryExpression(
-                    IASTUnaryExpression.op_bracketedPrimary, lhs,
-                    t.getOffset(), finalOffset);
-        case IToken.tIDENTIFIER:
-        case IToken.tCOLONCOLON:
-        case IToken.t_operator:
-        case IToken.tCOMPL: {
-            IASTName name = idExpression();
-            IASTIdExpression idExpression = createIdExpression();
-            ((ASTNode) idExpression).setOffsetAndLength(((ASTNode) name)
-                    .getOffset(), ((ASTNode) name).getOffset()
-                    + ((ASTNode) name).getLength()
-                    - ((ASTNode) name).getOffset());
-            idExpression.setName(name);
-            name.setParent(idExpression);
-            name.setPropertyInParent(IASTIdExpression.ID_NAME);
-            return idExpression;
-        }
-        case IToken.tCOMPLETION: {
-            IToken token = consume();
-            IASTName name = createName(token);
-            IASTIdExpression idExpression = createIdExpression();
-            idExpression.setName(name);
-            name.setParent(idExpression);
-            name.setPropertyInParent(IASTIdExpression.ID_NAME);
-            createCompletionNode(token).addName(name);
-            return idExpression;
-        }
-        default:
-            IToken la = LA(1);
-            int startingOffset = la.getOffset();
-            throwBacktrack(startingOffset, la.getLength());
-            return null;
-        }
-
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTLiteralExpression createLiteralExpression() {
-        return new CPPASTLiteralExpression();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTIdExpression createIdExpression() {
-        return new CPPASTIdExpression();
-    }
-
-    protected IASTName idExpression() throws EndOfFileException,
-            BacktrackException {
-        IASTName name = null;
-        try {
-            name = createName(name());
-        } catch (BacktrackException bt) {
-            IToken mark = mark();
-            if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
-                IToken start = consume();
-                IToken end = null;
-                if (start.getType() == IToken.tIDENTIFIER)
-                    end = consumeTemplateParameters(null);
-                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)
-                    name = operatorId(start, null);
-                else {
-                    backup(mark);
-                    throwBacktrack(start.getOffset(), end.getEndOffset()
-                            - start.getOffset());
-                }
-            } else if (LT(1) == IToken.t_operator)
-                name = operatorId(null, null);
-        }
-        return name;
-
-    }
-
-    protected IASTExpression specialCastExpression(int kind)
-            throws EndOfFileException, BacktrackException {
-        int startingOffset = LA(1).getOffset();
-        IToken op = consume();
-        consume(IToken.tLT);
-        IASTTypeId typeID = typeId(false, false);
-        consume(IToken.tGT);
-        consume(IToken.tLPAREN);
-        IASTExpression lhs = expression();
-        int l = consume(IToken.tRPAREN).getEndOffset();
-        IASTCastExpression result = createCastExpression();
-        ((ASTNode) result).setOffsetAndLength(startingOffset, l
-                - startingOffset);
-        result.setTypeId(typeID);
-        typeID.setParent(result);
-        typeID.setPropertyInParent(IASTCastExpression.TYPE_ID);
-        result.setOperand(lhs);
-
-        if (op.toString().equals(DYNAMIC_CAST)) {
-            result.setOperator(ICPPASTCastExpression.op_dynamic_cast);
-        } else if (op.toString().equals(STATIC_CAST)) {
-            result.setOperator(ICPPASTCastExpression.op_static_cast);
-        } else if (op.toString().equals(REINTERPRET_CAST)) {
-            result.setOperator(ICPPASTCastExpression.op_reinterpret_cast);
-        } else if (op.toString().equals(CONST_CAST)) {
-            result.setOperator(ICPPASTCastExpression.op_const_cast);
-        } else {
-            result.setOperator(IASTCastExpression.op_cast);
-        }
-
-        lhs.setParent(result);
-        lhs.setPropertyInParent(IASTCastExpression.OPERAND);
-        return result;
-    }
-
-    private final boolean allowCPPRestrict;
-
-    private final boolean supportExtendedTemplateSyntax;
-
-    private final boolean supportMinAndMaxOperators;
-
-    private final boolean supportComplex;
-
-    private final boolean supportRestrict;
-
-    private final boolean supportLongLong;
-
-    private static final int DEFAULT_PARM_LIST_SIZE = 4;
-
-    private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
-
-    private static final int DEFAULT_SIZE_EXCEPTIONS_LIST = 2;
-
-    private static final int DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE = 4;
-
-    /**
-     * This is the standard cosntructor that we expect the Parser to be
-     * instantiated with.
-     * 
-     * @param mode
-     *            TODO
-     */
-    public GNUCPPSourceParser(IScanner scanner, ParserMode mode,
-            IParserLogService log, ICPPParserExtensionConfiguration config) {
-        super(scanner, log, mode, config.supportStatementsInExpressions(),
-                config.supportTypeofUnaryExpressions(), config
-                        .supportAlignOfUnaryExpression());
-        allowCPPRestrict = config.allowRestrictPointerOperators();
-        supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax();
-        supportMinAndMaxOperators = config.supportMinAndMaxOperators();
-        supportRestrict = config.supportRestrictKeyword();
-        supportComplex = config.supportComplexNumbers();
-        supportLongLong = config.supportLongLongs();
-    }
-
-    /**
-     * 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.
-     * @return TODO
-     * @throws BacktrackException
-     *             request for a backtrack
-     */
-    protected IASTDeclaration usingClause() throws EndOfFileException,
-            BacktrackException {
-        IToken firstToken = consume(IToken.t_using);
-
-        if (LT(1) == IToken.t_namespace) {
-            // using-directive
-            int endOffset = consume(IToken.t_namespace).getEndOffset();
-            IASTName name = null;
-            if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON)
-                name = createName(name());
-            else
-                throwBacktrack(firstToken.getOffset(), endOffset
-                        - firstToken.getOffset());
-
-            endOffset = consume(IToken.tSEMI).getEndOffset();
-            ICPPASTUsingDirective astUD = createUsingDirective();
-            ((ASTNode) astUD).setOffsetAndLength(firstToken.getOffset(),
-                    endOffset - firstToken.getOffset());
-            astUD.setQualifiedName(name);
-            name.setParent(astUD);
-            name.setPropertyInParent(ICPPASTUsingDirective.QUALIFIED_NAME);
-            return astUD;
-        }
-
-        boolean typeName = false;
-
-        if (LT(1) == IToken.t_typename) {
-            typeName = true;
-            consume(IToken.t_typename);
-        }
-
-        IASTName name = createName(name());
-        int end = consume(IToken.tSEMI).getEndOffset();
-        ICPPASTUsingDeclaration result = createUsingDeclaration();
-        ((ASTNode) result).setOffsetAndLength(firstToken.getOffset(), end
-                - firstToken.getOffset());
-        result.setIsTypename(typeName);
-        result.setName(name);
-        name.setPropertyInParent(ICPPASTUsingDeclaration.NAME);
-        name.setParent(result);
-        return result;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTUsingDeclaration createUsingDeclaration() {
-        return new CPPASTUsingDeclaration();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTUsingDirective createUsingDirective() {
-        return new CPPASTUsingDirective();
-    }
-
-    /**
-     * 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.
-     * @return TODO
-     * @throws BacktrackException
-     *             request for a backtrack
-     */
-    protected ICPPASTLinkageSpecification linkageSpecification()
-            throws EndOfFileException, BacktrackException {
-        IToken firstToken = consume(IToken.t_extern);
-        IToken spec = consume(IToken.tSTRING);
-        ICPPASTLinkageSpecification linkage = createLinkageSpecification();
-        ((ASTNode) linkage).setOffset(firstToken.getOffset());
-        linkage.setLiteral(spec.getImage());
-
-        if (LT(1) == IToken.tLBRACE) {
-            consume(IToken.tLBRACE);
-
-            linkageDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
-                int checkToken = LA(1).hashCode();
-                switch (LT(1)) {
-                case IToken.tRBRACE:
-                    break linkageDeclarationLoop;
-                default:
-                    try {
-                        IASTDeclaration d = declaration();
-                        linkage.addDeclaration(d);
-                        d.setParent(linkage);
-                        d
-                                .setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
-                    } catch (BacktrackException bt) {
-                        IASTProblem p = failParse(bt);
-                        IASTProblemDeclaration pd = createProblemDeclaration();
-                        p.setParent(pd);
-                        pd.setProblem(p);
-                        ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
-                        p.setPropertyInParent(IASTProblemHolder.PROBLEM);
-                        linkage.addDeclaration(pd);
-                        pd.setParent(linkage);
-                        pd
-                                .setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
-                        errorHandling();
-                        if (checkToken == LA(1).hashCode())
-                            errorHandling();
-                    }
-                }
-                if (checkToken == LA(1).hashCode())
-                    failParseWithErrorHandling();
-            }
-            // consume the }
-            int endOffset = consume(IToken.tRBRACE).getEndOffset();
-            ((CPPASTNode) linkage)
-                    .setLength(endOffset - firstToken.getOffset());
-            return linkage;
-        }
-        // single declaration
-
-        IASTDeclaration d = declaration();
-        linkage.addDeclaration(d);
-        d.setParent(linkage);
-        d.setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
-        ((CPPASTNode) linkage).setLength(calculateEndOffset(d)
-                - firstToken.getOffset());
-        return linkage;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTLinkageSpecification createLinkageSpecification() {
-        return new CPPASTLinkageSpecification();
-    }
-
-    /**
-     * 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.
-     * @return TODO
-     * @throws BacktrackException
-     *             request for a backtrack
-     */
-    protected IASTDeclaration templateDeclaration() throws EndOfFileException,
-            BacktrackException {
-        IToken mark = mark();
-        IToken firstToken = null;
-        boolean exported = false;
-        boolean encounteredExtraMod = false;
-        if (LT(1) == IToken.t_export) {
-            exported = true;
-            firstToken = consume(IToken.t_export);
-            consume(IToken.t_template);
-        } else {
-            if (supportExtendedTemplateSyntax) {
-                switch (LT(1)) {
-                case IToken.t_static:
-                case IToken.t_extern:
-                case IToken.t_inline:
-                    firstToken = consume();
-                    consume(IToken.t_template);
-                    encounteredExtraMod = true;
-                    break;
-                default:
-                    firstToken = consume(IToken.t_template);
-                    break;
-                }
-            } else
-                firstToken = consume(IToken.t_template);
-        }
-        if (LT(1) != IToken.tLT) {
-            // explicit-instantiation
-            ICPPASTExplicitTemplateInstantiation templateInstantiation = null;
-            if (encounteredExtraMod && supportExtendedTemplateSyntax) {
-                IGPPASTExplicitTemplateInstantiation temp = createGnuTemplateInstantiation();
-                switch (firstToken.getType()) {
-                case IToken.t_static:
-                    temp
-                            .setModifier(IGPPASTExplicitTemplateInstantiation.ti_static);
-                    break;
-                case IToken.t_extern:
-                    temp
-                            .setModifier(IGPPASTExplicitTemplateInstantiation.ti_extern);
-                    break;
-                case IToken.t_inline:
-                    temp
-                            .setModifier(IGPPASTExplicitTemplateInstantiation.ti_inline);
-                    break;
-                }
-                templateInstantiation = temp;
-            } else
-                templateInstantiation = createTemplateInstantiation();
-            IASTDeclaration d = declaration();
-            ((ASTNode) templateInstantiation).setOffsetAndLength(firstToken
-                    .getOffset(), calculateEndOffset(d)
-                    - firstToken.getOffset());
-            templateInstantiation.setDeclaration(d);
-            d.setParent(templateInstantiation);
-            d
-                    .setPropertyInParent(ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION);
-            return templateInstantiation;
-        }
-        consume(IToken.tLT);
-        if (LT(1) == IToken.tGT) {
-            // explicit-specialization
-            consume(IToken.tGT);
-
-            ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization();
-            IASTDeclaration d = declaration();
-            ((ASTNode) templateSpecialization).setOffsetAndLength(firstToken
-                    .getOffset(), calculateEndOffset(d)
-                    - firstToken.getOffset());
-            templateSpecialization.setDeclaration(d);
-            d.setParent(templateSpecialization);
-            d
-                    .setPropertyInParent(ICPPASTTemplateSpecialization.OWNED_DECLARATION);
-            return templateSpecialization;
-        }
-
-        try {
-            List parms = templateParameterList();
-            consume(IToken.tGT);
-            IASTDeclaration d = declaration();
-            ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration();
-            ((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(),
-                    calculateEndOffset(d) - firstToken.getOffset());
-            templateDecl.setExported(exported);
-            templateDecl.setDeclaration(d);
-            d.setParent(templateDecl);
-            d.setPropertyInParent(ICPPASTTemplateDeclaration.OWNED_DECLARATION);
-            for (int i = 0; i < parms.size(); ++i) {
-                ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms
-                        .get(i);
-                templateDecl.addTemplateParamter(parm);
-                parm.setParent(templateDecl);
-                parm.setPropertyInParent(ICPPASTTemplateDeclaration.PARAMETER);
-            }
-
-            return templateDecl;
-        } catch (BacktrackException bt) {
-            backup(mark);
-            throw bt;
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTemplateDeclaration createTemplateDeclaration() {
-        return new CPPASTTemplateDeclaration();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTemplateSpecialization createTemplateSpecialization() {
-        return new CPPASTTemplateSpecialization();
-    }
-
-    /**
-     * @return
-     */
-    protected IGPPASTExplicitTemplateInstantiation createGnuTemplateInstantiation() {
-        return new GPPASTExplicitTemplateInstantiation();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTExplicitTemplateInstantiation createTemplateInstantiation() {
-        return new CPPASTExplicitTemplateInstantiation();
-    }
-
-    /**
-     * 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() 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(DEFAULT_PARM_LIST_SIZE);
-
-        for (;;) {
-            if (LT(1) == IToken.tGT)
-                return returnValue;
-            if (LT(1) == IToken.t_class || LT(1) == IToken.t_typename) {
-                IToken startingToken = LA(1);
-                int lastOffset = 0;
-                int type = (LT(1) == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class
-                        : ICPPASTSimpleTypeTemplateParameter.st_typename);
-                lastOffset = consume().getEndOffset();
-                IASTName identifierName = null;
-                IASTTypeId typeId = null;
-
-                if (LT(1) == IToken.tIDENTIFIER) // optional identifier
-                {
-                    identifierName = createName(identifier());
-                    lastOffset = calculateEndOffset(identifierName);
-                    if (LT(1) == IToken.tASSIGN) // optional = type-id
-                    {
-                        consume(IToken.tASSIGN);
-                        typeId = typeId(false, false); // type-id
-                        lastOffset = calculateEndOffset(typeId);
-                    }
-                } else {
-                    identifierName = createName();
-                }
-
-                ICPPASTSimpleTypeTemplateParameter parm = createSimpleTemplateParameter();
-                ((ASTNode) parm).setOffsetAndLength(startingToken.getOffset(),
-                        lastOffset - startingToken.getOffset());
-                parm.setParameterType(type);
-                parm.setName(identifierName);
-                identifierName.setParent(parm);
-                identifierName
-                        .setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME);
-                if (typeId != null) {
-                    parm.setDefaultType(typeId);
-                    typeId.setParent(parm);
-                    typeId
-                            .setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.DEFAULT_TYPE);
-                }
-                returnValue.add(parm);
-
-            } else if (LT(1) == IToken.t_template) {
-                IToken firstToken = consume(IToken.t_template);
-                consume(IToken.tLT);
-
-                List subResult = templateParameterList();
-                consume(IToken.tGT);
-                int last = consume(IToken.t_class).getEndOffset();
-                IASTName identifierName = null;
-                IASTExpression optionalExpression = null;
-
-                if (LT(1) == IToken.tIDENTIFIER) // optional identifier
-                {
-                    identifierName = createName(identifier());
-                    last = calculateEndOffset(identifierName);
-                    if (LT(1) == IToken.tASSIGN) // optional = type-id
-                    {
-                        consume(IToken.tASSIGN);
-                        optionalExpression = primaryExpression();
-                        last = calculateEndOffset(optionalExpression);
-                    }
-                } else
-                    identifierName = createName();
-
-                ICPPASTTemplatedTypeTemplateParameter parm = createTemplatedTemplateParameter();
-                ((ASTNode) parm).setOffsetAndLength(firstToken.getOffset(),
-                        last - firstToken.getOffset());
-                parm.setName(identifierName);
-                identifierName.setParent(parm);
-                identifierName
-                        .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME);
-                if (optionalExpression != null) {
-                    parm.setDefaultValue(optionalExpression);
-                    optionalExpression.setParent(parm);
-                    optionalExpression
-                            .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.DEFAULT_VALUE);
-                }
-
-                for (int i = 0; i < subResult.size(); ++i) {
-                    ICPPASTTemplateParameter p = (ICPPASTTemplateParameter) subResult
-                            .get(i);
-                    parm.addTemplateParamter(p);
-                    p.setParent(parm);
-                    p
-                            .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER);
-                }
-                returnValue.add(parm);
-
-            } else if (LT(1) == IToken.tCOMMA) {
-                consume(IToken.tCOMMA);
-                continue;
-            } else {
-                ICPPASTParameterDeclaration parm = parameterDeclaration();
-                returnValue.add(parm);
-            }
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTemplatedTypeTemplateParameter createTemplatedTemplateParameter() {
-        return new CPPASTTemplatedTypeTemplateParameter();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTSimpleTypeTemplateParameter createSimpleTemplateParameter() {
-        return new CPPASTSimpleTypeTemplateParameter();
-    }
-
-    /**
-     * 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 IASTDeclaration declaration() throws EndOfFileException,
-            BacktrackException {
-        switch (LT(1)) {
-        case IToken.t_asm:
-            return asmDeclaration();
-        case IToken.t_namespace:
-            return namespaceDefinitionOrAlias();
-        case IToken.t_using:
-            return usingClause();
-        case IToken.t_export:
-        case IToken.t_template:
-            return templateDeclaration();
-        case IToken.t_extern:
-            if (LT(2) == IToken.tSTRING)
-                return linkageSpecification();
-        default:
-            if (supportExtendedTemplateSyntax
-                    && (LT(1) == IToken.t_static || LT(1) == IToken.t_inline || LT(1) == IToken.t_extern)
-                    && LT(2) == IToken.t_template)
-                return templateDeclaration();
-            return simpleDeclarationStrategyUnion();
-        }
-    }
-
-    protected IASTDeclaration simpleDeclarationStrategyUnion()
-            throws EndOfFileException, BacktrackException {
-        simpleDeclarationMark = mark();
-        IASTProblem firstFailure = null;
-        IASTProblem secondFailure = null;
-        try {
-            IASTDeclaration d = simpleDeclaration(
-                    SimpleDeclarationStrategy.TRY_CONSTRUCTOR, false);
-            throwAwayMarksForInitializerClause();
-            return d;
-        } catch (BacktrackException bt) {
-            if (simpleDeclarationMark == null)
-                throwBacktrack(bt);
-            firstFailure = bt.getProblem();
-            // did not work
-            backup(simpleDeclarationMark);
-
-            try {
-                IASTDeclaration d = simpleDeclaration(
-                        SimpleDeclarationStrategy.TRY_FUNCTION, false);
-                throwAwayMarksForInitializerClause();
-                return d;
-            } catch (BacktrackException bt2) {
-                if (simpleDeclarationMark == null) {
-                    if (firstFailure != null && (bt2.getProblem() == null))
-                        throwBacktrack(firstFailure);
-                    else
-                        throwBacktrack(bt2);
-                }
-
-                secondFailure = bt2.getProblem();
-                backup(simpleDeclarationMark);
-                throwAwayMarksForInitializerClause();
-                try {
-                    return simpleDeclaration(
-                            SimpleDeclarationStrategy.TRY_VARIABLE, false);
-                } catch (BacktrackException b3) {
-                    backup(simpleDeclarationMark); // TODO - necessary?
-
-                    if (firstFailure != null)
-                        throwBacktrack(firstFailure);
-                    else if (secondFailure != null)
-                        throwBacktrack(secondFailure);
-                    else
-                        throwBacktrack(b3);
-                    return null;
-                }
-            }
-
-        }
-    }
-
-    /**
-     * 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.
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected IASTDeclaration namespaceDefinitionOrAlias()
-            throws BacktrackException, EndOfFileException {
-
-        IToken first = consume(IToken.t_namespace);
-        int last = first.getEndOffset();
-        IASTName name = null;
-        // optional name
-        if (LT(1) == IToken.tIDENTIFIER) {
-            name = createName(identifier());
-            last = calculateEndOffset(name);
-        } else
-            name = createName();
-
-        if (LT(1) == IToken.tLBRACE) {
-            consume();
-            ICPPASTNamespaceDefinition namespaceDefinition = createNamespaceDefinition();
-            ((ASTNode) namespaceDefinition).setOffset(first.getOffset());
-            namespaceDefinition.setName(name);
-            name.setParent(namespaceDefinition);
-            name.setPropertyInParent(ICPPASTNamespaceDefinition.NAMESPACE_NAME);
-
-            IASTNode n = mostRelevantScopeNode;
-            mostRelevantScopeNode = namespaceDefinition;
-            namespaceDefinition.setParent(n);
-
-            try {
-                namespaceDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
-                    int checkToken = LA(1).hashCode();
-                    switch (LT(1)) {
-                    case IToken.tRBRACE:
-                        break namespaceDeclarationLoop;
-                    default:
-                        try {
-                            IASTDeclaration d = declaration();
-                            d.setParent(namespaceDefinition);
-                            d
-                                    .setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION);
-                            namespaceDefinition.addDeclaration(d);
-                        } catch (BacktrackException bt) {
-                            IASTProblem p = failParse(bt);
-                            IASTProblemDeclaration pd = createProblemDeclaration();
-                            p.setParent(pd);
-                            pd.setProblem(p);
-                            ((CPPASTNode) pd)
-                                    .setOffsetAndLength((CPPASTNode) p);
-                            p.setPropertyInParent(IASTProblemHolder.PROBLEM);
-                            namespaceDefinition.addDeclaration(pd);
-                            pd.setParent(namespaceDefinition);
-                            pd
-                                    .setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION);
-                            errorHandling();
-                            if (checkToken == LA(1).hashCode())
-                                errorHandling();
-                        }
-                    }
-                    if (checkToken == LA(1).hashCode())
-                        failParseWithErrorHandling();
-                }
-            } finally {
-                mostRelevantScopeNode = n;
-            }
-            // consume the }
-            int end = consume(IToken.tRBRACE).getEndOffset();
-            ((CPPASTNode) namespaceDefinition).setLength(end
-                    - first.getOffset());
-            return namespaceDefinition;
-        } else if (LT(1) == IToken.tASSIGN) {
-            IToken assign = consume(IToken.tASSIGN);
-
-            if (name.toString() == null) {
-                throwBacktrack(first.getOffset(), assign.getEndOffset()
-                        - first.getOffset());
-                return null;
-            }
-
-            ITokenDuple duple = name();
-            IASTName qualifiedName = createName(duple);
-            int end = consume(IToken.tSEMI).getEndOffset();
-
-            ICPPASTNamespaceAlias alias = createNamespaceAlias();
-            ((ASTNode) alias).setOffsetAndLength(first.getOffset(), end
-                    - first.getOffset());
-            alias.setAlias(name);
-            name.setParent(alias);
-            name.setPropertyInParent(ICPPASTNamespaceAlias.ALIAS_NAME);
-            alias.setMappingName(qualifiedName);
-            qualifiedName.setParent(alias);
-            qualifiedName
-                    .setPropertyInParent(ICPPASTNamespaceAlias.MAPPING_NAME);
-            return alias;
-        } else {
-            throwBacktrack(first.getOffset(), last - first.getOffset());
-            return null;
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTNamespaceAlias createNamespaceAlias() {
-        return new CPPASTNamespaceAlias();
-    }
-
-    /**
-     * @param duple
-     * @return
-     */
-    protected ICPPASTQualifiedName createQualifiedName(ITokenDuple duple) {
-        CPPASTQualifiedName result = new CPPASTQualifiedName();
-        result.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
-                - duple.getStartOffset());
-        result.setValue(duple.toString());
-        ITokenDuple[] segments = duple.getSegments();
-        int startingValue = 0;
-        if (segments.length > 0 && segments[0] instanceof IToken
-                && ((IToken) segments[0]).getType() == IToken.tCOLONCOLON) {
-            ++startingValue;
-            result.setFullyQualified(true);
-        }
-        for (int i = startingValue; i < segments.length; ++i) {
-            IASTName subName = null;
-            // take each name and add it to the result
-            if (segments[i] instanceof IToken) {
-                subName = createName((IToken) segments[i]);
-            } else if (segments[i].getTemplateIdArgLists() == null)
-                subName = createName(segments[i]);
-            else
-                // templateID
-                subName = createTemplateID(segments[i]);
-
-            if (i == segments.length - 1 && duple instanceof OperatorTokenDuple) { // make
-                                                                                    // sure
-                                                                                    // the
-                                                                                    // last
-                                                                                    // segment
-                                                                                    // is
-                                                                                    // an
-                                                                                    // OperatorName/ConversionName
-                subName = createOperatorName((OperatorTokenDuple) duple,
-                        subName);
-            }
-
-            subName.setParent(result);
-            subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME);
-            ((ASTNode) subName).setOffsetAndLength(
-                    segments[i].getStartOffset(), segments[i].getEndOffset()
-                            - segments[i].getStartOffset());
-            result.addName(subName);
-        }
-        return result;
-    }
-
-    /**
-     * @param duple
-     * @return
-     */
-    protected ICPPASTTemplateId createTemplateID(ITokenDuple duple) {
-        ICPPASTTemplateId result = new CPPASTTemplateId();
-        ((ASTNode) result).setOffsetAndLength(duple.getStartOffset(), duple
-                .getEndOffset()
-                - duple.getStartOffset());
-        char[] image = duple.extractNameFromTemplateId();
-        CPPASTName templateIdName = (CPPASTName) createName();
-        templateIdName.setOffsetAndLength(duple.getStartOffset(), image.length);
-        templateIdName.setName(image);
-        result.setTemplateName(templateIdName);
-        templateIdName.setParent(result);
-        templateIdName.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_NAME);
-        if (duple.getTemplateIdArgLists() != null) {
-            List args = duple.getTemplateIdArgLists()[0];
-            if (args != null)
-                for (int i = 0; i < args.size(); ++i) {
-                    IASTNode n = (IASTNode) args.get(i);
-                    if (n instanceof IASTTypeId || n instanceof IASTExpression) {
-                        n.setParent(result);
-                        n
-                                .setPropertyInParent(ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT);
-                        if (n instanceof IASTTypeId)
-                            result.addTemplateArgument((IASTTypeId) n);
-                        else
-                            result.addTemplateArgument((IASTExpression) n);
-                    }
-                }
-        }
-        return result;
-    }
-
-    /**
-     * @param duple
-     * @return
-     */
-    protected IASTName createName(ITokenDuple duple) {
-        if (duple == null)
-            return createName();
-        if (duple.getSegmentCount() != 1)
-            return createQualifiedName(duple);
-        if (duple.getTemplateIdArgLists() != null)
-            return createTemplateID(duple);
-
-        // We're a single name
-        IASTName name = new CPPASTName(duple.toCharArray());
-        if (duple instanceof OperatorTokenDuple) {
-            name = createOperatorName((OperatorTokenDuple) duple, name);
-        }
-
-        IToken token = duple.getFirstToken();
-        switch (token.getType()) {
-        case IToken.tCOMPLETION:
-        case IToken.tEOC:
-            createCompletionNode(token).addName(name);
-            break;
-        }
-
-        ((ASTNode) name).setOffsetAndLength(duple.getStartOffset(), duple
-                .getEndOffset()
-                - duple.getStartOffset());
-
-        return name;
-    }
-
-    protected IASTName createOperatorName(OperatorTokenDuple duple,
-            IASTName name) {
-        IASTName aName = null;
-
-        if (duple.isConversionOperator()) {
-            aName = new CPPASTConversionName(name.toCharArray());
-            IASTTypeId typeId = duple.getTypeId();
-            typeId.setParent(aName);
-            typeId.setPropertyInParent(ICPPASTConversionName.TYPE_ID);
-            ((CPPASTConversionName) aName).setTypeId(typeId);
-        } else {
-            aName = new CPPASTOperatorName(name.toCharArray());
-        }
-
-        if (name instanceof ICPPASTTemplateId) {
-            ((ICPPASTTemplateId) name).setTemplateName(aName);
-            return name;
-        }
-
-        return aName;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTNamespaceDefinition createNamespaceDefinition() {
-        return new CPPASTNamespaceDefinition();
-    }
-
-    /**
-     * 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)
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected IASTDeclaration simpleDeclaration(
-            SimpleDeclarationStrategy strategy, boolean fromCatchHandler)
-            throws BacktrackException, EndOfFileException {
-        IToken firstToken = LA(1);
-        int firstOffset = firstToken.getOffset();
-        if (firstToken.getType() == IToken.tLBRACE)
-            throwBacktrack(firstOffset, firstToken.getLength());
-        firstToken = null; // necessary for scalability
-
-        ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false,
-                strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR);
-        IASTDeclarator[] declarators = new IASTDeclarator[2];
-        if (LT(1) != IToken.tSEMI && LT(1) != IToken.tEOC) {
-            declarators = (IASTDeclarator[]) ArrayUtil
-                    .append(IASTDeclarator.class, declarators,
-                            initDeclarator(strategy));
-            while (LT(1) == IToken.tCOMMA) {
-                consume(IToken.tCOMMA);
-                declarators = (IASTDeclarator[]) ArrayUtil.append(
-                        IASTDeclarator.class, declarators,
-                        initDeclarator(strategy));
-            }
-        }
-
-        declarators = (IASTDeclarator[]) ArrayUtil.removeNulls(
-                IASTDeclarator.class, declarators);
-
-        boolean hasFunctionBody = false;
-        boolean hasFunctionTryBlock = false;
-        boolean consumedSemi = false;
-        int semiOffset = 0;
-        List constructorChain = Collections.EMPTY_LIST;
-
-        switch (LT(1)) {
-        case IToken.tSEMI:
-            semiOffset = consume(IToken.tSEMI).getEndOffset();
-            consumedSemi = true;
-            break;
-        case IToken.t_try:
-            consume(IToken.t_try);
-            if (LT(1) == IToken.tCOLON) {
-                constructorChain = new ArrayList(
-                        DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
-                ctorInitializer(constructorChain);
-            }
-            hasFunctionTryBlock = true;
-            break;
-        case IToken.tCOLON:
-            constructorChain = new ArrayList(
-                    DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
-            ctorInitializer(constructorChain);
-            break;
-        case IToken.tLBRACE:
-            break;
-        case IToken.tRPAREN:
-            if (!fromCatchHandler)
-                throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-            break;
-        case IToken.tEOC:
-            // Pretend we consumed the semi
-            consumedSemi = true;
-            break;
-        default:
-            throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-        }
-
-        if (!consumedSemi) {
-            if (LT(1) == IToken.tLBRACE) {
-                hasFunctionBody = true;
-            }
-
-            if (hasFunctionTryBlock && !hasFunctionBody)
-                throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-        }
-
-        if (hasFunctionBody) {
-            if (declarators.length != 1)
-                throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-
-            IASTDeclarator declarator = declarators[0];
-            if (!(declarator instanceof IASTStandardFunctionDeclarator))
-                throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-
-            if (!constructorChain.isEmpty()
-                    && declarator instanceof ICPPASTFunctionDeclarator) {
-                ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator;
-
-                int size = constructorChain.size();
-                for (int i = 0; i < size; ++i) {
-                    ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) constructorChain
-                            .get(i);
-                    fd.addConstructorToChain(initializer);
-                    initializer.setParent(fd);
-                    initializer
-                            .setPropertyInParent(ICPPASTFunctionDeclarator.CONSTRUCTOR_CHAIN_MEMBER);
-                }
-
-                // fix for 86698, now that the constructorChain is established,
-                // update the declarator's length
-                if (fd instanceof ASTNode
-                        && constructorChain.get(size - 1) instanceof ASTNode) {
-                    ASTNode init = (ASTNode) constructorChain.get(size - 1);
-                    ((ASTNode) fd).setLength(init.getOffset()
-                            + init.getLength() - ((ASTNode) fd).getOffset());
-                }
-            }
-
-            IASTFunctionDefinition funcDefinition = createFunctionDefinition();
-            ((ASTNode) funcDefinition).setOffset(firstOffset);
-            funcDefinition.setDeclSpecifier(declSpec);
-            declSpec.setParent(funcDefinition);
-            declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER);
-
-            funcDefinition
-                    .setDeclarator((IASTStandardFunctionDeclarator) declarator);
-            declarator.setParent(funcDefinition);
-            declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR);
-
-            IASTStatement s = handleFunctionBody();
-            if (s != null) {
-                funcDefinition.setBody(s);
-                s.setParent(funcDefinition);
-                s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY);
-            }
-            ((CPPASTNode) funcDefinition).setLength(calculateEndOffset(s)
-                    - firstOffset);
-
-            if (hasFunctionTryBlock
-                    && declarator instanceof ICPPASTFunctionTryBlockDeclarator) {
-                List handlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE);
-                catchHandlerSequence(handlers);
-                for (int i = 0; i < handlers.size(); ++i) {
-                    ICPPASTCatchHandler handler = (ICPPASTCatchHandler) handlers
-                            .get(i);
-                    ((ICPPASTFunctionTryBlockDeclarator) declarator)
-                            .addCatchHandler(handler);
-                    handler.setParent(declarator);
-                    handler
-                            .setPropertyInParent(ICPPASTFunctionTryBlockDeclarator.CATCH_HANDLER);
-                    ((CPPASTNode) funcDefinition)
-                            .setLength(calculateEndOffset(handler)
-                                    - firstOffset);
-
-                }
-
-            }
-            return funcDefinition;
-        }
-
-        IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration();
-        int length = figureEndOffset(declSpec, declarators) - firstOffset;
-        if (consumedSemi)
-            length = semiOffset - firstOffset;
-
-        ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, length);
-        simpleDeclaration.setDeclSpecifier(declSpec);
-        declSpec.setParent(simpleDeclaration);
-        declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER);
-
-        for (int i = 0; i < declarators.length; ++i) {
-            IASTDeclarator declarator = declarators[i];
-            simpleDeclaration.addDeclarator(declarator);
-            declarator.setParent(simpleDeclaration);
-            declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR);
-        }
-        return simpleDeclaration;
-    }
-
-    /**
-     * @return
-     */
-    protected IASTFunctionDefinition createFunctionDefinition() {
-        return new CPPASTFunctionDefinition();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTSimpleDeclaration createSimpleDeclaration() {
-        return new CPPASTSimpleDeclaration();
-    }
-
-    /**
-     * 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(List collection) throws EndOfFileException,
-            BacktrackException {
-        consume(IToken.tCOLON);
-        for (;;) {
-            if (LT(1) == IToken.tLBRACE)
-                break;
-            ITokenDuple duple = name();
-            IASTName name = createName(duple);
-
-            consume(IToken.tLPAREN);
-            IASTExpression expressionList = null;
-
-            if (LT(1) != IToken.tRPAREN)
-                expressionList = expression();
-
-            int end = consume(IToken.tRPAREN).getEndOffset();
-            ICPPASTConstructorChainInitializer ctorInitializer = createConstructorChainInitializer();
-            ((ASTNode) ctorInitializer).setOffsetAndLength(duple
-                    .getStartOffset(), end - duple.getStartOffset());
-            ctorInitializer.setMemberInitializerId(name);
-            name.setParent(ctorInitializer);
-            name
-                    .setPropertyInParent(ICPPASTConstructorChainInitializer.MEMBER_ID);
-
-            if (expressionList != null) {
-                ctorInitializer.setInitializerValue(expressionList);
-                expressionList.setParent(ctorInitializer);
-                expressionList
-                        .setPropertyInParent(ICPPASTConstructorChainInitializer.INITIALIZER);
-            }
-            collection.add(ctorInitializer);
-            if (LT(1) == IToken.tLBRACE)
-                break;
-            consume(IToken.tCOMMA);
-        }
-
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTConstructorChainInitializer createConstructorChainInitializer() {
-        return new CPPASTConstructorChainInitializer();
-    }
-
-    /**
-     * This routine parses a parameter declaration
-     * 
-     * @param containerObject
-     *            The IParserCallback object representing the
-     *            parameterDeclarationClause owning the parm.
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected ICPPASTParameterDeclaration parameterDeclaration()
-            throws BacktrackException, EndOfFileException {
-        IToken current = LA(1);
-        IASTDeclSpecifier declSpec = declSpecifierSeq(true, false);
-        IASTDeclarator declarator = null;
-        if (LT(1) != IToken.tSEMI)
-            declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
-
-        if (current == LA(1)) {
-            throwBacktrack(current.getOffset(), figureEndOffset(declSpec,
-                    declarator)
-                    - current.getOffset());
-        }
-        ICPPASTParameterDeclaration parm = createParameterDeclaration();
-        ((ASTNode) parm).setOffsetAndLength(current.getOffset(),
-                figureEndOffset(declSpec, declarator) - current.getOffset());
-        parm.setDeclSpecifier(declSpec);
-        declSpec.setParent(parm);
-        declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER);
-        if (declarator != null) {
-            parm.setDeclarator(declarator);
-            declarator.setParent(parm);
-            declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR);
-        }
-        return parm;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTParameterDeclaration createParameterDeclaration() {
-        return new CPPASTParameterDeclaration();
-    }
-
-    /**
-     * @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
-     */
-    protected boolean lookAheadForConstructorOrOperator(Flags flags)
-            throws EndOfFileException {
-        if (flags.isForParameterDeclaration())
-            return false;
-        if (LT(2) == IToken.tLPAREN && flags.isForConstructor())
-            return true;
-
-        IToken mark = mark();
-        IASTName name = null;
-        try {
-            name = consumeTemplatedOperatorName();
-        } catch (BacktrackException e) {
-            backup(mark);
-            return false;
-        } catch (EndOfFileException eof) {
-            backup(mark);
-            return false;
-        }
-
-        if (name == null) {
-            backup(mark);
-            return false;
-        }
-
-        // constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be
-        // defined for the global scope)
-        if (name instanceof ICPPASTQualifiedName) {
-            IASTName[] segments = ((ICPPASTQualifiedName) name).getNames();
-
-            int len = segments.length;
-            if (len >= 2) {
-                if (segments[0].toString().length() == 0) {
-                    backup(mark);
-                    return false;
-                }
-
-                if (((ICPPASTQualifiedName) name).isConversionOrOperator()) { // conversion
-                                                                                // or
-                                                                                // operator
-                    backup(mark);
-                    return true;
-                }
-
-                if (segments[len - 1].toString().equals(
-                        segments[len - 2].toString())) { // constructor
-                    backup(mark);
-                    return true;
-                }
-
-                StringBuffer destructorName = new StringBuffer();
-                destructorName.append(COMPL);
-                destructorName.append(segments[len - 2]);
-                if (segments[len - 1].toString().equals(
-                        destructorName.toString())) { // destructor
-                    backup(mark);
-                    return true;
-                }
-            } else {
-                backup(mark);
-                return false;
-            }
-        } else {
-            backup(mark);
-            return false;
-        }
-
-        backup(mark);
-        return false;
-    }
-
-    /**
-     * 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 parm
-     *            Is this for a parameter declaration (true) or simple
-     *            declaration (false)
-     * @param tryConstructor
-     *            true for constructor, false for pointer to function strategy
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm,
-            boolean tryConstructor) throws BacktrackException,
-            EndOfFileException {
-        IToken firstToken = LA(1);
-        Flags flags = new Flags(parm, tryConstructor);
-        IToken last = null;
-
-        boolean isInline = false, isVirtual = false, isExplicit = false, isFriend = false;
-        boolean isConst = false, isVolatile = false, isRestrict = false;
-        boolean isLong = false, isShort = false, isUnsigned = false, isSigned = false, isLongLong = false;
-        boolean isTypename = false;
-
-        int storageClass = IASTDeclSpecifier.sc_unspecified;
-        int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
-        ITokenDuple duple = null;
-
-        ICPPASTCompositeTypeSpecifier classSpec = null;
-        ICPPASTElaboratedTypeSpecifier elabSpec = null;
-        IASTEnumerationSpecifier enumSpec = null;
-        IASTExpression typeofExpression = null;
-        int startOffset = firstToken.getOffset();
-
-        declSpecifiers: for (;;) {
-            switch (LT(1)) {
-            case IToken.t_inline:
-                last = consume();
-                isInline = true;
-                break;
-            case IToken.t_typedef:
-                storageClass = IASTDeclSpecifier.sc_typedef;
-                last = consume();
-                break;
-            case IToken.t_auto:
-                last = consume();
-                storageClass = IASTDeclSpecifier.sc_auto;
-                break;
-            case IToken.t_register:
-                last = consume();
-                storageClass = IASTDeclSpecifier.sc_register;
-                break;
-            case IToken.t_static:
-                storageClass = IASTDeclSpecifier.sc_static;
-                last = consume();
-                break;
-            case IToken.t_extern:
-                storageClass = IASTDeclSpecifier.sc_extern;
-                last = consume();
-                break;
-            case IToken.t_mutable:
-                storageClass = ICPPASTDeclSpecifier.sc_mutable;
-                last = consume();
-                break;
-            case IToken.t_virtual:
-                isVirtual = true;
-                last = consume();
-                break;
-            case IToken.t_explicit:
-                isExplicit = true;
-                last = consume();
-                break;
-            case IToken.t_friend:
-                isFriend = true;
-                last = consume();
-                break;
-            case IToken.t_const:
-                isConst = true;
-                last = consume();
-                break;
-            case IToken.t_volatile:
-                isVolatile = true;
-                last = consume();
-                break;
-            case IToken.t_restrict:
-                if (!supportRestrict) {
-                    IToken la = LA(1);
-                    throwBacktrack(la.getOffset(), la.getEndOffset()
-                            - la.getOffset());
-                }
-                isRestrict = true;
-                last = consume();
-                break;
-            case IToken.t_signed:
-                isSigned = true;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_unsigned:
-                isUnsigned = true;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_short:
-                isShort = true;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_long:
-                if (isLong && supportLongLong) {
-                    isLong = false;
-                    isLongLong = true;
-                } else
-                    isLong = true;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t__Complex:
-                if (!supportComplex) {
-                    IToken la = LA(1);
-                    throwBacktrack(la.getOffset(), la.getEndOffset()
-                            - la.getOffset());
-                }
-                last = consume(IToken.t__Complex);
-                simpleType = IGPPASTSimpleDeclSpecifier.t_Complex;
-                break;
-            case IToken.t__Imaginary:
-                if (!supportComplex) {
-                    IToken la = LA(1);
-                    throwBacktrack(la.getOffset(), la.getLength());
-                }
-                last = consume(IToken.t__Imaginary);
-                simpleType = IGPPASTSimpleDeclSpecifier.t_Imaginary;
-                break;
-            case IToken.t_char:
-                simpleType = IASTSimpleDeclSpecifier.t_char;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_wchar_t:
-                simpleType = ICPPASTSimpleDeclSpecifier.t_wchar_t;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_bool:
-                simpleType = ICPPASTSimpleDeclSpecifier.t_bool;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_int:
-                flags.setEncounteredRawType(true);
-                last = consume();
-                simpleType = IASTSimpleDeclSpecifier.t_int;
-                break;
-            case IToken.t_float:
-                simpleType = IASTSimpleDeclSpecifier.t_float;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_double:
-                simpleType = IASTSimpleDeclSpecifier.t_double;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_void:
-                simpleType = IASTSimpleDeclSpecifier.t_void;
-                flags.setEncounteredRawType(true);
-                last = consume();
-                break;
-            case IToken.t_typename:
-                isTypename = true;
-                last = consume(IToken.t_typename);
-                duple = name();
-                flags.setEncounteredTypename(true);
-                break;
-            case IToken.tCOLONCOLON:
-            case IToken.tIDENTIFIER:
-                // TODO - Kludgy way to handle constructors/destructors
-                if (flags.haveEncounteredRawType())
-                    break declSpecifiers;
-
-                if (parm && flags.haveEncounteredTypename())
-                    break declSpecifiers;
-
-                if (lookAheadForConstructorOrOperator(flags))
-                    break declSpecifiers;
-
-                if (lookAheadForDeclarator(flags))
-                    break declSpecifiers;
-
-                duple = name();
-                last = duple.getLastToken();
-                flags.setEncounteredTypename(true);
-                break;
-            case IToken.t_class:
-            case IToken.t_struct:
-            case IToken.t_union:
-                if (flags.haveEncounteredTypename())
-                    throwBacktrack(LA(1));
-                try {
-                    classSpec = classSpecifier();
-                    flags.setEncounteredTypename(true);
-                    break;
-                } catch (BacktrackException bt) {
-                    elabSpec = elaboratedTypeSpecifier();
-                    flags.setEncounteredTypename(true);
-                    break;
-                }
-            case IToken.t_enum:
-                if (flags.haveEncounteredTypename())
-                    throwBacktrack(LA(1));
-                try {
-                    enumSpec = enumSpecifier();
-                    flags.setEncounteredTypename(true);
-                    break;
-                } catch (BacktrackException bt) {
-                    // this is an elaborated class specifier
-                    elabSpec = elaboratedTypeSpecifier();
-                    flags.setEncounteredTypename(true);
-                    break;
-                }
-            default:
-                if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
-                    typeofExpression = unaryTypeofExpression();
-                    if (typeofExpression != null) {
-                        flags.setEncounteredTypename(true);
-                    }
-                }
-                break declSpecifiers;
-            }
-        }
-
-        if (elabSpec != null) {
-            elabSpec.setConst(isConst);
-            elabSpec.setVolatile(isVolatile);
-            if (elabSpec instanceof IGPPASTDeclSpecifier)
-                ((IGPPASTDeclSpecifier) elabSpec).setRestrict(isRestrict);
-            elabSpec.setFriend(isFriend);
-            elabSpec.setInline(isInline);
-            elabSpec.setStorageClass(storageClass);
-            elabSpec.setVirtual(isVirtual);
-            elabSpec.setExplicit(isExplicit);
-            ((CPPASTNode) elabSpec).setOffsetAndLength(startOffset,
-                    calculateEndOffset(elabSpec) - startOffset);
-            return elabSpec;
-        }
-        if (enumSpec != null) {
-            enumSpec.setConst(isConst);
-            enumSpec.setVolatile(isVolatile);
-            if (enumSpec instanceof IGPPASTDeclSpecifier)
-                ((IGPPASTDeclSpecifier) enumSpec).setRestrict(isRestrict);
-            ((ICPPASTDeclSpecifier) enumSpec).setFriend(isFriend);
-            ((ICPPASTDeclSpecifier) enumSpec).setVirtual(isVirtual);
-            ((ICPPASTDeclSpecifier) enumSpec).setExplicit(isExplicit);
-            enumSpec.setInline(isInline);
-            enumSpec.setStorageClass(storageClass);
-            ((CPPASTNode) enumSpec).setOffsetAndLength(startOffset,
-                    calculateEndOffset(enumSpec) - startOffset);
-            return (ICPPASTDeclSpecifier) enumSpec;
-        }
-        if (classSpec != null) {
-            classSpec.setConst(isConst);
-            classSpec.setVolatile(isVolatile);
-            if (classSpec instanceof IGPPASTDeclSpecifier)
-                ((IGPPASTDeclSpecifier) classSpec).setRestrict(isRestrict);
-            classSpec.setFriend(isFriend);
-            classSpec.setInline(isInline);
-            classSpec.setStorageClass(storageClass);
-            classSpec.setVirtual(isVirtual);
-            classSpec.setExplicit(isExplicit);
-            ((CPPASTNode) classSpec).setOffsetAndLength(startOffset,
-                    calculateEndOffset(classSpec) - startOffset);
-            return classSpec;
-        }
-        if (duple != null) {
-            ICPPASTNamedTypeSpecifier nameSpec = (ICPPASTNamedTypeSpecifier) createNamedTypeSpecifier();
-            nameSpec.setIsTypename(isTypename);
-            IASTName name = createName(duple);
-            nameSpec.setName(name);
-            name.setParent(nameSpec);
-            name.setPropertyInParent(IASTNamedTypeSpecifier.NAME);
-
-            nameSpec.setConst(isConst);
-            nameSpec.setVolatile(isVolatile);
-            if (nameSpec instanceof IGPPASTDeclSpecifier)
-                ((IGPPASTDeclSpecifier) nameSpec).setRestrict(isRestrict);
-            nameSpec.setFriend(isFriend);
-            nameSpec.setInline(isInline);
-            nameSpec.setStorageClass(storageClass);
-            nameSpec.setVirtual(isVirtual);
-            nameSpec.setExplicit(isExplicit);
-            ((CPPASTNode) nameSpec).setOffsetAndLength(startOffset, last
-                    .getEndOffset()
-                    - startOffset);
-            return nameSpec;
-        }
-        ICPPASTSimpleDeclSpecifier simpleDeclSpec = null;
-        if (isLongLong || typeofExpression != null) {
-            simpleDeclSpec = createGPPSimpleDeclSpecifier();
-            ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec)
-                    .setLongLong(isLongLong);
-            if (typeofExpression != null) {
-                ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec)
-                        .setTypeofExpression(typeofExpression);
-                typeofExpression.setParent(simpleDeclSpec);
-                typeofExpression
-                        .setPropertyInParent(IGPPASTSimpleDeclSpecifier.TYPEOF_EXPRESSION);
-            }
-        } else
-            simpleDeclSpec = createSimpleDeclSpecifier();
-
-        int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0;
-        ((ASTNode) simpleDeclSpec)
-                .setOffsetAndLength(firstToken.getOffset(), l);
-        simpleDeclSpec.setConst(isConst);
-        simpleDeclSpec.setVolatile(isVolatile);
-        if (simpleDeclSpec instanceof IGPPASTDeclSpecifier)
-            ((IGPPASTDeclSpecifier) simpleDeclSpec).setRestrict(isRestrict);
-
-        simpleDeclSpec.setFriend(isFriend);
-        simpleDeclSpec.setInline(isInline);
-        simpleDeclSpec.setStorageClass(storageClass);
-        simpleDeclSpec.setVirtual(isVirtual);
-        simpleDeclSpec.setExplicit(isExplicit);
-
-        simpleDeclSpec.setType(simpleType);
-        simpleDeclSpec.setLong(isLong);
-        simpleDeclSpec.setShort(isShort);
-        simpleDeclSpec.setUnsigned(isUnsigned);
-        simpleDeclSpec.setSigned(isSigned);
-
-        return simpleDeclSpec;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() {
-        return new GPPASTSimpleDeclSpecifier();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTSimpleDeclSpecifier createSimpleDeclSpecifier() {
-        return new CPPASTSimpleDeclSpecifier();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTNamedTypeSpecifier createNamedTypeSpecifier() {
-        return new CPPASTNamedTypeSpecifier();
-    }
-
-    /**
-     * Parse an elaborated type specifier.
-     * 
-     * @param decl
-     *            Declaration which owns the elaborated type
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier()
-            throws BacktrackException, EndOfFileException {
-        // this is an elaborated class specifier
-        IToken t = consume();
-        int eck = 0;
-
-        switch (t.getType()) {
-        case IToken.t_class:
-            eck = ICPPASTElaboratedTypeSpecifier.k_class;
-            break;
-        case IToken.t_struct:
-            eck = IASTElaboratedTypeSpecifier.k_struct;
-            break;
-        case IToken.t_union:
-            eck = IASTElaboratedTypeSpecifier.k_union;
-            break;
-        case IToken.t_enum:
-            eck = IASTElaboratedTypeSpecifier.k_enum;
-            break;
-        default:
-            backup(t);
-            throwBacktrack(t.getOffset(), t.getLength());
-        }
-
-        IASTName name = createName(name());
-
-        ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = createElaboratedTypeSpecifier();
-        ((ASTNode) elaboratedTypeSpec).setOffsetAndLength(t.getOffset(),
-                calculateEndOffset(name) - t.getOffset());
-        elaboratedTypeSpec.setKind(eck);
-        elaboratedTypeSpec.setName(name);
-        name.setParent(elaboratedTypeSpec);
-        name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME);
-        return elaboratedTypeSpec;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() {
-        return new CPPASTElaboratedTypeSpecifier();
-    }
-
-    /**
-     * Parses the initDeclarator construct of the ANSI C++ spec. initDeclarator :
-     * declarator ("=" initializerClause | "(" expressionList ")")?
-     * 
-     * @param constructInitializers
-     *            TODO
-     * @param owner
-     *            IParserCallback object that represents the owner declaration
-     *            object.
-     * @return declarator that this parsing produced.
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy)
-            throws EndOfFileException, BacktrackException {
-        IASTDeclarator d = declarator(strategy, false, false);
-
-        IASTInitializer initializer = optionalCPPInitializer( d );
-        if (initializer != null) {
-            d.setInitializer(initializer);
-            initializer.setParent(d);
-            initializer.setPropertyInParent(IASTDeclarator.INITIALIZER);
-            ((ASTNode) d).setLength(calculateEndOffset(initializer)
-                    - ((ASTNode) d).getOffset());
-        }
-
-        return d;
-    }
-
-    protected IASTInitializer optionalCPPInitializer( IASTDeclarator d )
-            throws EndOfFileException, BacktrackException {
-        // handle initializer
-
-        if (LT(1) == IToken.tASSIGN) {
-            consume(IToken.tASSIGN);
-            throwAwayMarksForInitializerClause();
-            try {
-                return initializerClause();
-            } catch (EndOfFileException eof) {
-                failParse();
-                throw eof;
-            }
-        } else if (LT(1) == IToken.tLPAREN) {
-            if( d instanceof IASTFunctionDeclarator && d.getNestedDeclarator() == null ){
-                //constructor initializer doesn't make sense for a function declarator, 
-                //we must have an object to initialize, a function doesn't work.
-                return null;
-            }
-            // initializer in constructor
-            int o = consume(IToken.tLPAREN).getOffset(); // EAT IT!
-            IASTExpression astExpression = expression();
-            int l = consume(IToken.tRPAREN).getEndOffset();
-            ICPPASTConstructorInitializer result = createConstructorInitializer();
-            ((ASTNode) result).setOffsetAndLength(o, l - o);
-            result.setExpression(astExpression);
-            astExpression.setParent(result);
-            astExpression
-                    .setPropertyInParent(ICPPASTConstructorInitializer.EXPRESSION);
-            return result;
-        }
-        return null;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTConstructorInitializer createConstructorInitializer() {
-        return new CPPASTConstructorInitializer();
-    }
-
-    /**
-     *  
-     */
-    protected IASTInitializer initializerClause() throws EndOfFileException,
-            BacktrackException {
-        if (LT(1) == IToken.tLBRACE) {
-            int startingOffset = consume(IToken.tLBRACE).getOffset();
-
-            IASTInitializerList result = createInitializerList();
-            ((ASTNode) result).setOffset(startingOffset);
-
-            if (LT(1) == (IToken.tRBRACE)) {
-                int l = consume(IToken.tRBRACE).getEndOffset();
-                ((ASTNode) result).setLength(l - startingOffset);
-                return result;
-            }
-
-            // otherwise it is a list of initializer clauses
-
-            for (;;) {
-                if (LT(1) == IToken.tRBRACE)
-                    break;
-
-                IASTInitializer clause = initializerClause();
-                if (clause != null) {
-                    result.addInitializer(clause);
-                    clause.setParent(result);
-                    clause
-                            .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER);
-                }
-                if (LT(1) == IToken.tRBRACE)
-                    break;
-                consume(IToken.tCOMMA);
-            }
-            int l = consume(IToken.tRBRACE).getEndOffset();
-            ((ASTNode) result).setLength(l - startingOffset);
-            return result;
-        }
-
-        // if we get this far, it means that we did not
-        // try this now instead
-        // assignmentExpression
-        IASTExpression assignmentExpression = assignmentExpression();
-        IASTInitializerExpression result = createInitializerExpression();
-        ((ASTNode) result).setOffsetAndLength(((ASTNode) assignmentExpression));
-        result.setExpression(assignmentExpression);
-        assignmentExpression.setParent(result);
-        assignmentExpression
-                .setPropertyInParent(IASTInitializerExpression.INITIALIZER_EXPRESSION);
-        return result;
-    }
-
-    /**
-     * @return
-     */
-    protected IASTInitializerList createInitializerList() {
-        return new CPPASTInitializerList();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTInitializerExpression createInitializerExpression() {
-        return new CPPASTInitializerExpression();
-    }
-
-    /**
-     * 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 forTypeID
-     *            TODO
-     * @param skipArrayDeclarator
-     *            TODO
-     * @param container
-     *            IParserCallback object that represents the owner declaration.
-     * @return declarator that this parsing produced.
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy,
-            boolean forTypeID, boolean skipArrayDeclarator)
-            throws EndOfFileException, BacktrackException {
-
-        IToken la = LA(1);
-        int startingOffset = la.getOffset();
-        la = null;
-        IASTDeclarator innerDecl = null;
-        IASTName declaratorName = null;
-        List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
-        List parameters = Collections.EMPTY_LIST;
-        List arrayMods = Collections.EMPTY_LIST;
-        List exceptionSpecIds = Collections.EMPTY_LIST;
-        boolean encounteredVarArgs = false;
-        boolean tryEncountered = false;
-        IASTExpression bitField = null;
-        boolean isFunction = false;
-        boolean isPureVirtual = false, isConst = false, isVolatile = false;
-        int finalOffset = startingOffset;
-        overallLoop: do {
-
-            consumePointerOperators(pointerOps);
-            if (!pointerOps.isEmpty())
-                finalOffset = calculateEndOffset((IASTNode) pointerOps
-                        .get(pointerOps.size() - 1));
-
-            if (!forTypeID && LT(1) == IToken.tLPAREN) {
-                IToken mark = mark();
-                try {
-                    consume();
-                    innerDecl = declarator(strategy, forTypeID,
-                            skipArrayDeclarator);
-                    finalOffset = consume(IToken.tRPAREN).getEndOffset();
-                } catch (BacktrackException bte) {
-                    backup(mark);
-                }
-                declaratorName = createName();
-            } else {
-                try {
-                    declaratorName = consumeTemplatedOperatorName();
-                    finalOffset = calculateEndOffset(declaratorName);
-                    if (declaratorName instanceof ICPPASTQualifiedName
-                            && ((ICPPASTQualifiedName) declaratorName)
-                                    .isConversionOrOperator())
-                        isFunction = true;
-                } catch (BacktrackException bt) {
-                    declaratorName = createName();
-                }
-            }
-
-            for (;;) {
-                switch (LT(1)) {
-                case IToken.tLPAREN:
-
-                    boolean failed = false;
-
-                    // temporary fix for initializer/function declaration
-                    // ambiguity
-                    if (!LA(2).looksLikeExpression()
-                            && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) {
-                        if (LT(2) == IToken.tIDENTIFIER) {
-                            IToken newMark = mark();
-                            consume(IToken.tLPAREN);
-                            try {
-                                name();
-                                // TODO - we need to lookup/resolve this name
-                                // see if its a type ...
-                                // if it is a type, failed = false
-                                // else failed = true
-                                failed = false;
-                            } catch (BacktrackException b) {
-                                failed = true;
-                            }
-
-                            backup(newMark);
-                        }
-                    }
-                    if ((!LA(2).looksLikeExpression()
-                            && strategy != SimpleDeclarationStrategy.TRY_VARIABLE
-                            && !failed && !forTypeID)) {
-                        // parameterDeclarationClause
-                        isFunction = true;
-                        // TODO need to create a temporary scope object here
-                        IToken last = consume(IToken.tLPAREN);
-                        finalOffset = last.getEndOffset();
-                        boolean seenParameter = false;
-                        parameterDeclarationLoop: for (;;) {
-                            switch (LT(1)) {
-                            case IToken.tRPAREN:
-                                last = consume();
-                                finalOffset = last.getEndOffset();
-                                break parameterDeclarationLoop;
-                            case IToken.tELLIPSIS:
-                                last = consume();
-                                encounteredVarArgs = true;
-                                finalOffset = last.getEndOffset();
-                                break;
-                            case IToken.tCOMMA:
-                                last = consume();
-                                seenParameter = false;
-                                finalOffset = last.getEndOffset();
-                                break;
-                            default:
-                                int endOffset = (last != null) ? last
-                                        .getEndOffset() : LA(1).getEndOffset();
-                                if (seenParameter)
-                                    throwBacktrack(startingOffset, endOffset
-                                            - startingOffset);
-                                IASTParameterDeclaration p = parameterDeclaration();
-                                finalOffset = calculateEndOffset(p);
-                                if (parameters == Collections.EMPTY_LIST)
-                                    parameters = new ArrayList(
-                                            DEFAULT_PARM_LIST_SIZE);
-                                parameters.add(p);
-                                seenParameter = true;
-                            }
-                        }
-                    }
-
-                    if (LT(1) == IToken.tCOLON)
-                        break overallLoop;
-
-                    if (LT(1) == IToken.t_try) {
-                        tryEncountered = true;
-                        break overallLoop;
-                    }
-
-                    IToken beforeCVModifier = mark();
-                    IToken[] cvModifiers = new IToken[2];
-                    int numCVModifiers = 0;
-                    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
-                    while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile)
-                            && numCVModifiers < 2) {
-                        IToken t = consume();
-                        finalOffset = t.getEndOffset();
-                        cvModifiers[numCVModifiers++] = t;
-                        afterCVModifier = mark();
-                    }
-                    // check for throws clause here
-
-                    if (LT(1) == IToken.t_throw) {
-                        exceptionSpecIds = new ArrayList(
-                                DEFAULT_SIZE_EXCEPTIONS_LIST);
-                        consume(IToken.t_throw); // throw
-                        consume(IToken.tLPAREN); // (
-                        boolean done = false;
-                        while (!done) {
-                            switch (LT(1)) {
-                            case IToken.tRPAREN:
-                                finalOffset = consume().getEndOffset();
-                                done = true;
-                                break;
-                            case IToken.tCOMMA:
-                                consume();
-                                break;
-                            default:
-                                try {
-                                    exceptionSpecIds.add(typeId(false, false));
-                                } catch (BacktrackException e) {
-                                    IASTProblem p = failParse(e);
-                                    IASTProblemTypeId typeIdProblem = createTypeIDProblem();
-                                    typeIdProblem.setProblem(p);
-                                    ((CPPASTNode) typeIdProblem)
-                                            .setOffsetAndLength(((CPPASTNode) p));
-                                    p.setParent(typeIdProblem);
-                                    p
-                                            .setPropertyInParent(IASTProblemHolder.PROBLEM);
-                                    exceptionSpecIds.add(typeIdProblem);
-                                }
-                                break;
-                            }
-                        }
-                    }
-                    // check for optional pure virtual
-                    if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) {
-                        char[] image = LA(2).getCharImage();
-                        if (image.length == 1 && image[0] == '0') {
-                            consume(IToken.tASSIGN);
-                            finalOffset = consume(IToken.tINTEGER)
-                                    .getEndOffset();
-                            isPureVirtual = true;
-                        }
-                    }
-                    if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI
-                            || LT(1) == IToken.tLBRACE) {
-                        // There were C++-specific clauses after
-                        // const/volatile modifier
-                        // Then it is a marker for the method
-                        if (numCVModifiers > 0) {
-                            for (int i = 0; i < numCVModifiers; i++) {
-                                if (cvModifiers[i].getType() == IToken.t_const)
-                                    isConst = true;
-                                if (cvModifiers[i].getType() == IToken.t_volatile)
-                                    isVolatile = 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:
-                    if (skipArrayDeclarator)
-                        break;
-                    arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
-                    consumeArrayModifiers(arrayMods);
-                    if (!arrayMods.isEmpty())
-                        finalOffset = calculateEndOffset((IASTNode) arrayMods
-                                .get(arrayMods.size() - 1));
-                    continue;
-                case IToken.tCOLON:
-                    consume(IToken.tCOLON);
-                    bitField = constantExpression();
-                    finalOffset = calculateEndOffset(bitField);
-                    break;
-                default:
-                    break;
-                }
-                break;
-            }
-            if (LA(1).getType() != IToken.tIDENTIFIER)
-                break;
-
-        } while (true);
-
-        IASTDeclarator d = null;
-        if (isFunction) {
-
-            ICPPASTFunctionDeclarator fc = null;
-            if (tryEncountered)
-                fc = createTryBlockDeclarator();
-            else
-                fc = createFunctionDeclarator();
-            fc.setVarArgs(encounteredVarArgs);
-            for (int i = 0; i < parameters.size(); ++i) {
-                IASTParameterDeclaration p = (IASTParameterDeclaration) parameters
-                        .get(i);
-                p.setParent(fc);
-                p
-                        .setPropertyInParent(IASTStandardFunctionDeclarator.FUNCTION_PARAMETER);
-                fc.addParameterDeclaration(p);
-            }
-            fc.setConst(isConst);
-            fc.setVolatile(isVolatile);
-            fc.setPureVirtual(isPureVirtual);
-            for (int i = 0; i < exceptionSpecIds.size(); ++i) {
-                IASTTypeId typeId = (IASTTypeId) exceptionSpecIds.get(i);
-                fc.addExceptionSpecificationTypeId(typeId);
-                typeId.setParent(fc);
-                typeId
-                        .setPropertyInParent(ICPPASTFunctionDeclarator.EXCEPTION_TYPEID);
-            }
-            d = fc;
-        } else if (arrayMods != Collections.EMPTY_LIST) {
-            d = createArrayDeclarator();
-            for (int i = 0; i < arrayMods.size(); ++i) {
-                IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i);
-                m.setParent(d);
-                m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER);
-                ((IASTArrayDeclarator) d).addArrayModifier(m);
-            }
-        } else if (bitField != null) {
-            IASTFieldDeclarator fl = createFieldDeclarator();
-            fl.setBitFieldSize(bitField);
-            bitField.setParent(fl);
-            bitField.setPropertyInParent(IASTFieldDeclarator.FIELD_SIZE);
-            d = fl;
-        } else {
-            d = createDeclarator();
-        }
-        for (int i = 0; i < pointerOps.size(); ++i) {
-            IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i);
-            d.addPointerOperator(po);
-            po.setParent(d);
-            po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR);
-        }
-        if (innerDecl != null) {
-            d.setNestedDeclarator(innerDecl);
-            innerDecl.setParent(d);
-            innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR);
-        }
-        if (declaratorName != null) {
-            d.setName(declaratorName);
-            declaratorName.setParent(d);
-            declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME);
-        }
-
-        ((ASTNode) d).setOffsetAndLength(startingOffset, finalOffset
-                - startingOffset);
-        return d;
-
-    }
-
-    /**
-     * @return
-     */
-    protected IASTProblemTypeId createTypeIDProblem() {
-        return new CPPASTProblemTypeId();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTFunctionTryBlockDeclarator createTryBlockDeclarator() {
-        return new CPPASTFunctionTryBlockDeclarator();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTFunctionDeclarator createFunctionDeclarator() {
-        return new CPPASTFunctionDeclarator();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTFieldDeclarator createFieldDeclarator() {
-        return new CPPASTFieldDeclarator();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTDeclarator createArrayDeclarator() {
-        return new CPPASTArrayDeclarator();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTDeclarator createDeclarator() {
-        return new CPPASTDeclarator();
-    }
-
-    protected IASTName consumeTemplatedOperatorName()
-            throws EndOfFileException, BacktrackException {
-        TemplateParameterManager argumentList = TemplateParameterManager
-                .getInstance();
-        try {
-            if (LT(1) == IToken.t_operator)
-                return operatorId(null, null);
-
-            try {
-                return createName(name());
-            } catch (BacktrackException bt) {
-            }
-            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 = consumeTemplateArguments(end, argumentList);
-                }
-
-                while (LT(1) == IToken.tCOLONCOLON
-                        || LT(1) == IToken.tIDENTIFIER) {
-                    end = consume();
-                    if (end.getType() == IToken.tIDENTIFIER) {
-                        end = consumeTemplateArguments(end, argumentList);
-                    }
-                }
-
-                if (LT(1) == IToken.t_operator) {
-                    return operatorId(start, argumentList);
-                }
-
-                int endOffset = (end != null) ? end.getEndOffset() : 0;
-                backup(mark);
-                throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
-            }
-            int endOffset = (mark != null) ? mark.getEndOffset() : 0;
-            backup(mark);
-            throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
-
-            return null;
-        } finally {
-            TemplateParameterManager.returnInstance(argumentList);
-        }
-    }
-
-    /**
-     * Parse a class/struct/union definition. classSpecifier : classKey name
-     * (baseClause)? "{" (memberSpecification)* "}"
-     * 
-     * @param owner
-     *            IParserCallback object that represents the declaration that
-     *            owns this classSpecifier
-     * @return TODO
-     * @throws BacktrackException
-     *             request a backtrack
-     */
-    protected ICPPASTCompositeTypeSpecifier classSpecifier()
-            throws BacktrackException, EndOfFileException {
-        int classKind = 0;
-        IToken classKey = null;
-        IToken mark = mark();
-
-        // class key
-        switch (LT(1)) {
-        case IToken.t_class:
-            classKey = consume();
-            classKind = ICPPASTCompositeTypeSpecifier.k_class;
-            break;
-        case IToken.t_struct:
-            classKey = consume();
-            classKind = IASTCompositeTypeSpecifier.k_struct;
-            break;
-        case IToken.t_union:
-            classKey = consume();
-            classKind = IASTCompositeTypeSpecifier.k_union;
-            break;
-        default:
-            throwBacktrack(mark.getOffset(), mark.getLength());
-        }
-
-        IASTName name = null;
-
-        // class name
-        if (LT(1) == IToken.tIDENTIFIER)
-            name = createName(name());
-        else
-            name = createName();
-
-        if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) {
-            IToken errorPoint = LA(1);
-            backup(mark);
-            throwBacktrack(errorPoint.getOffset(), errorPoint.getLength());
-        }
-
-        ICPPASTCompositeTypeSpecifier astClassSpecifier = createClassSpecifier();
-        ((ASTNode) astClassSpecifier).setOffset(classKey.getOffset());
-        astClassSpecifier.setKey(classKind);
-        astClassSpecifier.setName(name);
-        name.setParent(astClassSpecifier);
-        name.setPropertyInParent(IASTCompositeTypeSpecifier.TYPE_NAME);
-
-        // base clause
-        if (LT(1) == IToken.tCOLON) {
-            baseSpecifier(astClassSpecifier);
-        }
-
-        if (LT(1) == IToken.tLBRACE) {
-            consume(IToken.tLBRACE);
-
-            IASTNode n = mostRelevantScopeNode;
-            mostRelevantScopeNode = astClassSpecifier;
-            astClassSpecifier.setParent(n);
-
-            try {
-                memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
-                    int checkToken = LA(1).hashCode();
-                    switch (LT(1)) {
-                    case IToken.t_public:
-                    case IToken.t_protected:
-                    case IToken.t_private:
-                        IToken key = consume();
-                        int l = consume(IToken.tCOLON).getEndOffset();
-                        ICPPASTVisiblityLabel label = createVisibilityLabel();
-                        ((ASTNode) label).setOffsetAndLength(key.getOffset(), l
-                                - key.getOffset());
-                        label.setVisibility(token2Visibility(key.getType()));
-                        astClassSpecifier.addMemberDeclaration(label);
-                        label.setParent(astClassSpecifier);
-                        label
-                                .setPropertyInParent(ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL);
-                        break;
-                    case IToken.tRBRACE:
-                        consume(IToken.tRBRACE);
-                        break memberDeclarationLoop;
-                    default:
-                        try {
-                            IASTDeclaration d = declaration();
-                            astClassSpecifier.addMemberDeclaration(d);
-                            d.setParent(astClassSpecifier);
-                            d
-                                    .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION);
-                        } catch (BacktrackException bt) {
-                            IASTProblem p = failParse(bt);
-                            IASTProblemDeclaration pd = createProblemDeclaration();
-                            pd.setProblem(p);
-                            ((CPPASTNode) pd)
-                                    .setOffsetAndLength(((CPPASTNode) p));
-                            p.setParent(pd);
-                            p.setPropertyInParent(IASTProblemHolder.PROBLEM);
-                            astClassSpecifier.addMemberDeclaration(pd);
-                            pd.setParent(astClassSpecifier);
-                            pd
-                                    .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION);
-                            if (checkToken == LA(1).hashCode())
-                                errorHandling();
-                        }
-
-                        if (checkToken == LA(1).hashCode())
-                            failParseWithErrorHandling();
-                    }
-                }
-            } finally {
-                mostRelevantScopeNode = n;
-            }
-            // consume the }
-            int l = consume(IToken.tRBRACE).getEndOffset();
-            ((ASTNode) astClassSpecifier).setLength(l - classKey.getOffset());
-
-        }
-        return astClassSpecifier;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTCompositeTypeSpecifier createClassSpecifier() {
-        return new CPPASTCompositeTypeSpecifier();
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTVisiblityLabel createVisibilityLabel() {
-        return new CPPASTVisibilityLabel();
-    }
-
-    /**
-     * @param type
-     * @return
-     */
-    protected int token2Visibility(int type) {
-        switch (type) {
-        case IToken.t_public:
-            return ICPPASTVisiblityLabel.v_public;
-        case IToken.t_protected:
-            return ICPPASTVisiblityLabel.v_protected;
-        case IToken.t_private:
-            return ICPPASTVisiblityLabel.v_private;
-        }
-        return 0;
-    }
-
-    /**
-     * 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(ICPPASTCompositeTypeSpecifier astClassSpec)
-            throws EndOfFileException, BacktrackException {
-
-        IToken last = consume(IToken.tCOLON);
-
-        boolean isVirtual = false;
-        int visibility = 0; // ASTAccessVisibility.PUBLIC;
-        IASTName name = null;
-        IToken firstToken = null;
-        baseSpecifierLoop: for (;;) {
-            switch (LT(1)) {
-            case IToken.t_virtual:
-                if (firstToken == null) {
-                    firstToken = consume(IToken.t_virtual);
-                    last = firstToken;
-                } else
-                    last = consume(IToken.t_virtual);
-                isVirtual = true;
-                break;
-            case IToken.t_public:
-                visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public;
-                if (firstToken == null) {
-                    firstToken = consume();
-                    last = firstToken;
-                } else
-                    last = consume();
-                break;
-            case IToken.t_protected:
-                visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected;
-                if (firstToken == null) {
-                    firstToken = consume();
-                    last = firstToken;
-                } else
-                    last = consume();
-                break;
-            case IToken.t_private:
-                visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private;
-                if (firstToken == null) {
-                    firstToken = consume();
-                    last = firstToken;
-                } else
-                    last = consume();
-                break;
-            case IToken.tCOLONCOLON:
-            case IToken.tIDENTIFIER:
-                // to get templates right we need to use the class as the scope
-                ITokenDuple d = name();
-                name = createName(d);
-                if (firstToken == null)
-                    firstToken = d.getFirstToken();
-                last = d.getLastToken();
-                break;
-            case IToken.tCOMMA:
-                if (name == null)
-                    name = createName();
-                consume();
-                ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = createBaseSpecifier();
-                if (firstToken != null)
-                    ((ASTNode) baseSpec).setOffsetAndLength(firstToken
-                            .getOffset(), last.getEndOffset()
-                            - firstToken.getOffset());
-                baseSpec.setVirtual(isVirtual);
-                baseSpec.setVisibility(visibility);
-                baseSpec.setName(name);
-                name.setParent(baseSpec);
-                name
-                        .setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME);
-
-                astClassSpec.addBaseSpecifier(baseSpec);
-                baseSpec.setParent(astClassSpec);
-                baseSpec
-                        .setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER);
-
-                isVirtual = false;
-                visibility = 0;
-                name = null;
-                firstToken = null;
-
-                continue baseSpecifierLoop;
-            case IToken.tLBRACE:
-                if (name == null)
-                    name = createName();
-                baseSpec = createBaseSpecifier();
-                if (firstToken != null)
-                    ((ASTNode) baseSpec).setOffsetAndLength(firstToken
-                            .getOffset(), last.getEndOffset()
-                            - firstToken.getOffset());
-                baseSpec.setVirtual(isVirtual);
-                baseSpec.setVisibility(visibility);
-                baseSpec.setName(name);
-                name.setParent(baseSpec);
-                name
-                        .setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME);
-
-                astClassSpec.addBaseSpecifier(baseSpec);
-                baseSpec.setParent(astClassSpec);
-                baseSpec
-                        .setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER);
-            // fall through
-            default:
-                break baseSpecifierLoop;
-            }
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTBaseSpecifier createBaseSpecifier() {
-        return new CPPASTBaseSpecifier();
-    }
-
-    protected void catchHandlerSequence(List collection)
-            throws EndOfFileException, BacktrackException {
-        if (LT(1) != IToken.t_catch) {
-            IToken la = LA(1);
-            throwBacktrack(la.getOffset(), la.getLength()); // error, need at
-                                                            // least
-            // one of these
-        }
-        while (LT(1) == IToken.t_catch) {
-            int startOffset = consume(IToken.t_catch).getOffset();
-            consume(IToken.tLPAREN);
-            boolean isEllipsis = false;
-            IASTDeclaration decl = null;
-            try {
-                if (LT(1) == IToken.tELLIPSIS) {
-                    consume(IToken.tELLIPSIS);
-                    isEllipsis = true;
-                } else {
-                    decl = simpleDeclaration(
-                            SimpleDeclarationStrategy.TRY_VARIABLE, true);
-                }
-                consume(IToken.tRPAREN);
-            } catch (BacktrackException bte) {
-                IASTProblem p = failParse(bte);
-                IASTProblemDeclaration pd = createProblemDeclaration();
-                pd.setProblem(p);
-                ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
-                p.setParent(pd);
-                p.setPropertyInParent(IASTProblemHolder.PROBLEM);
-                decl = pd;
-            }
-
-            IASTStatement compoundStatement = catchBlockCompoundStatement();
-            ICPPASTCatchHandler handler = createCatchHandler();
-            ((ASTNode) handler).setOffsetAndLength(startOffset,
-                    calculateEndOffset(compoundStatement) - startOffset);
-            handler.setIsCatchAll(isEllipsis);
-            if (decl != null) {
-                handler.setDeclaration(decl);
-                decl.setParent(handler);
-                decl.setPropertyInParent(ICPPASTCatchHandler.DECLARATION);
-            }
-            if (compoundStatement != null) {
-                handler.setCatchBody(compoundStatement);
-                compoundStatement.setParent(handler);
-                compoundStatement
-                        .setPropertyInParent(ICPPASTCatchHandler.CATCH_BODY);
-            }
-            collection.add(handler);
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTCatchHandler createCatchHandler() {
-        return new CPPASTCatchHandler();
-    }
-
-    protected IASTStatement catchBlockCompoundStatement()
-            throws BacktrackException, EndOfFileException {
-        if (mode == ParserMode.QUICK_PARSE
-                || mode == ParserMode.STRUCTURAL_PARSE) {
-            IToken curr = LA(1);
-            IToken last = skipOverCompoundStatement();
-            IASTCompoundStatement cs = createCompoundStatement();
-            ((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last
-                    .getEndOffset()
-                    - curr.getOffset());
-            return cs;
-        } else if (mode == ParserMode.COMPLETION_PARSE
-                || mode == ParserMode.SELECTION_PARSE) {
-            if (scanner.isOnTopContext())
-                return compoundStatement();
-            IToken curr = LA(1);
-            IToken last = skipOverCompoundStatement();
-            IASTCompoundStatement cs = createCompoundStatement();
-            ((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last
-                    .getEndOffset()
-                    - curr.getOffset());
-            return cs;
-        }
-        return compoundStatement();
-    }
-
-    /**
-     * @throws BacktrackException
-     */
-    protected IASTNode forInitStatement() throws BacktrackException,
-            EndOfFileException {
-        IToken mark = mark();
-        try {
-            IASTExpression e = null;
-            if (LT(1) != IToken.tSEMI)
-                e = expression();
-            consume(IToken.tSEMI);
-            return e;
-        } catch (BacktrackException bt) {
-            backup(mark);
-            try {
-                return simpleDeclarationStrategyUnion();
-            } catch (BacktrackException b) {
-                failParse();
-                throwBacktrack(b);
-                return null;
-            }
-        }
-    }
-
-    /**
-     * This is the top-level entry point into the ANSI C++ grammar.
-     * translationUnit : (declaration)*
-     */
-    protected void translationUnit() {
-        try {
-            translationUnit = createTranslationUnit();
-        } catch (Exception e2) {
-            logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$
-            return;
-        }
-        translationUnit.setLocationResolver(scanner.getLocationResolver());
-
-        mostRelevantScopeNode = translationUnit;
-        while (true) {
-            try {
-                if (LT(1) == IToken.tEOC)
-                    break;
-                int checkOffset = LA(1).hashCode();
-                IASTDeclaration declaration = declaration();
-                translationUnit.addDeclaration(declaration);
-                declaration.setParent(translationUnit);
-                declaration
-                        .setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION);
-
-                if (LA(1).hashCode() == checkOffset)
-                    failParseWithErrorHandling();
-            } catch (EndOfFileException e) {
-                if (translationUnit.getDeclarations().length != 0) {
-                    CPPASTNode d = (CPPASTNode) translationUnit
-                            .getDeclarations()[translationUnit
-                            .getDeclarations().length - 1];
-                    ((CPPASTNode) translationUnit).setLength(d.getOffset()
-                            + d.getLength());
-                } else
-                    ((CPPASTNode) translationUnit).setLength(0);
-                break;
-            } catch (BacktrackException b) {
-                try {
-                    // Mark as failure and try to reach a recovery point
-                    IASTProblem p = failParse(b);
-                    IASTProblemDeclaration pd = createProblemDeclaration();
-                    p.setParent(pd);
-                    pd.setProblem(p);
-                    ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
-                    p.setPropertyInParent(IASTProblemHolder.PROBLEM);
-                    translationUnit.addDeclaration(pd);
-                    pd.setParent(translationUnit);
-                    pd
-                            .setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION);
-                    errorHandling();
-                } catch (EndOfFileException e) {
-                    break;
-                }
-            } catch (OutOfMemoryError oome) {
-                logThrowable("translationUnit", oome); //$NON-NLS-1$
-                throw oome;
-            } catch (Exception e) {
-                logException("translationUnit", e); //$NON-NLS-1$
-                try {
-                    failParseWithErrorHandling();
-                } catch (EndOfFileException e3) {
-                    // nothing
-                }
-            } catch (ParseError perr) {
-                throw perr;
-            } catch (Throwable e) {
-                logThrowable("translationUnit", e); //$NON-NLS-1$
-                try {
-                    failParseWithErrorHandling();
-                } catch (EndOfFileException e3) {
-                    // break;
-                }
-            }
-        }
-    }
-
-    /**
-     * @return
-     */
-    protected IASTProblemDeclaration createProblemDeclaration() {
-        return new CPPASTProblemDeclaration();
-    }
-
-    /**
-     * @return
-     */
-    protected CPPASTTranslationUnit createTranslationUnit() {
-        return new CPPASTTranslationUnit();
-    }
-
-    protected void consumeArrayModifiers(List collection)
-            throws EndOfFileException, BacktrackException {
-        while (LT(1) == IToken.tLBRACKET) {
-            int o = consume(IToken.tLBRACKET).getOffset(); // eat the '['
-
-            IASTExpression exp = null;
-            if (LT(1) != IToken.tRBRACKET) {
-                exp = constantExpression();
-            }
-            int l = consume(IToken.tRBRACKET).getEndOffset();
-            IASTArrayModifier arrayMod = createArrayModifier();
-            ((ASTNode) arrayMod).setOffsetAndLength(o, l - o);
-            if (exp != null) {
-                arrayMod.setConstantExpression(exp);
-                exp.setParent(arrayMod);
-                exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION);
-            }
-            collection.add(arrayMod);
-        }
-        return;
-    }
-
-    /**
-     * @return
-     */
-    protected IASTArrayModifier createArrayModifier() {
-        return new CPPASTArrayModifier();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit()
-     */
-    protected IASTTranslationUnit getTranslationUnit() {
-        return translationUnit;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement()
-     */
-    protected IASTCompoundStatement createCompoundStatement() {
-        return new CPPASTCompoundStatement();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression()
-     */
-    protected IASTBinaryExpression createBinaryExpression() {
-        return new CPPASTBinaryExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression()
-     */
-    protected IASTConditionalExpression createConditionalExpression() {
-        return new CPPASTConditionalExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression()
-     */
-    protected IASTUnaryExpression createUnaryExpression() {
-        return new CPPASTUnaryExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression()
-     */
-    protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() {
-        return new CPPASTCompoundStatementExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList()
-     */
-    protected IASTExpressionList createExpressionList() {
-        return new CPPASTExpressionList();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken)
-     */
-    protected IASTName createName(IToken token) {
-        IASTName n = null;
-
-        if (token instanceof OperatorTokenDuple) {
-            n = createOperatorName((OperatorTokenDuple) token, n);
-        } else {
-            n = new CPPASTName(token.getCharImage());
-        }
-
-        switch (token.getType()) {
-        case IToken.tCOMPLETION:
-        case IToken.tEOC:
-            createCompletionNode(token).addName(n);
-            break;
-        }
-        ((ASTNode) n).setOffsetAndLength(token.getOffset(), token.getLength());
-
-        return n;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName()
-     */
-    protected IASTName createName() {
-        return new CPPASTName();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator()
-     */
-    protected IASTEnumerator createEnumerator() {
-        return new CPPASTEnumerator();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#buildTypeIdExpression(int,
-     *      org.eclipse.cdt.core.dom.ast.IASTTypeId, int)
-     */
-    protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId,
-            int startingOffset, int endingOffset) {
-        ICPPASTTypeIdExpression typeIdExpression = createTypeIdExpression();
-        ((ASTNode) typeIdExpression).setOffsetAndLength(startingOffset,
-                endingOffset - startingOffset);
-        ((ASTNode) typeIdExpression).setLength(endingOffset - startingOffset);
-        typeIdExpression.setOperator(op);
-        typeIdExpression.setTypeId(typeId);
-        typeId.setParent(typeIdExpression);
-        typeId.setPropertyInParent(IASTTypeIdExpression.TYPE_ID);
-        return typeIdExpression;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTypeIdExpression createTypeIdExpression() {
-        return new CPPASTTypeIdExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerationSpecifier()
-     */
-    protected IASTEnumerationSpecifier createEnumerationSpecifier() {
-        return new CPPASTEnumerationSpecifier();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTLabelStatement createLabelStatement() {
-        return new CPPASTLabelStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTGotoStatement createGoToStatement() {
-        return new CPPASTGotoStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTReturnStatement createReturnStatement() {
-        return new CPPASTReturnStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTForStatement createForStatement() {
-        return new CPPASTForStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTContinueStatement createContinueStatement() {
-        return new CPPASTContinueStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTDoStatement createDoStatement() {
-        return new CPPASTDoStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTBreakStatement createBreakStatement() {
-        return new CPPASTBreakStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTWhileStatement createWhileStatement() {
-        return new CPPASTWhileStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTNullStatement createNullStatement() {
-        return new CPPASTNullStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTSwitchStatement createSwitchStatement() {
-        return new CPPASTSwitchStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTIfStatement createIfStatement() {
-        return new CPPASTIfStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTDefaultStatement createDefaultStatement() {
-        return new CPPASTDefaultStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTCaseStatement createCaseStatement() {
-        return new CPPASTCaseStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTExpressionStatement createExpressionStatement() {
-        return new CPPASTExpressionStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTDeclarationStatement createDeclarationStatement() {
-        return new CPPASTDeclarationStatement();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTASMDeclaration createASMDirective() {
-        return new CPPASTASMDeclaration();
-    }
-
-    /**
-     * @return
-     */
-    protected IASTCastExpression createCastExpression() {
-        return new CPPASTCastExpression();
-    }
-
-    protected IASTStatement statement() throws EndOfFileException,
-            BacktrackException {
-
-        switch (LT(1)) {
-        // labeled statements
-        case IToken.t_case:
-            return parseCaseStatement();
-        case IToken.t_default:
-            return parseDefaultStatement();
-        // compound statement
-        case IToken.tLBRACE:
-            return parseCompoundStatement();
-        // selection statement
-        case IToken.t_if:
-            return parseIfStatement();
-        case IToken.t_switch:
-            return parseSwitchStatement();
-        // iteration statements
-        case IToken.t_while:
-            return parseWhileStatement();
-        case IToken.t_do:
-            return parseDoStatement();
-        case IToken.t_for:
-            return parseForStatement();
-        // jump statement
-        case IToken.t_break:
-            return parseBreakStatement();
-        case IToken.t_continue:
-            return parseContinueStatement();
-        case IToken.t_return:
-            return parseReturnStatement();
-        case IToken.t_goto:
-            return parseGotoStatement();
-        case IToken.tSEMI:
-            return parseNullStatement();
-        case IToken.t_try:
-            return parseTryStatement();
-        default:
-            // can be many things:
-            // label
-            if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
-                return parseLabelStatement();
-            }
-
-            return parseDeclarationOrExpressionStatement();
-        }
-    }
-
-    /**
-     * @return
-     * @throws EndOfFileException
-     * @throws BacktrackException
-     */
-    protected IASTStatement parseTryStatement() throws EndOfFileException,
-            BacktrackException {
-        int startO = consume().getOffset();
-        IASTStatement tryBlock = compoundStatement();
-        List catchHandlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE);
-        catchHandlerSequence(catchHandlers);
-        ICPPASTTryBlockStatement tryStatement = createTryBlockStatement();
-        ((ASTNode) tryStatement).setOffset(startO);
-        tryStatement.setTryBody(tryBlock);
-        tryBlock.setParent(tryStatement);
-        tryBlock.setPropertyInParent(ICPPASTTryBlockStatement.BODY);
-
-        for (int i = 0; i < catchHandlers.size(); ++i) {
-            ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers
-                    .get(i);
-            tryStatement.addCatchHandler(handler);
-            handler.setParent(tryStatement);
-            handler.setPropertyInParent(ICPPASTTryBlockStatement.CATCH_HANDLER);
-            ((ASTNode) tryStatement).setLength(calculateEndOffset(handler)
-                    - startO);
-        }
-        return tryStatement;
-    }
-
-    /**
-     * @return
-     */
-    protected ICPPASTTryBlockStatement createTryBlockStatement() {
-        return new CPPASTTryBlockStatement();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit()
-     */
-    protected void nullifyTranslationUnit() {
-        translationUnit = null;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement()
-     */
-    protected IASTProblemStatement createProblemStatement() {
-        return new CPPASTProblemStatement();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression()
-     */
-    protected IASTProblemExpression createProblemExpression() {
-        return new CPPASTProblemExpression();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int,
-     *      int, int)
-     */
-    protected IASTProblem createProblem(int signal, int offset, int length) {
-        IASTProblem result = new CPPASTProblem(signal, EMPTY_STRING, false,
-                true);
-        ((ASTNode) result).setOffsetAndLength(offset, length);
-        ((ASTNode) result).setLength(length);
-        return result;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#resolveOtherAmbiguitiesAsDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement,
-     *      org.eclipse.cdt.core.dom.ast.IASTExpressionStatement)
-     */
-    protected boolean resolveOtherAmbiguitiesAsDeclaration(
-            IASTDeclarationStatement ds,
-            IASTExpressionStatement expressionStatement) {
-        if (expressionStatement.getExpression() instanceof IASTArraySubscriptExpression) {
-            IASTArraySubscriptExpression arraySub = (IASTArraySubscriptExpression) expressionStatement
-                    .getExpression();
-            if (!(arraySub.getArrayExpression() instanceof IASTIdExpression
-                    || arraySub.getArrayExpression() instanceof IASTArraySubscriptExpression || arraySub
-                    .getArrayExpression() instanceof IASTFieldReference))
-                return true;
-        }
-        // A & B = C;
-        if (expressionStatement.getExpression() instanceof IASTBinaryExpression) {
-            IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement
-                    .getExpression();
-            if (exp.getOperator() == IASTBinaryExpression.op_assign) {
-                IASTExpression lhs = exp.getOperand1();
-                if (lhs instanceof IASTBinaryExpression
-                        && ((IASTBinaryExpression) lhs).getOperator() == IASTBinaryExpression.op_binaryAnd) {
-
-                    return true;
-                }
-            }
-        }
-
-        return super.resolveOtherAmbiguitiesAsDeclaration(ds,
-                expressionStatement);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#parseWhileStatement()
-     */
-    protected IASTStatement parseWhileStatement() throws EndOfFileException,
-            BacktrackException {
-        int startOffset = consume(IToken.t_while).getOffset();
-        consume(IToken.tLPAREN);
-        IASTNode while_condition = whileCondition();
-        consume(IToken.tRPAREN);
-        IASTStatement while_body = statement();
-
-        ICPPASTWhileStatement while_statement = (ICPPASTWhileStatement) createWhileStatement();
-        ((ASTNode) while_statement).setOffsetAndLength(startOffset,
-                calculateEndOffset(while_body) - startOffset);
-        if (while_condition instanceof IASTExpression) {
-            while_statement.setCondition((IASTExpression) while_condition);
-            while_condition.setParent(while_statement);
-            while_condition
-                    .setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
-        } else if (while_condition instanceof IASTDeclaration) {
-            while_statement
-                    .setConditionDeclaration((IASTDeclaration) while_condition);
-            while_condition.setParent(while_statement);
-            while_condition
-                    .setPropertyInParent(ICPPASTWhileStatement.CONDITIONDECLARATION);
-        }
-        while_statement.setBody(while_body);
-        while_body.setParent(while_statement);
-        while_body.setPropertyInParent(IASTWhileStatement.BODY);
-        return while_statement;
-
-    }
-
-    /**
-     * @return
-     */
-    protected IASTNode whileCondition() throws BacktrackException,
-            EndOfFileException {
-        IToken mark = mark();
-        try {
-            IASTExpression e = expression();
-            if (LT(1) != IToken.tRPAREN)
-                throwBacktrack(LA(1));
-            return e;
-        } catch (BacktrackException bt) {
-            backup(mark);
-            try {
-                return simpleDeclaration(
-                        SimpleDeclarationStrategy.TRY_VARIABLE, true);
-            } catch (BacktrackException b) {
-                failParse();
-                throwBacktrack(b);
-                return null;
-            }
-        }
-    }
-
-    static class HeuristicTypeDetector extends CPPASTVisitor
-    {
-        IASTName searchName;
-        boolean found = false;
-        {
-            shouldVisitDeclarations = true;
-        }
-
-        public HeuristicTypeDetector(IASTName name) {
-            this.searchName = name;
-        }
-        
-        public int visit(IASTDeclaration declaration) {
-            if( declaration instanceof IASTSimpleDeclaration )
-            {
-                IASTSimpleDeclaration sd = (IASTSimpleDeclaration) declaration;
-                if( sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef )
-                {
-                    IASTDeclarator [] declarators = sd.getDeclarators();
-                    for( int i = 0; i < declarators.length; ++i )
-                        if( CharArrayUtils.equals( declarators[i].getName().toCharArray(), searchName.toCharArray() ) )
-                        {
-                            found = true;
-                            return PROCESS_ABORT;
-                        }
-                }
-                else if( sd.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier )
-                {
-                    IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) sd.getDeclSpecifier();
-                    if( CharArrayUtils.equals( comp.getName().toCharArray(), searchName.toCharArray() ) )
-                    {
-                        found = true;
-                        return PROCESS_ABORT;
-                    }
-                }
-            }
-            return PROCESS_CONTINUE;
-        }
-    }
-    
-    protected boolean queryIsTypeName(IASTName name) {
-        HeuristicTypeDetector visitor = new HeuristicTypeDetector( name );
-        translationUnit.accept( visitor );
-        return visitor.found;
-    }
-
-    protected void resolveAmbiguities() {
-        // TODO Auto-generated method stub
-        
-    }
+	private static final String COMPL = "~"; //$NON-NLS-1$
+
+	private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
+
+	private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
+
+	private static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
+
+	private static final String DYNAMIC_CAST = "dynamic_cast"; //$NON-NLS-1$
+
+	private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE = 4;
+
+	private ScopeStack templateIdScopes = new ScopeStack();
+
+	protected CPPASTTranslationUnit translationUnit;
+
+	private static class ScopeStack {
+		private int[] stack;
+
+		private int index = -1;
+
+		public ScopeStack() {
+			stack = new int[8];
+		}
+
+		private void grow() {
+			int[] newStack = new int[stack.length << 1];
+			System.arraycopy(stack, 0, newStack, 0, stack.length);
+			stack = newStack;
+		}
+
+		final public void push(int i) {
+			if (++index == stack.length)
+				grow();
+			stack[index] = i;
+		}
+
+		final public int pop() {
+			if (index >= 0)
+				return stack[index--];
+			return -1;
+		}
+
+		final public int peek() {
+			if (index >= 0)
+				return stack[index];
+			return -1;
+		}
+
+		final public int size() {
+			return index + 1;
+		}
+	}
+
+	/**
+	 * 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 {
+		int startingOffset = previousLast == null ? LA(1).getOffset()
+				: previousLast.getOffset();
+		IToken last = previousLast;
+		if (LT(1) == IToken.tLT) {
+			last = consume(IToken.tLT);
+			// until we get all the names sorted out
+			ScopeStack scopes = new ScopeStack();
+			scopes.push(IToken.tLT);
+
+			while (scopes.size() > 0) {
+				int top;
+				last = consume();
+
+				switch (last.getType()) {
+				case IToken.tGT:
+					if (scopes.peek() == IToken.tLT) {
+						scopes.pop();
+					}
+					break;
+				case IToken.tRBRACKET:
+					do {
+						top = scopes.pop();
+					} while (scopes.size() > 0
+							&& (top == IToken.tGT || top == IToken.tLT));
+					if (top != IToken.tLBRACKET)
+						throwBacktrack(startingOffset, last.getEndOffset()
+								- startingOffset);
+
+					break;
+				case IToken.tRPAREN:
+					do {
+						top = scopes.pop();
+					} while (scopes.size() > 0
+							&& (top == IToken.tGT || top == IToken.tLT));
+					if (top != IToken.tLPAREN)
+						throwBacktrack(startingOffset, last.getEndOffset()
+								- startingOffset);
+
+					break;
+				case IToken.tLT:
+				case IToken.tLBRACKET:
+				case IToken.tLPAREN:
+					scopes.push(last.getType());
+					break;
+				}
+			}
+		}
+		return last;
+	}
+
+	protected List templateArgumentList() throws EndOfFileException,
+			BacktrackException {
+		IToken start = LA(1);
+		int startingOffset = start.getOffset();
+		int endOffset = 0;
+		start = null;
+		List list = new ArrayList();
+
+		boolean completedArg = false;
+		boolean failed = false;
+
+		templateIdScopes.push(IToken.tLT);
+
+		while (LT(1) != IToken.tGT) {
+			completedArg = false;
+
+			IToken mark = mark();
+
+			try {
+				IASTTypeId typeId = typeId(false, false);
+				list.add(typeId);
+				completedArg = true;
+			} catch (BacktrackException e) {
+				backup(mark);
+			} /*
+				 * catch (ASTSemanticException e) { backup(mark); }
+				 */
+
+			if (!completedArg) {
+				try {
+					IASTExpression expression = assignmentExpression();
+					list.add(expression);
+					completedArg = true;
+				} catch (BacktrackException e) {
+					backup(mark);
+				}
+			}
+
+			if (LT(1) == IToken.tCOMMA) {
+				consume();
+			} else if (LT(1) != IToken.tGT) {
+				failed = true;
+				endOffset = LA(1).getEndOffset();
+				break;
+			}
+		}
+
+		templateIdScopes.pop();
+
+		if (failed)
+			throwBacktrack(startingOffset, endOffset - startingOffset);
+
+		return list;
+	}
+
+	/**
+	 * Parse a name. name : ("::")? name2 ("::" name2)* name2 : IDENTIFER :
+	 * template-id
+	 * 
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected ITokenDuple name() throws BacktrackException, EndOfFileException {
+
+		TemplateParameterManager argumentList = TemplateParameterManager
+				.getInstance();
+
+		try {
+			IToken first = LA(1);
+			IToken last = null;
+			IToken mark = mark();
+
+			boolean hasTemplateId = false;
+
+			if (LT(1) == IToken.tCOLONCOLON) {
+				argumentList.addSegment(null);
+				last = consume(IToken.tCOLONCOLON);
+			}
+
+			if (LT(1) == IToken.tCOMPL)
+				consume();
+
+			switch (LT(1)) {
+			case IToken.tIDENTIFIER:
+			case IToken.tCOMPLETION:
+			case IToken.tEOC:
+				last = consume();
+				last = consumeTemplateArguments(last, argumentList);
+				if (last.getType() == IToken.tGT)
+					hasTemplateId = true;
+				break;
+
+			default:
+				IToken l = LA(1);
+				backup(mark);
+				throwBacktrack(first.getOffset(), l.getEndOffset()
+						- first.getOffset());
+			}
+
+			while (LT(1) == IToken.tCOLONCOLON) {
+				last = consume(IToken.tCOLONCOLON);
+
+				if (LT(1) == IToken.t_template)
+					consume();
+
+				if (LT(1) == IToken.tCOMPL)
+					consume();
+
+				switch (LT(1)) {
+				case IToken.t_operator:
+					IToken l = LA(1);
+					backup(mark);
+					throwBacktrack(first.getOffset(), l.getEndOffset()
+							- first.getOffset());
+				case IToken.tIDENTIFIER:
+				case IToken.tCOMPLETION:
+				case IToken.tEOC:
+					last = consume();
+					last = consumeTemplateArguments(last, argumentList);
+					if (last.getType() == IToken.tGT)
+						hasTemplateId = true;
+				}
+			}
+
+			ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last,
+					(hasTemplateId ? argumentList.getTemplateArgumentsList()
+							: null));
+			return tokenDuple;
+		} finally {
+			TemplateParameterManager.returnInstance(argumentList);
+		}
+
+	}
+
+	/**
+	 * @param last
+	 * @param argumentList
+	 * @return
+	 * @throws EndOfFileException
+	 * @throws BacktrackException
+	 */
+	protected IToken consumeTemplateArguments(IToken last,
+			TemplateParameterManager argumentList) throws EndOfFileException,
+			BacktrackException {
+		// if (language != ParserLanguage.CPP)
+		// return last;
+		if (LT(1) == IToken.tLT) {
+			IToken secondMark = mark();
+			consume(IToken.tLT);
+			try {
+				List list = templateArgumentList();
+				argumentList.addSegment(list);
+				last = consume(IToken.tGT);
+			} catch (BacktrackException bt) {
+				argumentList.addSegment(null);
+				backup(secondMark);
+			}
+		} else {
+			argumentList.addSegment(null);
+		}
+		return last;
+	}
+
+	protected IASTName operatorId(IToken originalToken,
+			TemplateParameterManager templateArgs) throws BacktrackException,
+			EndOfFileException {
+		// we know this is an operator
+		IToken operatorToken = consume(IToken.t_operator);
+		IToken toSend = null;
+		IASTTypeId typeId = 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
+				throwBacktrack(operatorToken.getOffset(),
+						toSend != null ? toSend.getEndOffset()
+								- operatorToken.getOffset() : 0);
+		} else {
+			// must be a conversion function
+			IToken t = LA(1);
+			typeId = typeId(true, false);
+			if (t != LA(1)) {
+				while (t.getNext() != LA(1)) {
+					t = t.getNext();
+				}
+				toSend = t;
+			}
+		}
+
+		boolean hasTemplateId = (templateArgs != null);
+		boolean grabbedNewInstance = false;
+		if (templateArgs == null) {
+			templateArgs = TemplateParameterManager.getInstance();
+			grabbedNewInstance = true;
+		}
+
+		try {
+			toSend = consumeTemplateArguments(toSend, templateArgs);
+			if (toSend.getType() == IToken.tGT) {
+				hasTemplateId = true;
+			}
+
+			ITokenDuple duple = TokenFactory.createTokenDuple(
+					originalToken == null ? operatorToken : originalToken,
+					toSend, (hasTemplateId ? templateArgs
+							.getTemplateArgumentsList() : null));
+
+			OperatorTokenDuple operator = new OperatorTokenDuple(duple);
+			if (typeId != null) { // if it's a conversion operator
+				operator.setConversionOperator(true);
+				operator.setTypeId(typeId);
+			}
+
+			return createName(operator);
+		} finally {
+			if (grabbedNewInstance)
+				TemplateParameterManager.returnInstance(templateArgs);
+		}
+	}
+
+	/**
+	 * Parse a Pointer Operator. ptrOperator : "*" (cvQualifier)* | "&" | ::?
+	 * nestedNameSpecifier "*" (cvQualifier)*
+	 * 
+	 * @param owner
+	 *            Declarator that this pointer operator corresponds to.
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected void consumePointerOperators(List collection)
+			throws EndOfFileException, BacktrackException {
+
+		for (;;) {
+			if (LT(1) == IToken.tAMPER) {
+				int length = LA(1).getEndOffset() - LA(1).getOffset();
+				int o = consume(IToken.tAMPER).getOffset();
+				ICPPASTReferenceOperator refOp = createReferenceOperator();
+				((ASTNode) refOp).setOffsetAndLength(o, length);
+				collection.add(refOp);
+				return;
+			}
+			IToken last = null;
+			IToken mark = mark();
+			ITokenDuple nameDuple = null;
+			boolean isConst = false, isVolatile = false, isRestrict = false;
+			if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) {
+				try {
+					nameDuple = name();
+					last = nameDuple.getLastToken();
+				} catch (BacktrackException bt) {
+					backup(mark);
+					return;
+				}
+			}
+			if (LT(1) == IToken.tSTAR) {
+				last = consume(IToken.tSTAR);
+				int starOffset = last.getOffset();
+
+				for (;;) {
+					IToken t = LA(1);
+					int startingOffset = LA(1).getOffset();
+					switch (LT(1)) {
+					case IToken.t_const:
+						last = consume(IToken.t_const);
+						isConst = true;
+						break;
+					case IToken.t_volatile:
+						last = consume(IToken.t_volatile);
+						isVolatile = true;
+						break;
+					case IToken.t_restrict:
+						if (allowCPPRestrict) {
+							last = consume(IToken.t_restrict);
+							isRestrict = true;
+							break;
+						}
+						IToken la = LA(1);
+						throwBacktrack(startingOffset, la.getEndOffset()
+								- startingOffset);
+
+					}
+					if (t == LA(1))
+						break;
+				}
+
+				IASTPointerOperator po = null;
+				if (nameDuple != null) {
+					IASTName name = createName(nameDuple);
+					ICPPASTPointerToMember p2m = createPointerToMember(isRestrict);
+					((ASTNode) p2m).setOffsetAndLength(nameDuple
+							.getFirstToken().getOffset(), last.getEndOffset()
+							- nameDuple.getFirstToken().getOffset());
+					p2m.setConst(isConst);
+					p2m.setVolatile(isVolatile);
+					p2m.setName(name);
+					name.setParent(p2m);
+					name.setPropertyInParent(ICPPASTPointerToMember.NAME);
+					if (isRestrict) {
+						IGPPASTPointerToMember newPo = (IGPPASTPointerToMember) p2m;
+						newPo.setRestrict(isRestrict);
+						p2m = newPo;
+					}
+					po = p2m;
+
+				} else {
+					po = createPointer(isRestrict);
+					((ASTNode) po).setOffsetAndLength(starOffset, last
+							.getEndOffset()
+							- starOffset);
+					((IASTPointer) po).setConst(isConst);
+					((IASTPointer) po).setVolatile(isVolatile);
+					if (isRestrict) {
+						IGPPASTPointer newPo = (IGPPASTPointer) po;
+						newPo.setRestrict(isRestrict);
+						po = newPo;
+					}
+				}
+				if (po != null)
+					collection.add(po);
+
+				continue;
+			}
+
+			backup(mark);
+			return;
+		}
+	}
+
+	/**
+	 * @param isRestrict
+	 * @return
+	 */
+	protected ICPPASTPointerToMember createPointerToMember(boolean gnu) {
+		if (gnu)
+			return new GPPASTPointerToMember();
+		return new CPPASTPointerToMember();
+	}
+
+	/**
+	 * @param isRestrict
+	 * @return
+	 */
+	protected IASTPointerOperator createPointer(boolean gnu) {
+		if (gnu)
+			return new GPPASTPointer();
+		return new CPPASTPointer();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTReferenceOperator createReferenceOperator() {
+		return new CPPASTReferenceOperator();
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression assignmentExpression() throws EndOfFileException,
+			BacktrackException {
+		if (LT(1) == IToken.t_throw) {
+			return throwExpression();
+		}
+
+		if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tLBRACE
+				&& supportStatementsInExpressions) {
+			IASTExpression resultExpression = compoundStatementExpression();
+			if (resultExpression != null)
+				return resultExpression;
+		}
+
+		IASTExpression conditionalExpression = conditionalExpression();
+		// if the condition not taken, try assignment operators
+		if (conditionalExpression != null
+				&& conditionalExpression instanceof IASTConditionalExpression) // &&
+			return conditionalExpression;
+
+		switch (LT(1)) {
+		case IToken.tASSIGN:
+			return assignmentOperatorExpression(IASTBinaryExpression.op_assign,
+					conditionalExpression);
+		case IToken.tSTARASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_multiplyAssign,
+					conditionalExpression);
+		case IToken.tDIVASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_divideAssign, conditionalExpression);
+		case IToken.tMODASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_moduloAssign, conditionalExpression);
+		case IToken.tPLUSASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_plusAssign, conditionalExpression);
+		case IToken.tMINUSASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_minusAssign, conditionalExpression);
+		case IToken.tSHIFTRASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_shiftRightAssign,
+					conditionalExpression);
+		case IToken.tSHIFTLASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_shiftLeftAssign,
+					conditionalExpression);
+		case IToken.tAMPERASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_binaryAndAssign,
+					conditionalExpression);
+		case IToken.tXORASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_binaryXorAssign,
+					conditionalExpression);
+		case IToken.tBITORASSIGN:
+			return assignmentOperatorExpression(
+					IASTBinaryExpression.op_binaryOrAssign,
+					conditionalExpression);
+		}
+		return conditionalExpression;
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression throwExpression() throws EndOfFileException,
+			BacktrackException {
+		IToken throwToken = consume(IToken.t_throw);
+		IASTExpression throwExpression = null;
+		try {
+			throwExpression = expression();
+		} catch (BacktrackException bte) {
+		}
+		int o = throwExpression != null ? calculateEndOffset(throwExpression)
+				: throwToken.getEndOffset();
+		return buildUnaryExpression(ICPPASTUnaryExpression.op_throw,
+				throwExpression, throwToken.getOffset(), o
+						- throwToken.getOffset());
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression relationalExpression() throws BacktrackException,
+			EndOfFileException {
+
+		IASTExpression firstExpression = shiftExpression();
+		for (;;) {
+			switch (LT(1)) {
+			case IToken.tGT:
+				if (templateIdScopes.size() > 0
+						&& templateIdScopes.peek() == IToken.tLT) {
+					return firstExpression;
+				}
+			case IToken.tLT:
+			case IToken.tLTEQUAL:
+			case IToken.tGTEQUAL:
+				IToken m = mark();
+				int t = consume().getType();
+
+				IASTExpression secondExpression = null;
+				try {
+					secondExpression = shiftExpression();
+				} catch (BacktrackException bte) {
+					backup(m);
+					return firstExpression;
+				}
+				int expressionKind = 0;
+				switch (t) {
+				case IToken.tGT:
+					expressionKind = IASTBinaryExpression.op_greaterThan;
+					break;
+				case IToken.tLT:
+					expressionKind = IASTBinaryExpression.op_lessThan;
+					break;
+				case IToken.tLTEQUAL:
+					expressionKind = IASTBinaryExpression.op_lessEqual;
+					break;
+				case IToken.tGTEQUAL:
+					expressionKind = IASTBinaryExpression.op_greaterEqual;
+					break;
+				}
+				firstExpression = buildBinaryExpression(expressionKind,
+						firstExpression, secondExpression,
+						calculateEndOffset(secondExpression));
+				break;
+			default:
+				if (supportMinAndMaxOperators
+						&& (LT(1) == IGCCToken.tMIN || LT(1) == IGCCToken.tMAX)) {
+					int new_operator = 0;
+					switch (LT(1)) {
+					case IGCCToken.tMAX:
+						consume();
+						new_operator = IGPPASTBinaryExpression.op_max;
+						break;
+					case IGCCToken.tMIN:
+						consume();
+						new_operator = IGPPASTBinaryExpression.op_min;
+					}
+
+					secondExpression = shiftExpression();
+
+					firstExpression = buildBinaryExpression(new_operator,
+							firstExpression, secondExpression,
+							calculateEndOffset(secondExpression));
+					break;
+				}
+				return firstExpression;
+			}
+		}
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression multiplicativeExpression()
+			throws BacktrackException, EndOfFileException {
+		IASTExpression firstExpression = pmExpression();
+		for (;;) {
+			switch (LT(1)) {
+			case IToken.tSTAR:
+			case IToken.tDIV:
+			case IToken.tMOD:
+				IToken t = consume();
+				IASTExpression secondExpression = pmExpression();
+				int operator = 0;
+				switch (t.getType()) {
+				case IToken.tSTAR:
+					operator = IASTBinaryExpression.op_multiply;
+					break;
+				case IToken.tDIV:
+					operator = IASTBinaryExpression.op_divide;
+					break;
+				case IToken.tMOD:
+					operator = IASTBinaryExpression.op_modulo;
+					break;
+				}
+				firstExpression = buildBinaryExpression(operator,
+						firstExpression, secondExpression,
+						calculateEndOffset(secondExpression));
+				break;
+			default:
+				return firstExpression;
+			}
+		}
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression pmExpression() throws EndOfFileException,
+			BacktrackException {
+
+		IASTExpression firstExpression = castExpression();
+		for (;;) {
+			switch (LT(1)) {
+			case IToken.tDOTSTAR:
+			case IToken.tARROWSTAR:
+				IToken t = consume();
+				IASTExpression secondExpression = castExpression();
+				int operator = 0;
+				switch (t.getType()) {
+				case IToken.tDOTSTAR:
+					operator = ICPPASTBinaryExpression.op_pmdot;
+					break;
+				case IToken.tARROWSTAR:
+					operator = ICPPASTBinaryExpression.op_pmarrow;
+					break;
+				}
+				firstExpression = buildBinaryExpression(operator,
+						firstExpression, secondExpression,
+						calculateEndOffset(secondExpression));
+				break;
+			default:
+				return firstExpression;
+			}
+		}
+	}
+
+	/**
+	 * castExpression : unaryExpression | "(" typeId ")" castExpression
+	 */
+	protected IASTExpression castExpression() throws EndOfFileException,
+			BacktrackException {
+		// TO DO: we need proper symbol checkint to ensure type name
+		if (LT(1) == IToken.tLPAREN) {
+			IToken la = LA(1);
+			int startingOffset = la.getOffset();
+			IToken mark = mark();
+			consume();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLPAREN);
+			}
+			boolean popped = false;
+			IASTTypeId typeId = null;
+			// If this isn't a type name, then we shouldn't be here
+			try {
+				try {
+					typeId = typeId(false, false);
+					consume(IToken.tRPAREN);
+				} catch (BacktrackException bte) {
+					backup(mark);
+					throwBacktrack(bte);
+				}
+
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.pop();
+					popped = true;
+				}
+				IASTExpression castExpression = castExpression();
+				mark = null; // clean up mark so that we can garbage collect
+				return buildTypeIdUnaryExpression(IASTCastExpression.op_cast,
+						typeId, castExpression, startingOffset,
+						calculateEndOffset(castExpression));
+			} catch (BacktrackException b) {
+				backup(mark);
+				if (templateIdScopes.size() > 0 && !popped) {
+					templateIdScopes.pop();
+				}
+			}
+		}
+		return unaryExpression();
+
+	}
+
+	/**
+	 * @throws BacktrackException
+	 */
+	protected IASTTypeId typeId(boolean skipArrayModifiers,
+			boolean forNewExpression) throws EndOfFileException,
+			BacktrackException {
+		IToken mark = mark();
+		int startingOffset = mark.getOffset();
+		IASTDeclSpecifier declSpecifier = null;
+		IASTDeclarator declarator = null;
+
+		try {
+			declSpecifier = declSpecifierSeq(true, true);
+			declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR,
+					true, forNewExpression);
+		} catch (BacktrackException bt) {
+			backup(mark);
+			throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
+					declarator)
+					- startingOffset);
+		}
+		if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$
+		{
+			backup(mark);
+			throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
+					declarator)
+					- startingOffset);
+		}
+		if (declSpecifier instanceof IASTSimpleDeclSpecifier
+				&& ((ASTNode) declSpecifier).getLength() == 0) {
+			backup(mark);
+			throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
+					declarator)
+					- startingOffset);
+		}
+		if (declarator instanceof IASTArrayDeclarator && skipArrayModifiers) {
+			backup(mark);
+			throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
+					declarator)
+					- startingOffset);
+		}
+
+		IASTTypeId result = createTypeId();
+		((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(
+				declSpecifier, declarator)
+				- startingOffset);
+
+		result.setDeclSpecifier(declSpecifier);
+		declSpecifier.setParent(result);
+		declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER);
+
+		result.setAbstractDeclarator(declarator);
+		declarator.setParent(result);
+		declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR);
+
+		return result;
+
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTTypeId createTypeId() {
+		return new CPPASTTypeId();
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression deleteExpression() throws EndOfFileException,
+			BacktrackException {
+		int startingOffset = LA(1).getOffset();
+		boolean global = false;
+		if (LT(1) == IToken.tCOLONCOLON) {
+			// global scope
+			consume(IToken.tCOLONCOLON);
+			global = true;
+		}
+
+		consume(IToken.t_delete);
+
+		boolean vectored = false;
+		if (LT(1) == IToken.tLBRACKET) {
+			// array delete
+			consume();
+			consume(IToken.tRBRACKET);
+			vectored = true;
+		}
+		IASTExpression castExpression = castExpression();
+		ICPPASTDeleteExpression deleteExpression = createDeleteExpression();
+		((ASTNode) deleteExpression).setOffsetAndLength(startingOffset,
+				calculateEndOffset(castExpression) - startingOffset);
+		deleteExpression.setIsGlobal(global);
+		deleteExpression.setIsVectored(vectored);
+		deleteExpression.setOperand(castExpression);
+		castExpression.setParent(deleteExpression);
+		castExpression.setPropertyInParent(ICPPASTDeleteExpression.OPERAND);
+		return deleteExpression;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTDeleteExpression createDeleteExpression() {
+		return new CPPASTDeleteExpression();
+	}
+
+	/**
+	 * 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() throws BacktrackException,
+			EndOfFileException {
+		IToken la = LA(1);
+		int startingOffset = la.getOffset();
+		int lastOffset = 0;
+
+		boolean isGlobal = false;
+		if (LT(1) == IToken.tCOLONCOLON) {
+			lastOffset = consume(IToken.tCOLONCOLON).getEndOffset();
+			isGlobal = true;
+		}
+		lastOffset = consume(IToken.t_new).getEndOffset();
+		boolean typeIdInParen = false;
+		boolean placementParseFailure = true;
+		IToken beforeSecondParen = null;
+		IToken backtrackMarker = null;
+		IASTTypeId typeId = null;
+		IASTExpression newPlacementExpressions = null;
+		IASTExpression newInitializerExpressions = null;
+		boolean isNewTypeId = false;
+
+		master_new_loop: for (int i = 0; i < 2; ++i) {
+			IToken loopMark = LA(1);
+			if (LT(1) == IToken.tLPAREN) {
+				lastOffset = consume(IToken.tLPAREN).getEndOffset();
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.push(IToken.tLPAREN);
+				}
+				try {
+					// Try to consume placement list
+					if (i == 0) {
+						backtrackMarker = mark();
+						newPlacementExpressions = expression();
+						lastOffset = consume(IToken.tRPAREN).getEndOffset();
+						if (LT(1) == IToken.tLBRACKET) {
+							backup(backtrackMarker);
+							if (templateIdScopes.size() > 0) {
+								templateIdScopes.pop();
+							} // pop 1st Parent
+							placementParseFailure = true;
+							throwBacktrack(backtrackMarker.getOffset(),
+									backtrackMarker.getLength());
+						} else
+							placementParseFailure = false;
+					}
+
+					if (LT(1) == IToken.tLPAREN) {
+						beforeSecondParen = mark();
+						lastOffset = consume(IToken.tLPAREN).getEndOffset();
+						if (templateIdScopes.size() > 0) {
+							templateIdScopes.push(IToken.tLPAREN);
+						} // push 2nd Paren
+						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(true, false);
+					lastOffset = consume(IToken.tRPAREN).getEndOffset();
+					if (templateIdScopes.size() > 0) {
+						templateIdScopes.pop();
+					} // pop 1st Paren
+					break master_new_loop;
+				}
+				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(true, true);
+							lastOffset = calculateEndOffset(typeId);
+							break master_new_loop;
+						} catch (BacktrackException e) {
+							// Hmmm, so it wasn't typeId after all... Then it is
+							// CASE: new (typeid-looking-as-placement)
+							backup(loopMark);
+							placementParseFailure = true;
+							continue master_new_loop;
+						}
+					}
+				} 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(true, false);
+						lastOffset = consume(IToken.tRPAREN).getEndOffset();
+						if (templateIdScopes.size() > 0) {
+							templateIdScopes.pop();
+						} // popping the 2nd Paren
+
+						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.
+							ICPPASTNewExpression result = createNewExpression();
+							((ASTNode) result)
+									.setOffsetAndLength(startingOffset,
+											lastOffset - startingOffset);
+							result.setIsGlobal(isGlobal);
+							result.setIsNewTypeId(isNewTypeId);
+							result.setTypeId(typeId);
+							typeId.setParent(result);
+							typeId
+									.setPropertyInParent(ICPPASTNewExpression.TYPE_ID);
+							if (newPlacementExpressions != null) {
+								result.setNewPlacement(newPlacementExpressions);
+								newPlacementExpressions.setParent(result);
+								newPlacementExpressions
+										.setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT);
+							}
+							return result;
+						}
+						break master_new_loop;
+					} catch (BacktrackException e) {
+						// CASE: new
+						// (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
+						// Fallback to initializer processing
+						backup(beforeSecondParen);
+						if (templateIdScopes.size() > 0) {
+							templateIdScopes.pop();
+						}// pop that 2nd paren
+					}
+				}
+
+			} else {
+				// CASE: new typeid ...
+				// new parameters do not start with '('
+				// i.e it has to be a plain typeId
+				typeId = typeId(true, true);
+				lastOffset = calculateEndOffset(typeId);
+				isNewTypeId = true;
+				break master_new_loop;
+			}
+		}
+		ICPPASTNewExpression result = createNewExpression();
+		((ASTNode) result).setOffsetAndLength(startingOffset, lastOffset
+				- startingOffset);
+		result.setIsGlobal(isGlobal);
+		if (typeId != null) {
+			result.setIsNewTypeId(isNewTypeId);
+			result.setTypeId(typeId);
+			typeId.setParent(result);
+			typeId.setPropertyInParent(ICPPASTNewExpression.TYPE_ID);
+		}
+		if (newPlacementExpressions != null) {
+			result.setNewPlacement(newPlacementExpressions);
+			newPlacementExpressions.setParent(result);
+			newPlacementExpressions
+					.setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT);
+		}
+
+		while (LT(1) == IToken.tLBRACKET) {
+			// array new
+			lastOffset = consume().getEndOffset();
+
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLBRACKET);
+			}
+
+			IASTExpression a = assignmentExpression();
+			lastOffset = consume(IToken.tRBRACKET).getEndOffset();
+			result.addNewTypeIdArrayExpression(a);
+			a.setParent(result);
+			a
+					.setPropertyInParent(ICPPASTNewExpression.NEW_TYPEID_ARRAY_EXPRESSION);
+
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.pop();
+			}
+		}
+		// newinitializer
+		if (LT(1) == IToken.tLPAREN) {
+			lastOffset = consume(IToken.tLPAREN).getEndOffset();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLPAREN);
+			}
+
+			// we want to know the difference between no newInitializer and an
+			// empty new Initializer
+			// if the next token is the RPAREN, then we have an Empty expression
+			// in our list.
+			if (LT(1) != IToken.tRPAREN)
+				newInitializerExpressions = expression();
+
+			lastOffset = consume(IToken.tRPAREN).getEndOffset();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.pop();
+			}
+			if (newInitializerExpressions != null) {
+				result.setNewInitializer(newInitializerExpressions);
+				newInitializerExpressions.setParent(result);
+				newInitializerExpressions
+						.setPropertyInParent(ICPPASTNewExpression.NEW_INITIALIZER);
+			}
+
+		}
+		((CPPASTNode) result).setLength(lastOffset - startingOffset);
+		return result;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTNewExpression createNewExpression() {
+		return new CPPASTNewExpression();
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression unaryExpression() throws EndOfFileException,
+			BacktrackException {
+		IToken la = LA(1);
+		int startingOffset = la.getOffset();
+		switch (LT(1)) {
+		case IToken.tSTAR:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_star);// IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION);
+		case IToken.tAMPER:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_amper);// IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION);
+		case IToken.tPLUS:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_plus);// IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION);
+		case IToken.tMINUS:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_minus);// IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION);
+		case IToken.tNOT:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_not);// IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION);
+		case IToken.tCOMPL:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_tilde);// IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION);
+		case IToken.tINCR:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixIncr);// IASTExpression.Kind.UNARY_INCREMENT);
+		case IToken.tDECR:
+			return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr);// IASTExpression.Kind.UNARY_DECREMENT);
+		case IToken.t_sizeof:
+			consume(IToken.t_sizeof);
+			IToken mark = LA(1);
+			IASTTypeId typeId = null;
+			int lastOffset = 0;
+			IASTExpression unaryExpression = null;
+			if (LT(1) == IToken.tLPAREN) {
+				try {
+					consume(IToken.tLPAREN);
+					typeId = typeId(true, false);
+					lastOffset = consume(IToken.tRPAREN).getEndOffset();
+				} catch (BacktrackException bt) {
+					backup(mark);
+					unaryExpression = unaryExpression();
+					lastOffset = calculateEndOffset(unaryExpression);
+				}
+			} else {
+				unaryExpression = unaryExpression();
+				lastOffset = calculateEndOffset(unaryExpression);
+			}
+
+			if (typeId == null && unaryExpression != null)
+				return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
+						unaryExpression, startingOffset, lastOffset);
+			return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
+					typeId, startingOffset, lastOffset);
+		case IToken.t_new:
+			return newExpression();
+		case IToken.t_delete:
+			return deleteExpression();
+		case IToken.tCOLONCOLON:
+			switch (LT(2)) {
+			case IToken.t_new:
+				return newExpression();
+			case IToken.t_delete:
+				return deleteExpression();
+			default:
+				return postfixExpression();
+			}
+		default:
+			if (LT(1) == IGCCToken.t_typeof && supportTypeOfUnaries) {
+				IASTExpression unary = unaryTypeofExpression();
+				if (unary != null)
+					return unary;
+			}
+			if (LT(1) == IGCCToken.t___alignof__ && supportAlignOfUnaries) {
+				IASTExpression align = unaryAlignofExpression();
+				if (align != null)
+					return align;
+			}
+			return postfixExpression();
+		}
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression postfixExpression() throws EndOfFileException,
+			BacktrackException {
+		IASTExpression firstExpression = null;
+		boolean isTemplate = false;
+
+		switch (LT(1)) {
+		case IToken.t_typename:
+			int o = consume(IToken.t_typename).getOffset();
+
+			boolean templateTokenConsumed = false;
+			if (LT(1) == IToken.t_template) {
+				consume(IToken.t_template);
+				templateTokenConsumed = true;
+			}
+			ITokenDuple nestedName = name();
+			IASTName name = createName(nestedName);
+
+			consume(IToken.tLPAREN);
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLPAREN);
+			}
+			IASTExpression expressionList = expression();
+			int lastOffset = consume(IToken.tRPAREN).getEndOffset();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.pop();
+			}
+
+			ICPPASTTypenameExpression result = createTypenameExpression();
+			((ASTNode) result).setOffsetAndLength(o, lastOffset - o);
+			result.setIsTemplate(templateTokenConsumed);
+			result.setName(name);
+			name.setParent(result);
+			name.setPropertyInParent(ICPPASTTypenameExpression.TYPENAME);
+			result.setInitialValue(expressionList);
+			expressionList.setParent(result);
+			expressionList
+					.setPropertyInParent(ICPPASTTypenameExpression.INITIAL_VALUE);
+			firstExpression = result;
+			break;
+		// simple-type-specifier ( assignment-expression , .. )
+		case IToken.t_char:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_char);
+			break;
+		case IToken.t_wchar_t:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_wchar_t);
+			break;
+		case IToken.t_bool:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_bool);
+			break;
+		case IToken.t_short:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_short);
+			break;
+		case IToken.t_int:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_int);
+			break;
+		case IToken.t_long:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_long);
+			break;
+		case IToken.t_signed:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_signed);
+			break;
+		case IToken.t_unsigned:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_unsigned);
+			break;
+		case IToken.t_float:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_float);
+			break;
+		case IToken.t_double:
+			firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_double);
+			break;
+		case IToken.t_dynamic_cast:
+			firstExpression = specialCastExpression(ICPPASTCastExpression.op_dynamic_cast);
+			break;
+		case IToken.t_static_cast:
+			firstExpression = specialCastExpression(ICPPASTCastExpression.op_static_cast);
+			break;
+		case IToken.t_reinterpret_cast:
+			firstExpression = specialCastExpression(ICPPASTCastExpression.op_reinterpret_cast);
+			break;
+		case IToken.t_const_cast:
+			firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast);
+			break;
+		case IToken.t_typeid:
+			int so = consume().getOffset();
+			consume(IToken.tLPAREN);
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLPAREN);
+			}
+			boolean isTypeId = true;
+			IASTExpression lhs = null;
+			IASTTypeId typeId = null;
+			IToken m = mark();
+			try {
+				boolean amb = false;
+				if (LT(1) == IToken.tIDENTIFIER)
+					amb = true;
+				typeId = typeId(false, false);
+				if (amb
+						&& typeId.getDeclSpecifier() instanceof IASTNamedTypeSpecifier) {
+					if (!queryIsTypeName(((IASTNamedTypeSpecifier) typeId
+							.getDeclSpecifier()).getName())) {
+						backup(m);
+						throwBacktrack(((CPPASTNode) typeId).getOffset(),
+								((CPPASTNode) typeId).getLength());
+					}
+				}
+			} catch (BacktrackException b) {
+				typeId = null;
+				isTypeId = false;
+				lhs = expression();
+			}
+			lastOffset = consume(IToken.tRPAREN).getEndOffset();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.pop();
+			}
+			if (isTypeId && typeId != null)
+				firstExpression = buildTypeIdExpression(
+						ICPPASTTypeIdExpression.op_typeid, typeId, so,
+						lastOffset);
+			else
+				firstExpression = buildUnaryExpression(
+						ICPPASTUnaryExpression.op_typeid, lhs, so, lastOffset);
+			break;
+		default:
+			firstExpression = primaryExpression();
+		}
+		IASTExpression secondExpression = null;
+		for (;;) {
+			switch (LT(1)) {
+			case IToken.tLBRACKET:
+				// array access
+				consume(IToken.tLBRACKET);
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.push(IToken.tLBRACKET);
+				}
+				secondExpression = expression();
+				int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.pop();
+				}
+
+				IASTArraySubscriptExpression s = createArraySubscriptExpression();
+				((ASTNode) s).setOffsetAndLength(((ASTNode) firstExpression)
+						.getOffset(), lastOffset
+						- ((ASTNode) firstExpression).getOffset());
+				s.setArrayExpression(firstExpression);
+				firstExpression.setParent(s);
+				firstExpression
+						.setPropertyInParent(IASTArraySubscriptExpression.ARRAY);
+				s.setSubscriptExpression(secondExpression);
+				secondExpression.setParent(s);
+				secondExpression
+						.setPropertyInParent(IASTArraySubscriptExpression.SUBSCRIPT);
+				firstExpression = s;
+				break;
+			case IToken.tLPAREN:
+				// function call
+				consume(IToken.tLPAREN);
+
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.push(IToken.tLPAREN);
+				}
+				if (LT(1) != IToken.tRPAREN)
+					secondExpression = expression();
+				else
+					secondExpression = null;
+				lastOffset = consume(IToken.tRPAREN).getEndOffset();
+
+				if (templateIdScopes.size() > 0) {
+					templateIdScopes.pop();
+				}
+
+				IASTFunctionCallExpression fce = createFunctionCallExpression();
+				((ASTNode) fce).setOffsetAndLength(((ASTNode) firstExpression)
+						.getOffset(), lastOffset
+						- ((ASTNode) firstExpression).getOffset());
+				fce.setFunctionNameExpression(firstExpression);
+				firstExpression.setParent(fce);
+				firstExpression
+						.setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME);
+				if (secondExpression != null) {
+					fce.setParameterExpression(secondExpression);
+					secondExpression.setParent(fce);
+					secondExpression
+							.setPropertyInParent(IASTFunctionCallExpression.PARAMETERS);
+				}
+				firstExpression = fce;
+				break;
+			case IToken.tINCR:
+				int offset = consume(IToken.tINCR).getEndOffset();
+				firstExpression = buildUnaryExpression(
+						IASTUnaryExpression.op_postFixIncr, firstExpression,
+						((ASTNode) firstExpression).getOffset(), offset);
+				break;
+			case IToken.tDECR:
+				offset = consume().getEndOffset();
+				firstExpression = buildUnaryExpression(
+						IASTUnaryExpression.op_postFixDecr, firstExpression,
+						((ASTNode) firstExpression).getOffset(), offset);
+				break;
+			case IToken.tDOT:
+				// member access
+				consume(IToken.tDOT);
+				if (LT(1) == IToken.t_template) {
+					consume(IToken.t_template);
+					isTemplate = true;
+				}
+
+				IASTName name = idExpression();
+
+				ICPPASTFieldReference fieldReference = createFieldReference();
+				((ASTNode) fieldReference).setOffsetAndLength(
+						((ASTNode) firstExpression).getOffset(),
+						calculateEndOffset(name)
+								- ((ASTNode) firstExpression).getOffset());
+				fieldReference.setIsTemplate(isTemplate);
+				fieldReference.setIsPointerDereference(false);
+				fieldReference.setFieldName(name);
+				name.setParent(fieldReference);
+				name.setPropertyInParent(IASTFieldReference.FIELD_NAME);
+
+				fieldReference.setFieldOwner(firstExpression);
+				firstExpression.setParent(fieldReference);
+				firstExpression
+						.setPropertyInParent(IASTFieldReference.FIELD_OWNER);
+				firstExpression = fieldReference;
+				break;
+			case IToken.tARROW:
+				// member access
+				consume(IToken.tARROW);
+
+				if (LT(1) == IToken.t_template) {
+					consume(IToken.t_template);
+					isTemplate = true;
+				}
+
+				name = idExpression();
+
+				fieldReference = createFieldReference();
+				((ASTNode) fieldReference).setOffsetAndLength(
+						((ASTNode) firstExpression).getOffset(),
+						calculateEndOffset(name)
+								- ((ASTNode) firstExpression).getOffset());
+				fieldReference.setIsTemplate(isTemplate);
+				fieldReference.setIsPointerDereference(true);
+				fieldReference.setFieldName(name);
+				name.setParent(fieldReference);
+				name.setPropertyInParent(IASTFieldReference.FIELD_NAME);
+
+				fieldReference.setFieldOwner(firstExpression);
+				firstExpression.setParent(fieldReference);
+				firstExpression
+						.setPropertyInParent(IASTFieldReference.FIELD_OWNER);
+				firstExpression = fieldReference;
+				break;
+			default:
+				return firstExpression;
+			}
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTArraySubscriptExpression createArraySubscriptExpression() {
+		return new CPPASTArraySubscriptExpression();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTypenameExpression createTypenameExpression() {
+		return new CPPASTTypenameExpression();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTFunctionCallExpression createFunctionCallExpression() {
+		return new CPPASTFunctionCallExpression();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTFieldReference createFieldReference() {
+		return new CPPASTFieldReference();
+	}
+
+	protected IASTExpression simpleTypeConstructorExpression(int operator)
+			throws EndOfFileException, BacktrackException {
+		int startingOffset = LA(1).getOffset();
+		consume();
+		consume(IToken.tLPAREN);
+		IASTExpression operand = null;
+		if (LT(1) != IToken.tRPAREN)
+			operand = expression();
+		int l = consume(IToken.tRPAREN).getEndOffset();
+		ICPPASTSimpleTypeConstructorExpression result = createSimpleTypeConstructorExpression();
+		((ASTNode) result).setOffsetAndLength(startingOffset, l
+				- startingOffset);
+		result.setSimpleType(operator);
+		if (operand != null) {
+			result.setInitialValue(operand);
+			operand.setParent(result);
+			operand
+					.setPropertyInParent(ICPPASTSimpleTypeConstructorExpression.INITIALIZER_VALUE);
+		}
+		return result;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTSimpleTypeConstructorExpression createSimpleTypeConstructorExpression() {
+		return new CPPASTSimpleTypeConstructorExpression();
+	}
+
+	/**
+	 * @param expression
+	 * @throws BacktrackException
+	 */
+	protected IASTExpression primaryExpression() throws EndOfFileException,
+			BacktrackException {
+		IToken t = null;
+		ICPPASTLiteralExpression literalExpression = null;
+		switch (LT(1)) {
+		// TO DO: we need more literals...
+		case IToken.tINTEGER:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression
+					.setKind(IASTLiteralExpression.lk_integer_constant);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.tFLOATINGPT:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(IASTLiteralExpression.lk_float_constant);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.tSTRING:
+		case IToken.tLSTRING:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(IASTLiteralExpression.lk_string_literal);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.tCHAR:
+		case IToken.tLCHAR:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(IASTLiteralExpression.lk_char_constant);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.t_false:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(ICPPASTLiteralExpression.lk_false);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.t_true:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(ICPPASTLiteralExpression.lk_true);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+
+		case IToken.t_this:
+			t = consume();
+			literalExpression = createLiteralExpression();
+			literalExpression.setKind(ICPPASTLiteralExpression.lk_this);
+			literalExpression.setValue(t.getImage());
+			((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t
+					.getEndOffset()
+					- t.getOffset());
+			return literalExpression;
+		case IToken.tLPAREN:
+			t = consume();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.push(IToken.tLPAREN);
+			}
+			IASTExpression lhs = expression();
+			int finalOffset = consume(IToken.tRPAREN).getEndOffset();
+			if (templateIdScopes.size() > 0) {
+				templateIdScopes.pop();
+			}
+			return buildUnaryExpression(
+					IASTUnaryExpression.op_bracketedPrimary, lhs,
+					t.getOffset(), finalOffset);
+		case IToken.tIDENTIFIER:
+		case IToken.tCOLONCOLON:
+		case IToken.t_operator:
+		case IToken.tCOMPL: {
+			IASTName name = idExpression();
+			IASTIdExpression idExpression = createIdExpression();
+			((ASTNode) idExpression).setOffsetAndLength(((ASTNode) name)
+					.getOffset(), ((ASTNode) name).getOffset()
+					+ ((ASTNode) name).getLength()
+					- ((ASTNode) name).getOffset());
+			idExpression.setName(name);
+			name.setParent(idExpression);
+			name.setPropertyInParent(IASTIdExpression.ID_NAME);
+			return idExpression;
+		}
+		case IToken.tCOMPLETION: {
+			IToken token = consume();
+			IASTName name = createName(token);
+			IASTIdExpression idExpression = createIdExpression();
+			idExpression.setName(name);
+			name.setParent(idExpression);
+			name.setPropertyInParent(IASTIdExpression.ID_NAME);
+			createCompletionNode(token).addName(name);
+			return idExpression;
+		}
+		default:
+			IToken la = LA(1);
+			int startingOffset = la.getOffset();
+			throwBacktrack(startingOffset, la.getLength());
+			return null;
+		}
+
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTLiteralExpression createLiteralExpression() {
+		return new CPPASTLiteralExpression();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTIdExpression createIdExpression() {
+		return new CPPASTIdExpression();
+	}
+
+	protected IASTName idExpression() throws EndOfFileException,
+			BacktrackException {
+		IASTName name = null;
+		try {
+			name = createName(name());
+		} catch (BacktrackException bt) {
+			IToken mark = mark();
+			if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
+				IToken start = consume();
+				IToken end = null;
+				if (start.getType() == IToken.tIDENTIFIER)
+					end = consumeTemplateParameters(null);
+				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)
+					name = operatorId(start, null);
+				else {
+					backup(mark);
+					throwBacktrack(start.getOffset(), end.getEndOffset()
+							- start.getOffset());
+				}
+			} else if (LT(1) == IToken.t_operator)
+				name = operatorId(null, null);
+		}
+		return name;
+
+	}
+
+	protected IASTExpression specialCastExpression(int kind)
+			throws EndOfFileException, BacktrackException {
+		int startingOffset = LA(1).getOffset();
+		IToken op = consume();
+		consume(IToken.tLT);
+		IASTTypeId typeID = typeId(false, false);
+		consume(IToken.tGT);
+		consume(IToken.tLPAREN);
+		IASTExpression lhs = expression();
+		int l = consume(IToken.tRPAREN).getEndOffset();
+		IASTCastExpression result = createCastExpression();
+		((ASTNode) result).setOffsetAndLength(startingOffset, l
+				- startingOffset);
+		result.setTypeId(typeID);
+		typeID.setParent(result);
+		typeID.setPropertyInParent(IASTCastExpression.TYPE_ID);
+		result.setOperand(lhs);
+
+		if (op.toString().equals(DYNAMIC_CAST)) {
+			result.setOperator(ICPPASTCastExpression.op_dynamic_cast);
+		} else if (op.toString().equals(STATIC_CAST)) {
+			result.setOperator(ICPPASTCastExpression.op_static_cast);
+		} else if (op.toString().equals(REINTERPRET_CAST)) {
+			result.setOperator(ICPPASTCastExpression.op_reinterpret_cast);
+		} else if (op.toString().equals(CONST_CAST)) {
+			result.setOperator(ICPPASTCastExpression.op_const_cast);
+		} else {
+			result.setOperator(IASTCastExpression.op_cast);
+		}
+
+		lhs.setParent(result);
+		lhs.setPropertyInParent(IASTCastExpression.OPERAND);
+		return result;
+	}
+
+	private final boolean allowCPPRestrict;
+
+	private final boolean supportExtendedTemplateSyntax;
+
+	private final boolean supportMinAndMaxOperators;
+
+	private final boolean supportComplex;
+
+	private final boolean supportRestrict;
+
+	private final boolean supportLongLong;
+
+	private static final int DEFAULT_PARM_LIST_SIZE = 4;
+
+	private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
+
+	private static final int DEFAULT_SIZE_EXCEPTIONS_LIST = 2;
+
+	private static final int DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE = 4;
+
+	/**
+	 * This is the standard cosntructor that we expect the Parser to be
+	 * instantiated with.
+	 * 
+	 * @param mode
+	 *            TODO
+	 */
+	public GNUCPPSourceParser(IScanner scanner, ParserMode mode,
+			IParserLogService log, ICPPParserExtensionConfiguration config) {
+		super(scanner, log, mode, config.supportStatementsInExpressions(),
+				config.supportTypeofUnaryExpressions(), config
+						.supportAlignOfUnaryExpression());
+		allowCPPRestrict = config.allowRestrictPointerOperators();
+		supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax();
+		supportMinAndMaxOperators = config.supportMinAndMaxOperators();
+		supportRestrict = config.supportRestrictKeyword();
+		supportComplex = config.supportComplexNumbers();
+		supportLongLong = config.supportLongLongs();
+	}
+
+	/**
+	 * 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.
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request for a backtrack
+	 */
+	protected IASTDeclaration usingClause() throws EndOfFileException,
+			BacktrackException {
+		IToken firstToken = consume(IToken.t_using);
+
+		if (LT(1) == IToken.t_namespace) {
+			// using-directive
+			int endOffset = consume(IToken.t_namespace).getEndOffset();
+			IASTName name = null;
+			if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON)
+				name = createName(name());
+			else
+				throwBacktrack(firstToken.getOffset(), endOffset
+						- firstToken.getOffset());
+
+			endOffset = consume(IToken.tSEMI).getEndOffset();
+			ICPPASTUsingDirective astUD = createUsingDirective();
+			((ASTNode) astUD).setOffsetAndLength(firstToken.getOffset(),
+					endOffset - firstToken.getOffset());
+			astUD.setQualifiedName(name);
+			name.setParent(astUD);
+			name.setPropertyInParent(ICPPASTUsingDirective.QUALIFIED_NAME);
+			return astUD;
+		}
+
+		boolean typeName = false;
+
+		if (LT(1) == IToken.t_typename) {
+			typeName = true;
+			consume(IToken.t_typename);
+		}
+
+		IASTName name = createName(name());
+		int end = consume(IToken.tSEMI).getEndOffset();
+		ICPPASTUsingDeclaration result = createUsingDeclaration();
+		((ASTNode) result).setOffsetAndLength(firstToken.getOffset(), end
+				- firstToken.getOffset());
+		result.setIsTypename(typeName);
+		result.setName(name);
+		name.setPropertyInParent(ICPPASTUsingDeclaration.NAME);
+		name.setParent(result);
+		return result;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTUsingDeclaration createUsingDeclaration() {
+		return new CPPASTUsingDeclaration();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTUsingDirective createUsingDirective() {
+		return new CPPASTUsingDirective();
+	}
+
+	/**
+	 * 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.
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request for a backtrack
+	 */
+	protected ICPPASTLinkageSpecification linkageSpecification()
+			throws EndOfFileException, BacktrackException {
+		IToken firstToken = consume(IToken.t_extern);
+		IToken spec = consume(IToken.tSTRING);
+		ICPPASTLinkageSpecification linkage = createLinkageSpecification();
+		((ASTNode) linkage).setOffset(firstToken.getOffset());
+		linkage.setLiteral(spec.getImage());
+
+		if (LT(1) == IToken.tLBRACE) {
+			consume(IToken.tLBRACE);
+
+			linkageDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
+				int checkToken = LA(1).hashCode();
+				switch (LT(1)) {
+				case IToken.tRBRACE:
+					break linkageDeclarationLoop;
+				default:
+					try {
+						IASTDeclaration d = declaration();
+						linkage.addDeclaration(d);
+						d.setParent(linkage);
+						d
+								.setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
+					} catch (BacktrackException bt) {
+						IASTProblem p = failParse(bt);
+						IASTProblemDeclaration pd = createProblemDeclaration();
+						p.setParent(pd);
+						pd.setProblem(p);
+						((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
+						p.setPropertyInParent(IASTProblemHolder.PROBLEM);
+						linkage.addDeclaration(pd);
+						pd.setParent(linkage);
+						pd
+								.setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
+						errorHandling();
+						if (checkToken == LA(1).hashCode())
+							errorHandling();
+					}
+				}
+				if (checkToken == LA(1).hashCode())
+					failParseWithErrorHandling();
+			}
+			// consume the }
+			int endOffset = consume(IToken.tRBRACE).getEndOffset();
+			((CPPASTNode) linkage)
+					.setLength(endOffset - firstToken.getOffset());
+			return linkage;
+		}
+		// single declaration
+
+		IASTDeclaration d = declaration();
+		linkage.addDeclaration(d);
+		d.setParent(linkage);
+		d.setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION);
+		((CPPASTNode) linkage).setLength(calculateEndOffset(d)
+				- firstToken.getOffset());
+		return linkage;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTLinkageSpecification createLinkageSpecification() {
+		return new CPPASTLinkageSpecification();
+	}
+
+	/**
+	 * 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.
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request for a backtrack
+	 */
+	protected IASTDeclaration templateDeclaration() throws EndOfFileException,
+			BacktrackException {
+		IToken mark = mark();
+		IToken firstToken = null;
+		boolean exported = false;
+		boolean encounteredExtraMod = false;
+		if (LT(1) == IToken.t_export) {
+			exported = true;
+			firstToken = consume(IToken.t_export);
+			consume(IToken.t_template);
+		} else {
+			if (supportExtendedTemplateSyntax) {
+				switch (LT(1)) {
+				case IToken.t_static:
+				case IToken.t_extern:
+				case IToken.t_inline:
+					firstToken = consume();
+					consume(IToken.t_template);
+					encounteredExtraMod = true;
+					break;
+				default:
+					firstToken = consume(IToken.t_template);
+					break;
+				}
+			} else
+				firstToken = consume(IToken.t_template);
+		}
+		if (LT(1) != IToken.tLT) {
+			// explicit-instantiation
+			ICPPASTExplicitTemplateInstantiation templateInstantiation = null;
+			if (encounteredExtraMod && supportExtendedTemplateSyntax) {
+				IGPPASTExplicitTemplateInstantiation temp = createGnuTemplateInstantiation();
+				switch (firstToken.getType()) {
+				case IToken.t_static:
+					temp
+							.setModifier(IGPPASTExplicitTemplateInstantiation.ti_static);
+					break;
+				case IToken.t_extern:
+					temp
+							.setModifier(IGPPASTExplicitTemplateInstantiation.ti_extern);
+					break;
+				case IToken.t_inline:
+					temp
+							.setModifier(IGPPASTExplicitTemplateInstantiation.ti_inline);
+					break;
+				}
+				templateInstantiation = temp;
+			} else
+				templateInstantiation = createTemplateInstantiation();
+			IASTDeclaration d = declaration();
+			((ASTNode) templateInstantiation).setOffsetAndLength(firstToken
+					.getOffset(), calculateEndOffset(d)
+					- firstToken.getOffset());
+			templateInstantiation.setDeclaration(d);
+			d.setParent(templateInstantiation);
+			d
+					.setPropertyInParent(ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION);
+			return templateInstantiation;
+		}
+		consume(IToken.tLT);
+		if (LT(1) == IToken.tGT) {
+			// explicit-specialization
+			consume(IToken.tGT);
+
+			ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization();
+			IASTDeclaration d = declaration();
+			((ASTNode) templateSpecialization).setOffsetAndLength(firstToken
+					.getOffset(), calculateEndOffset(d)
+					- firstToken.getOffset());
+			templateSpecialization.setDeclaration(d);
+			d.setParent(templateSpecialization);
+			d
+					.setPropertyInParent(ICPPASTTemplateSpecialization.OWNED_DECLARATION);
+			return templateSpecialization;
+		}
+
+		try {
+			List parms = templateParameterList();
+			consume(IToken.tGT);
+			IASTDeclaration d = declaration();
+			ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration();
+			((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(),
+					calculateEndOffset(d) - firstToken.getOffset());
+			templateDecl.setExported(exported);
+			templateDecl.setDeclaration(d);
+			d.setParent(templateDecl);
+			d.setPropertyInParent(ICPPASTTemplateDeclaration.OWNED_DECLARATION);
+			for (int i = 0; i < parms.size(); ++i) {
+				ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms
+						.get(i);
+				templateDecl.addTemplateParamter(parm);
+				parm.setParent(templateDecl);
+				parm.setPropertyInParent(ICPPASTTemplateDeclaration.PARAMETER);
+			}
+
+			return templateDecl;
+		} catch (BacktrackException bt) {
+			backup(mark);
+			throw bt;
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTemplateDeclaration createTemplateDeclaration() {
+		return new CPPASTTemplateDeclaration();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTemplateSpecialization createTemplateSpecialization() {
+		return new CPPASTTemplateSpecialization();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IGPPASTExplicitTemplateInstantiation createGnuTemplateInstantiation() {
+		return new GPPASTExplicitTemplateInstantiation();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTExplicitTemplateInstantiation createTemplateInstantiation() {
+		return new CPPASTExplicitTemplateInstantiation();
+	}
+
+	/**
+	 * 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() 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(DEFAULT_PARM_LIST_SIZE);
+
+		for (;;) {
+			if (LT(1) == IToken.tGT)
+				return returnValue;
+			if (LT(1) == IToken.t_class || LT(1) == IToken.t_typename) {
+				IToken startingToken = LA(1);
+				int lastOffset = 0;
+				int type = (LT(1) == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class
+						: ICPPASTSimpleTypeTemplateParameter.st_typename);
+				lastOffset = consume().getEndOffset();
+				IASTName identifierName = null;
+				IASTTypeId typeId = null;
+
+				if (LT(1) == IToken.tIDENTIFIER) // optional identifier
+				{
+					identifierName = createName(identifier());
+					lastOffset = calculateEndOffset(identifierName);
+					if (LT(1) == IToken.tASSIGN) // optional = type-id
+					{
+						consume(IToken.tASSIGN);
+						typeId = typeId(false, false); // type-id
+						lastOffset = calculateEndOffset(typeId);
+					}
+				} else {
+					identifierName = createName();
+				}
+
+				ICPPASTSimpleTypeTemplateParameter parm = createSimpleTemplateParameter();
+				((ASTNode) parm).setOffsetAndLength(startingToken.getOffset(),
+						lastOffset - startingToken.getOffset());
+				parm.setParameterType(type);
+				parm.setName(identifierName);
+				identifierName.setParent(parm);
+				identifierName
+						.setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME);
+				if (typeId != null) {
+					parm.setDefaultType(typeId);
+					typeId.setParent(parm);
+					typeId
+							.setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.DEFAULT_TYPE);
+				}
+				returnValue.add(parm);
+
+			} else if (LT(1) == IToken.t_template) {
+				IToken firstToken = consume(IToken.t_template);
+				consume(IToken.tLT);
+
+				List subResult = templateParameterList();
+				consume(IToken.tGT);
+				int last = consume(IToken.t_class).getEndOffset();
+				IASTName identifierName = null;
+				IASTExpression optionalExpression = null;
+
+				if (LT(1) == IToken.tIDENTIFIER) // optional identifier
+				{
+					identifierName = createName(identifier());
+					last = calculateEndOffset(identifierName);
+					if (LT(1) == IToken.tASSIGN) // optional = type-id
+					{
+						consume(IToken.tASSIGN);
+						optionalExpression = primaryExpression();
+						last = calculateEndOffset(optionalExpression);
+					}
+				} else
+					identifierName = createName();
+
+				ICPPASTTemplatedTypeTemplateParameter parm = createTemplatedTemplateParameter();
+				((ASTNode) parm).setOffsetAndLength(firstToken.getOffset(),
+						last - firstToken.getOffset());
+				parm.setName(identifierName);
+				identifierName.setParent(parm);
+				identifierName
+						.setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME);
+				if (optionalExpression != null) {
+					parm.setDefaultValue(optionalExpression);
+					optionalExpression.setParent(parm);
+					optionalExpression
+							.setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.DEFAULT_VALUE);
+				}
+
+				for (int i = 0; i < subResult.size(); ++i) {
+					ICPPASTTemplateParameter p = (ICPPASTTemplateParameter) subResult
+							.get(i);
+					parm.addTemplateParamter(p);
+					p.setParent(parm);
+					p
+							.setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER);
+				}
+				returnValue.add(parm);
+
+			} else if (LT(1) == IToken.tCOMMA) {
+				consume(IToken.tCOMMA);
+				continue;
+			} else {
+				ICPPASTParameterDeclaration parm = parameterDeclaration();
+				returnValue.add(parm);
+			}
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTemplatedTypeTemplateParameter createTemplatedTemplateParameter() {
+		return new CPPASTTemplatedTypeTemplateParameter();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTSimpleTypeTemplateParameter createSimpleTemplateParameter() {
+		return new CPPASTSimpleTypeTemplateParameter();
+	}
+
+	/**
+	 * 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 IASTDeclaration declaration() throws EndOfFileException,
+			BacktrackException {
+		switch (LT(1)) {
+		case IToken.t_asm:
+			return asmDeclaration();
+		case IToken.t_namespace:
+			return namespaceDefinitionOrAlias();
+		case IToken.t_using:
+			return usingClause();
+		case IToken.t_export:
+		case IToken.t_template:
+			return templateDeclaration();
+		case IToken.t_extern:
+			if (LT(2) == IToken.tSTRING)
+				return linkageSpecification();
+		default:
+			if (supportExtendedTemplateSyntax
+					&& (LT(1) == IToken.t_static || LT(1) == IToken.t_inline || LT(1) == IToken.t_extern)
+					&& LT(2) == IToken.t_template)
+				return templateDeclaration();
+			return simpleDeclarationStrategyUnion();
+		}
+	}
+
+	protected IASTDeclaration simpleDeclarationStrategyUnion()
+			throws EndOfFileException, BacktrackException {
+		simpleDeclarationMark = mark();
+		IASTProblem firstFailure = null;
+		IASTProblem secondFailure = null;
+		try {
+			IASTDeclaration d = simpleDeclaration(
+					SimpleDeclarationStrategy.TRY_CONSTRUCTOR, false);
+			throwAwayMarksForInitializerClause();
+			return d;
+		} catch (BacktrackException bt) {
+			if (simpleDeclarationMark == null)
+				throwBacktrack(bt);
+			firstFailure = bt.getProblem();
+			// did not work
+			backup(simpleDeclarationMark);
+
+			try {
+				IASTDeclaration d = simpleDeclaration(
+						SimpleDeclarationStrategy.TRY_FUNCTION, false);
+				throwAwayMarksForInitializerClause();
+				return d;
+			} catch (BacktrackException bt2) {
+				if (simpleDeclarationMark == null) {
+					if (firstFailure != null && (bt2.getProblem() == null))
+						throwBacktrack(firstFailure);
+					else
+						throwBacktrack(bt2);
+				}
+
+				secondFailure = bt2.getProblem();
+				backup(simpleDeclarationMark);
+				throwAwayMarksForInitializerClause();
+				try {
+					return simpleDeclaration(
+							SimpleDeclarationStrategy.TRY_VARIABLE, false);
+				} catch (BacktrackException b3) {
+					backup(simpleDeclarationMark); // TODO - necessary?
+
+					if (firstFailure != null)
+						throwBacktrack(firstFailure);
+					else if (secondFailure != null)
+						throwBacktrack(secondFailure);
+					else
+						throwBacktrack(b3);
+					return null;
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * 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.
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected IASTDeclaration namespaceDefinitionOrAlias()
+			throws BacktrackException, EndOfFileException {
+
+		IToken first = consume(IToken.t_namespace);
+		int last = first.getEndOffset();
+		IASTName name = null;
+		// optional name
+		if (LT(1) == IToken.tIDENTIFIER) {
+			name = createName(identifier());
+			last = calculateEndOffset(name);
+		} else
+			name = createName();
+
+		if (LT(1) == IToken.tLBRACE) {
+			consume();
+			ICPPASTNamespaceDefinition namespaceDefinition = createNamespaceDefinition();
+			((ASTNode) namespaceDefinition).setOffset(first.getOffset());
+			namespaceDefinition.setName(name);
+			name.setParent(namespaceDefinition);
+			name.setPropertyInParent(ICPPASTNamespaceDefinition.NAMESPACE_NAME);
+
+			namespaceDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
+				int checkToken = LA(1).hashCode();
+				switch (LT(1)) {
+				case IToken.tRBRACE:
+					break namespaceDeclarationLoop;
+				default:
+					try {
+						IASTDeclaration d = declaration();
+						d.setParent(namespaceDefinition);
+						d
+								.setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION);
+						namespaceDefinition.addDeclaration(d);
+					} catch (BacktrackException bt) {
+						IASTProblem p = failParse(bt);
+						IASTProblemDeclaration pd = createProblemDeclaration();
+						p.setParent(pd);
+						pd.setProblem(p);
+						((CPPASTNode) pd).setOffsetAndLength((CPPASTNode) p);
+						p.setPropertyInParent(IASTProblemHolder.PROBLEM);
+						namespaceDefinition.addDeclaration(pd);
+						pd.setParent(namespaceDefinition);
+						pd
+								.setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION);
+						errorHandling();
+						if (checkToken == LA(1).hashCode())
+							errorHandling();
+					}
+				}
+				if (checkToken == LA(1).hashCode())
+					failParseWithErrorHandling();
+			}
+
+			// consume the }
+			int end = consume(IToken.tRBRACE).getEndOffset();
+			((CPPASTNode) namespaceDefinition).setLength(end
+					- first.getOffset());
+			return namespaceDefinition;
+		} else if (LT(1) == IToken.tASSIGN) {
+			IToken assign = consume(IToken.tASSIGN);
+
+			if (name.toString() == null) {
+				throwBacktrack(first.getOffset(), assign.getEndOffset()
+						- first.getOffset());
+				return null;
+			}
+
+			ITokenDuple duple = name();
+			IASTName qualifiedName = createName(duple);
+			int end = consume(IToken.tSEMI).getEndOffset();
+
+			ICPPASTNamespaceAlias alias = createNamespaceAlias();
+			((ASTNode) alias).setOffsetAndLength(first.getOffset(), end
+					- first.getOffset());
+			alias.setAlias(name);
+			name.setParent(alias);
+			name.setPropertyInParent(ICPPASTNamespaceAlias.ALIAS_NAME);
+			alias.setMappingName(qualifiedName);
+			qualifiedName.setParent(alias);
+			qualifiedName
+					.setPropertyInParent(ICPPASTNamespaceAlias.MAPPING_NAME);
+			return alias;
+		} else {
+			throwBacktrack(first.getOffset(), last - first.getOffset());
+			return null;
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTNamespaceAlias createNamespaceAlias() {
+		return new CPPASTNamespaceAlias();
+	}
+
+	/**
+	 * @param duple
+	 * @return
+	 */
+	protected ICPPASTQualifiedName createQualifiedName(ITokenDuple duple) {
+		CPPASTQualifiedName result = new CPPASTQualifiedName();
+		result.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
+				- duple.getStartOffset());
+		result.setValue(duple.toString());
+		ITokenDuple[] segments = duple.getSegments();
+		int startingValue = 0;
+		if (segments.length > 0 && segments[0] instanceof IToken
+				&& ((IToken) segments[0]).getType() == IToken.tCOLONCOLON) {
+			++startingValue;
+			result.setFullyQualified(true);
+		}
+		for (int i = startingValue; i < segments.length; ++i) {
+			IASTName subName = null;
+			// take each name and add it to the result
+			if (segments[i] instanceof IToken) {
+				subName = createName((IToken) segments[i]);
+			} else if (segments[i].getTemplateIdArgLists() == null)
+				subName = createName(segments[i]);
+			else
+				// templateID
+				subName = createTemplateID(segments[i]);
+
+			if (i == segments.length - 1 && duple instanceof OperatorTokenDuple) { // make
+				// sure
+				// the
+				// last
+				// segment
+				// is
+				// an
+				// OperatorName/ConversionName
+				subName = createOperatorName((OperatorTokenDuple) duple,
+						subName);
+			}
+
+			subName.setParent(result);
+			subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME);
+			((ASTNode) subName).setOffsetAndLength(
+					segments[i].getStartOffset(), segments[i].getEndOffset()
+							- segments[i].getStartOffset());
+			result.addName(subName);
+		}
+		return result;
+	}
+
+	/**
+	 * @param duple
+	 * @return
+	 */
+	protected ICPPASTTemplateId createTemplateID(ITokenDuple duple) {
+		ICPPASTTemplateId result = new CPPASTTemplateId();
+		((ASTNode) result).setOffsetAndLength(duple.getStartOffset(), duple
+				.getEndOffset()
+				- duple.getStartOffset());
+		char[] image = duple.extractNameFromTemplateId();
+		CPPASTName templateIdName = (CPPASTName) createName();
+		templateIdName.setOffsetAndLength(duple.getStartOffset(), image.length);
+		templateIdName.setName(image);
+		result.setTemplateName(templateIdName);
+		templateIdName.setParent(result);
+		templateIdName.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_NAME);
+		if (duple.getTemplateIdArgLists() != null) {
+			List args = duple.getTemplateIdArgLists()[0];
+			if (args != null)
+				for (int i = 0; i < args.size(); ++i) {
+					IASTNode n = (IASTNode) args.get(i);
+					if (n instanceof IASTTypeId || n instanceof IASTExpression) {
+						n.setParent(result);
+						n
+								.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT);
+						if (n instanceof IASTTypeId)
+							result.addTemplateArgument((IASTTypeId) n);
+						else
+							result.addTemplateArgument((IASTExpression) n);
+					}
+				}
+		}
+		return result;
+	}
+
+	/**
+	 * @param duple
+	 * @return
+	 */
+	protected IASTName createName(ITokenDuple duple) {
+		if (duple == null)
+			return createName();
+		if (duple.getSegmentCount() != 1)
+			return createQualifiedName(duple);
+		if (duple.getTemplateIdArgLists() != null)
+			return createTemplateID(duple);
+
+		// We're a single name
+		IASTName name = new CPPASTName(duple.toCharArray());
+		if (duple instanceof OperatorTokenDuple) {
+			name = createOperatorName((OperatorTokenDuple) duple, name);
+		}
+
+		IToken token = duple.getFirstToken();
+		switch (token.getType()) {
+		case IToken.tCOMPLETION:
+		case IToken.tEOC:
+			createCompletionNode(token).addName(name);
+			break;
+		}
+
+		((ASTNode) name).setOffsetAndLength(duple.getStartOffset(), duple
+				.getEndOffset()
+				- duple.getStartOffset());
+
+		return name;
+	}
+
+	protected IASTName createOperatorName(OperatorTokenDuple duple,
+			IASTName name) {
+		IASTName aName = null;
+
+		if (duple.isConversionOperator()) {
+			aName = new CPPASTConversionName(name.toCharArray());
+			IASTTypeId typeId = duple.getTypeId();
+			typeId.setParent(aName);
+			typeId.setPropertyInParent(ICPPASTConversionName.TYPE_ID);
+			((CPPASTConversionName) aName).setTypeId(typeId);
+		} else {
+			aName = new CPPASTOperatorName(name.toCharArray());
+		}
+
+		if (name instanceof ICPPASTTemplateId) {
+			((ICPPASTTemplateId) name).setTemplateName(aName);
+			return name;
+		}
+
+		return aName;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTNamespaceDefinition createNamespaceDefinition() {
+		return new CPPASTNamespaceDefinition();
+	}
+
+	/**
+	 * 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)
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected IASTDeclaration simpleDeclaration(
+			SimpleDeclarationStrategy strategy, boolean fromCatchHandler)
+			throws BacktrackException, EndOfFileException {
+		IToken firstToken = LA(1);
+		int firstOffset = firstToken.getOffset();
+		if (firstToken.getType() == IToken.tLBRACE)
+			throwBacktrack(firstOffset, firstToken.getLength());
+		firstToken = null; // necessary for scalability
+
+		ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false,
+				strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR);
+		IASTDeclarator[] declarators = new IASTDeclarator[2];
+		if (LT(1) != IToken.tSEMI && LT(1) != IToken.tEOC) {
+			declarators = (IASTDeclarator[]) ArrayUtil
+					.append(IASTDeclarator.class, declarators,
+							initDeclarator(strategy));
+			while (LT(1) == IToken.tCOMMA) {
+				consume(IToken.tCOMMA);
+				declarators = (IASTDeclarator[]) ArrayUtil.append(
+						IASTDeclarator.class, declarators,
+						initDeclarator(strategy));
+			}
+		}
+
+		declarators = (IASTDeclarator[]) ArrayUtil.removeNulls(
+				IASTDeclarator.class, declarators);
+
+		boolean hasFunctionBody = false;
+		boolean hasFunctionTryBlock = false;
+		boolean consumedSemi = false;
+		int semiOffset = 0;
+		List constructorChain = Collections.EMPTY_LIST;
+
+		switch (LT(1)) {
+		case IToken.tSEMI:
+			semiOffset = consume(IToken.tSEMI).getEndOffset();
+			consumedSemi = true;
+			break;
+		case IToken.t_try:
+			consume(IToken.t_try);
+			if (LT(1) == IToken.tCOLON) {
+				constructorChain = new ArrayList(
+						DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
+				ctorInitializer(constructorChain);
+			}
+			hasFunctionTryBlock = true;
+			break;
+		case IToken.tCOLON:
+			constructorChain = new ArrayList(
+					DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
+			ctorInitializer(constructorChain);
+			break;
+		case IToken.tLBRACE:
+			break;
+		case IToken.tRPAREN:
+			if (!fromCatchHandler)
+				throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+			break;
+		case IToken.tEOC:
+			// Pretend we consumed the semi
+			consumedSemi = true;
+			break;
+		default:
+			throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+		}
+
+		if (!consumedSemi) {
+			if (LT(1) == IToken.tLBRACE) {
+				hasFunctionBody = true;
+			}
+
+			if (hasFunctionTryBlock && !hasFunctionBody)
+				throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+		}
+
+		if (hasFunctionBody) {
+			if (declarators.length != 1)
+				throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+
+			IASTDeclarator declarator = declarators[0];
+			if (!(declarator instanceof IASTStandardFunctionDeclarator))
+				throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+
+			if (!constructorChain.isEmpty()
+					&& declarator instanceof ICPPASTFunctionDeclarator) {
+				ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator;
+
+				int size = constructorChain.size();
+				for (int i = 0; i < size; ++i) {
+					ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) constructorChain
+							.get(i);
+					fd.addConstructorToChain(initializer);
+					initializer.setParent(fd);
+					initializer
+							.setPropertyInParent(ICPPASTFunctionDeclarator.CONSTRUCTOR_CHAIN_MEMBER);
+				}
+
+				// fix for 86698, now that the constructorChain is established,
+				// update the declarator's length
+				if (fd instanceof ASTNode
+						&& constructorChain.get(size - 1) instanceof ASTNode) {
+					ASTNode init = (ASTNode) constructorChain.get(size - 1);
+					((ASTNode) fd).setLength(init.getOffset()
+							+ init.getLength() - ((ASTNode) fd).getOffset());
+				}
+			}
+
+			IASTFunctionDefinition funcDefinition = createFunctionDefinition();
+			((ASTNode) funcDefinition).setOffset(firstOffset);
+			funcDefinition.setDeclSpecifier(declSpec);
+			declSpec.setParent(funcDefinition);
+			declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER);
+
+			funcDefinition
+					.setDeclarator((IASTStandardFunctionDeclarator) declarator);
+			declarator.setParent(funcDefinition);
+			declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR);
+
+			IASTStatement s = handleFunctionBody();
+			if (s != null) {
+				funcDefinition.setBody(s);
+				s.setParent(funcDefinition);
+				s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY);
+			}
+			((CPPASTNode) funcDefinition).setLength(calculateEndOffset(s)
+					- firstOffset);
+
+			if (hasFunctionTryBlock
+					&& declarator instanceof ICPPASTFunctionTryBlockDeclarator) {
+				List handlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE);
+				catchHandlerSequence(handlers);
+				for (int i = 0; i < handlers.size(); ++i) {
+					ICPPASTCatchHandler handler = (ICPPASTCatchHandler) handlers
+							.get(i);
+					((ICPPASTFunctionTryBlockDeclarator) declarator)
+							.addCatchHandler(handler);
+					handler.setParent(declarator);
+					handler
+							.setPropertyInParent(ICPPASTFunctionTryBlockDeclarator.CATCH_HANDLER);
+					((CPPASTNode) funcDefinition)
+							.setLength(calculateEndOffset(handler)
+									- firstOffset);
+
+				}
+
+			}
+			return funcDefinition;
+		}
+
+		IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration();
+		int length = figureEndOffset(declSpec, declarators) - firstOffset;
+		if (consumedSemi)
+			length = semiOffset - firstOffset;
+
+		((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, length);
+		simpleDeclaration.setDeclSpecifier(declSpec);
+		declSpec.setParent(simpleDeclaration);
+		declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER);
+
+		for (int i = 0; i < declarators.length; ++i) {
+			IASTDeclarator declarator = declarators[i];
+			simpleDeclaration.addDeclarator(declarator);
+			declarator.setParent(simpleDeclaration);
+			declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR);
+		}
+		return simpleDeclaration;
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTFunctionDefinition createFunctionDefinition() {
+		return new CPPASTFunctionDefinition();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTSimpleDeclaration createSimpleDeclaration() {
+		return new CPPASTSimpleDeclaration();
+	}
+
+	/**
+	 * 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(List collection) throws EndOfFileException,
+			BacktrackException {
+		consume(IToken.tCOLON);
+		for (;;) {
+			if (LT(1) == IToken.tLBRACE)
+				break;
+			ITokenDuple duple = name();
+			IASTName name = createName(duple);
+
+			consume(IToken.tLPAREN);
+			IASTExpression expressionList = null;
+
+			if (LT(1) != IToken.tRPAREN)
+				expressionList = expression();
+
+			int end = consume(IToken.tRPAREN).getEndOffset();
+			ICPPASTConstructorChainInitializer ctorInitializer = createConstructorChainInitializer();
+			((ASTNode) ctorInitializer).setOffsetAndLength(duple
+					.getStartOffset(), end - duple.getStartOffset());
+			ctorInitializer.setMemberInitializerId(name);
+			name.setParent(ctorInitializer);
+			name
+					.setPropertyInParent(ICPPASTConstructorChainInitializer.MEMBER_ID);
+
+			if (expressionList != null) {
+				ctorInitializer.setInitializerValue(expressionList);
+				expressionList.setParent(ctorInitializer);
+				expressionList
+						.setPropertyInParent(ICPPASTConstructorChainInitializer.INITIALIZER);
+			}
+			collection.add(ctorInitializer);
+			if (LT(1) == IToken.tLBRACE)
+				break;
+			consume(IToken.tCOMMA);
+		}
+
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTConstructorChainInitializer createConstructorChainInitializer() {
+		return new CPPASTConstructorChainInitializer();
+	}
+
+	/**
+	 * This routine parses a parameter declaration
+	 * 
+	 * @param containerObject
+	 *            The IParserCallback object representing the
+	 *            parameterDeclarationClause owning the parm.
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected ICPPASTParameterDeclaration parameterDeclaration()
+			throws BacktrackException, EndOfFileException {
+		IToken current = LA(1);
+		IASTDeclSpecifier declSpec = declSpecifierSeq(true, false);
+		IASTDeclarator declarator = null;
+		if (LT(1) != IToken.tSEMI)
+			declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
+
+		if (current == LA(1)) {
+			throwBacktrack(current.getOffset(), figureEndOffset(declSpec,
+					declarator)
+					- current.getOffset());
+		}
+		ICPPASTParameterDeclaration parm = createParameterDeclaration();
+		((ASTNode) parm).setOffsetAndLength(current.getOffset(),
+				figureEndOffset(declSpec, declarator) - current.getOffset());
+		parm.setDeclSpecifier(declSpec);
+		declSpec.setParent(parm);
+		declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER);
+		if (declarator != null) {
+			parm.setDeclarator(declarator);
+			declarator.setParent(parm);
+			declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR);
+		}
+		return parm;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTParameterDeclaration createParameterDeclaration() {
+		return new CPPASTParameterDeclaration();
+	}
+
+	/**
+	 * @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
+	 */
+	protected boolean lookAheadForConstructorOrOperator(Flags flags)
+			throws EndOfFileException {
+		if (flags.isForParameterDeclaration())
+			return false;
+		if (LT(2) == IToken.tLPAREN && flags.isForConstructor())
+			return true;
+
+		IToken mark = mark();
+		IASTName name = null;
+		try {
+			name = consumeTemplatedOperatorName();
+		} catch (BacktrackException e) {
+			backup(mark);
+			return false;
+		} catch (EndOfFileException eof) {
+			backup(mark);
+			return false;
+		}
+
+		if (name == null) {
+			backup(mark);
+			return false;
+		}
+
+		// constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be
+		// defined for the global scope)
+		if (name instanceof ICPPASTQualifiedName) {
+			IASTName[] segments = ((ICPPASTQualifiedName) name).getNames();
+
+			int len = segments.length;
+			if (len >= 2) {
+				if (segments[0].toString().length() == 0) {
+					backup(mark);
+					return false;
+				}
+
+				if (((ICPPASTQualifiedName) name).isConversionOrOperator()) { // conversion
+					// or
+					// operator
+					backup(mark);
+					return true;
+				}
+
+				if (segments[len - 1].toString().equals(
+						segments[len - 2].toString())) { // constructor
+					backup(mark);
+					return true;
+				}
+
+				StringBuffer destructorName = new StringBuffer();
+				destructorName.append(COMPL);
+				destructorName.append(segments[len - 2]);
+				if (segments[len - 1].toString().equals(
+						destructorName.toString())) { // destructor
+					backup(mark);
+					return true;
+				}
+			} else {
+				backup(mark);
+				return false;
+			}
+		} else {
+			backup(mark);
+			return false;
+		}
+
+		backup(mark);
+		return false;
+	}
+
+	/**
+	 * 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 parm
+	 *            Is this for a parameter declaration (true) or simple
+	 *            declaration (false)
+	 * @param tryConstructor
+	 *            true for constructor, false for pointer to function strategy
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm,
+			boolean tryConstructor) throws BacktrackException,
+			EndOfFileException {
+		IToken firstToken = LA(1);
+		Flags flags = new Flags(parm, tryConstructor);
+		IToken last = null;
+
+		boolean isInline = false, isVirtual = false, isExplicit = false, isFriend = false;
+		boolean isConst = false, isVolatile = false, isRestrict = false;
+		boolean isLong = false, isShort = false, isUnsigned = false, isSigned = false, isLongLong = false;
+		boolean isTypename = false;
+
+		int storageClass = IASTDeclSpecifier.sc_unspecified;
+		int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
+		ITokenDuple duple = null;
+
+		ICPPASTCompositeTypeSpecifier classSpec = null;
+		ICPPASTElaboratedTypeSpecifier elabSpec = null;
+		IASTEnumerationSpecifier enumSpec = null;
+		IASTExpression typeofExpression = null;
+		int startOffset = firstToken.getOffset();
+
+		declSpecifiers: for (;;) {
+			switch (LT(1)) {
+			case IToken.t_inline:
+				last = consume();
+				isInline = true;
+				break;
+			case IToken.t_typedef:
+				storageClass = IASTDeclSpecifier.sc_typedef;
+				last = consume();
+				break;
+			case IToken.t_auto:
+				last = consume();
+				storageClass = IASTDeclSpecifier.sc_auto;
+				break;
+			case IToken.t_register:
+				last = consume();
+				storageClass = IASTDeclSpecifier.sc_register;
+				break;
+			case IToken.t_static:
+				storageClass = IASTDeclSpecifier.sc_static;
+				last = consume();
+				break;
+			case IToken.t_extern:
+				storageClass = IASTDeclSpecifier.sc_extern;
+				last = consume();
+				break;
+			case IToken.t_mutable:
+				storageClass = ICPPASTDeclSpecifier.sc_mutable;
+				last = consume();
+				break;
+			case IToken.t_virtual:
+				isVirtual = true;
+				last = consume();
+				break;
+			case IToken.t_explicit:
+				isExplicit = true;
+				last = consume();
+				break;
+			case IToken.t_friend:
+				isFriend = true;
+				last = consume();
+				break;
+			case IToken.t_const:
+				isConst = true;
+				last = consume();
+				break;
+			case IToken.t_volatile:
+				isVolatile = true;
+				last = consume();
+				break;
+			case IToken.t_restrict:
+				if (!supportRestrict) {
+					IToken la = LA(1);
+					throwBacktrack(la.getOffset(), la.getEndOffset()
+							- la.getOffset());
+				}
+				isRestrict = true;
+				last = consume();
+				break;
+			case IToken.t_signed:
+				isSigned = true;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_unsigned:
+				isUnsigned = true;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_short:
+				isShort = true;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_long:
+				if (isLong && supportLongLong) {
+					isLong = false;
+					isLongLong = true;
+				} else
+					isLong = true;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t__Complex:
+				if (!supportComplex) {
+					IToken la = LA(1);
+					throwBacktrack(la.getOffset(), la.getEndOffset()
+							- la.getOffset());
+				}
+				last = consume(IToken.t__Complex);
+				simpleType = IGPPASTSimpleDeclSpecifier.t_Complex;
+				break;
+			case IToken.t__Imaginary:
+				if (!supportComplex) {
+					IToken la = LA(1);
+					throwBacktrack(la.getOffset(), la.getLength());
+				}
+				last = consume(IToken.t__Imaginary);
+				simpleType = IGPPASTSimpleDeclSpecifier.t_Imaginary;
+				break;
+			case IToken.t_char:
+				simpleType = IASTSimpleDeclSpecifier.t_char;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_wchar_t:
+				simpleType = ICPPASTSimpleDeclSpecifier.t_wchar_t;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_bool:
+				simpleType = ICPPASTSimpleDeclSpecifier.t_bool;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_int:
+				flags.setEncounteredRawType(true);
+				last = consume();
+				simpleType = IASTSimpleDeclSpecifier.t_int;
+				break;
+			case IToken.t_float:
+				simpleType = IASTSimpleDeclSpecifier.t_float;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_double:
+				simpleType = IASTSimpleDeclSpecifier.t_double;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_void:
+				simpleType = IASTSimpleDeclSpecifier.t_void;
+				flags.setEncounteredRawType(true);
+				last = consume();
+				break;
+			case IToken.t_typename:
+				isTypename = true;
+				last = consume(IToken.t_typename);
+				duple = name();
+				flags.setEncounteredTypename(true);
+				break;
+			case IToken.tCOLONCOLON:
+			case IToken.tIDENTIFIER:
+				// TODO - Kludgy way to handle constructors/destructors
+				if (flags.haveEncounteredRawType())
+					break declSpecifiers;
+
+				if (parm && flags.haveEncounteredTypename())
+					break declSpecifiers;
+
+				if (lookAheadForConstructorOrOperator(flags))
+					break declSpecifiers;
+
+				if (lookAheadForDeclarator(flags))
+					break declSpecifiers;
+
+				duple = name();
+				last = duple.getLastToken();
+				flags.setEncounteredTypename(true);
+				break;
+			case IToken.t_class:
+			case IToken.t_struct:
+			case IToken.t_union:
+				if (flags.haveEncounteredTypename())
+					throwBacktrack(LA(1));
+				try {
+					classSpec = classSpecifier();
+					flags.setEncounteredTypename(true);
+					break;
+				} catch (BacktrackException bt) {
+					elabSpec = elaboratedTypeSpecifier();
+					flags.setEncounteredTypename(true);
+					break;
+				}
+			case IToken.t_enum:
+				if (flags.haveEncounteredTypename())
+					throwBacktrack(LA(1));
+				try {
+					enumSpec = enumSpecifier();
+					flags.setEncounteredTypename(true);
+					break;
+				} catch (BacktrackException bt) {
+					// this is an elaborated class specifier
+					elabSpec = elaboratedTypeSpecifier();
+					flags.setEncounteredTypename(true);
+					break;
+				}
+			default:
+				if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
+					typeofExpression = unaryTypeofExpression();
+					if (typeofExpression != null) {
+						flags.setEncounteredTypename(true);
+					}
+				}
+				break declSpecifiers;
+			}
+		}
+
+		if (elabSpec != null) {
+			elabSpec.setConst(isConst);
+			elabSpec.setVolatile(isVolatile);
+			if (elabSpec instanceof IGPPASTDeclSpecifier)
+				((IGPPASTDeclSpecifier) elabSpec).setRestrict(isRestrict);
+			elabSpec.setFriend(isFriend);
+			elabSpec.setInline(isInline);
+			elabSpec.setStorageClass(storageClass);
+			elabSpec.setVirtual(isVirtual);
+			elabSpec.setExplicit(isExplicit);
+			((CPPASTNode) elabSpec).setOffsetAndLength(startOffset,
+					calculateEndOffset(elabSpec) - startOffset);
+			return elabSpec;
+		}
+		if (enumSpec != null) {
+			enumSpec.setConst(isConst);
+			enumSpec.setVolatile(isVolatile);
+			if (enumSpec instanceof IGPPASTDeclSpecifier)
+				((IGPPASTDeclSpecifier) enumSpec).setRestrict(isRestrict);
+			((ICPPASTDeclSpecifier) enumSpec).setFriend(isFriend);
+			((ICPPASTDeclSpecifier) enumSpec).setVirtual(isVirtual);
+			((ICPPASTDeclSpecifier) enumSpec).setExplicit(isExplicit);
+			enumSpec.setInline(isInline);
+			enumSpec.setStorageClass(storageClass);
+			((CPPASTNode) enumSpec).setOffsetAndLength(startOffset,
+					calculateEndOffset(enumSpec) - startOffset);
+			return (ICPPASTDeclSpecifier) enumSpec;
+		}
+		if (classSpec != null) {
+			classSpec.setConst(isConst);
+			classSpec.setVolatile(isVolatile);
+			if (classSpec instanceof IGPPASTDeclSpecifier)
+				((IGPPASTDeclSpecifier) classSpec).setRestrict(isRestrict);
+			classSpec.setFriend(isFriend);
+			classSpec.setInline(isInline);
+			classSpec.setStorageClass(storageClass);
+			classSpec.setVirtual(isVirtual);
+			classSpec.setExplicit(isExplicit);
+			((CPPASTNode) classSpec).setOffsetAndLength(startOffset,
+					calculateEndOffset(classSpec) - startOffset);
+			return classSpec;
+		}
+		if (duple != null) {
+			ICPPASTNamedTypeSpecifier nameSpec = (ICPPASTNamedTypeSpecifier) createNamedTypeSpecifier();
+			nameSpec.setIsTypename(isTypename);
+			IASTName name = createName(duple);
+			nameSpec.setName(name);
+			name.setParent(nameSpec);
+			name.setPropertyInParent(IASTNamedTypeSpecifier.NAME);
+
+			nameSpec.setConst(isConst);
+			nameSpec.setVolatile(isVolatile);
+			if (nameSpec instanceof IGPPASTDeclSpecifier)
+				((IGPPASTDeclSpecifier) nameSpec).setRestrict(isRestrict);
+			nameSpec.setFriend(isFriend);
+			nameSpec.setInline(isInline);
+			nameSpec.setStorageClass(storageClass);
+			nameSpec.setVirtual(isVirtual);
+			nameSpec.setExplicit(isExplicit);
+			((CPPASTNode) nameSpec).setOffsetAndLength(startOffset, last
+					.getEndOffset()
+					- startOffset);
+			return nameSpec;
+		}
+		ICPPASTSimpleDeclSpecifier simpleDeclSpec = null;
+		if (isLongLong || typeofExpression != null) {
+			simpleDeclSpec = createGPPSimpleDeclSpecifier();
+			((IGPPASTSimpleDeclSpecifier) simpleDeclSpec)
+					.setLongLong(isLongLong);
+			if (typeofExpression != null) {
+				((IGPPASTSimpleDeclSpecifier) simpleDeclSpec)
+						.setTypeofExpression(typeofExpression);
+				typeofExpression.setParent(simpleDeclSpec);
+				typeofExpression
+						.setPropertyInParent(IGPPASTSimpleDeclSpecifier.TYPEOF_EXPRESSION);
+			}
+		} else
+			simpleDeclSpec = createSimpleDeclSpecifier();
+
+		int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0;
+		((ASTNode) simpleDeclSpec)
+				.setOffsetAndLength(firstToken.getOffset(), l);
+		simpleDeclSpec.setConst(isConst);
+		simpleDeclSpec.setVolatile(isVolatile);
+		if (simpleDeclSpec instanceof IGPPASTDeclSpecifier)
+			((IGPPASTDeclSpecifier) simpleDeclSpec).setRestrict(isRestrict);
+
+		simpleDeclSpec.setFriend(isFriend);
+		simpleDeclSpec.setInline(isInline);
+		simpleDeclSpec.setStorageClass(storageClass);
+		simpleDeclSpec.setVirtual(isVirtual);
+		simpleDeclSpec.setExplicit(isExplicit);
+
+		simpleDeclSpec.setType(simpleType);
+		simpleDeclSpec.setLong(isLong);
+		simpleDeclSpec.setShort(isShort);
+		simpleDeclSpec.setUnsigned(isUnsigned);
+		simpleDeclSpec.setSigned(isSigned);
+
+		return simpleDeclSpec;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() {
+		return new GPPASTSimpleDeclSpecifier();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTSimpleDeclSpecifier createSimpleDeclSpecifier() {
+		return new CPPASTSimpleDeclSpecifier();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTNamedTypeSpecifier createNamedTypeSpecifier() {
+		return new CPPASTNamedTypeSpecifier();
+	}
+
+	/**
+	 * Parse an elaborated type specifier.
+	 * 
+	 * @param decl
+	 *            Declaration which owns the elaborated type
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier()
+			throws BacktrackException, EndOfFileException {
+		// this is an elaborated class specifier
+		IToken t = consume();
+		int eck = 0;
+
+		switch (t.getType()) {
+		case IToken.t_class:
+			eck = ICPPASTElaboratedTypeSpecifier.k_class;
+			break;
+		case IToken.t_struct:
+			eck = IASTElaboratedTypeSpecifier.k_struct;
+			break;
+		case IToken.t_union:
+			eck = IASTElaboratedTypeSpecifier.k_union;
+			break;
+		case IToken.t_enum:
+			eck = IASTElaboratedTypeSpecifier.k_enum;
+			break;
+		default:
+			backup(t);
+			throwBacktrack(t.getOffset(), t.getLength());
+		}
+
+		IASTName name = createName(name());
+
+		ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = createElaboratedTypeSpecifier();
+		((ASTNode) elaboratedTypeSpec).setOffsetAndLength(t.getOffset(),
+				calculateEndOffset(name) - t.getOffset());
+		elaboratedTypeSpec.setKind(eck);
+		elaboratedTypeSpec.setName(name);
+		name.setParent(elaboratedTypeSpec);
+		name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME);
+		return elaboratedTypeSpec;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() {
+		return new CPPASTElaboratedTypeSpecifier();
+	}
+
+	/**
+	 * Parses the initDeclarator construct of the ANSI C++ spec. initDeclarator :
+	 * declarator ("=" initializerClause | "(" expressionList ")")?
+	 * 
+	 * @param constructInitializers
+	 *            TODO
+	 * @param owner
+	 *            IParserCallback object that represents the owner declaration
+	 *            object.
+	 * @return declarator that this parsing produced.
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy)
+			throws EndOfFileException, BacktrackException {
+		IASTDeclarator d = declarator(strategy, false, false);
+
+		IASTInitializer initializer = optionalCPPInitializer(d);
+		if (initializer != null) {
+			d.setInitializer(initializer);
+			initializer.setParent(d);
+			initializer.setPropertyInParent(IASTDeclarator.INITIALIZER);
+			((ASTNode) d).setLength(calculateEndOffset(initializer)
+					- ((ASTNode) d).getOffset());
+		}
+
+		return d;
+	}
+
+	protected IASTInitializer optionalCPPInitializer(IASTDeclarator d)
+			throws EndOfFileException, BacktrackException {
+		// handle initializer
+
+		if (LT(1) == IToken.tASSIGN) {
+			consume(IToken.tASSIGN);
+			throwAwayMarksForInitializerClause();
+			try {
+				return initializerClause();
+			} catch (EndOfFileException eof) {
+				failParse();
+				throw eof;
+			}
+		} else if (LT(1) == IToken.tLPAREN) {
+			if (d instanceof IASTFunctionDeclarator
+					&& d.getNestedDeclarator() == null) {
+				// constructor initializer doesn't make sense for a function
+				// declarator,
+				// we must have an object to initialize, a function doesn't
+				// work.
+				return null;
+			}
+			// initializer in constructor
+			int o = consume(IToken.tLPAREN).getOffset(); // EAT IT!
+			IASTExpression astExpression = expression();
+			int l = consume(IToken.tRPAREN).getEndOffset();
+			ICPPASTConstructorInitializer result = createConstructorInitializer();
+			((ASTNode) result).setOffsetAndLength(o, l - o);
+			result.setExpression(astExpression);
+			astExpression.setParent(result);
+			astExpression
+					.setPropertyInParent(ICPPASTConstructorInitializer.EXPRESSION);
+			return result;
+		}
+		return null;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTConstructorInitializer createConstructorInitializer() {
+		return new CPPASTConstructorInitializer();
+	}
+
+	/**
+	 *  
+	 */
+	protected IASTInitializer initializerClause() throws EndOfFileException,
+			BacktrackException {
+		if (LT(1) == IToken.tLBRACE) {
+			int startingOffset = consume(IToken.tLBRACE).getOffset();
+
+			IASTInitializerList result = createInitializerList();
+			((ASTNode) result).setOffset(startingOffset);
+
+			if (LT(1) == (IToken.tRBRACE)) {
+				int l = consume(IToken.tRBRACE).getEndOffset();
+				((ASTNode) result).setLength(l - startingOffset);
+				return result;
+			}
+
+			// otherwise it is a list of initializer clauses
+
+			for (;;) {
+				if (LT(1) == IToken.tRBRACE)
+					break;
+
+				IASTInitializer clause = initializerClause();
+				if (clause != null) {
+					result.addInitializer(clause);
+					clause.setParent(result);
+					clause
+							.setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER);
+				}
+				if (LT(1) == IToken.tRBRACE)
+					break;
+				consume(IToken.tCOMMA);
+			}
+			int l = consume(IToken.tRBRACE).getEndOffset();
+			((ASTNode) result).setLength(l - startingOffset);
+			return result;
+		}
+
+		// if we get this far, it means that we did not
+		// try this now instead
+		// assignmentExpression
+		IASTExpression assignmentExpression = assignmentExpression();
+		IASTInitializerExpression result = createInitializerExpression();
+		((ASTNode) result).setOffsetAndLength(((ASTNode) assignmentExpression));
+		result.setExpression(assignmentExpression);
+		assignmentExpression.setParent(result);
+		assignmentExpression
+				.setPropertyInParent(IASTInitializerExpression.INITIALIZER_EXPRESSION);
+		return result;
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTInitializerList createInitializerList() {
+		return new CPPASTInitializerList();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTInitializerExpression createInitializerExpression() {
+		return new CPPASTInitializerExpression();
+	}
+
+	/**
+	 * 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 forTypeID
+	 *            TODO
+	 * @param skipArrayDeclarator
+	 *            TODO
+	 * @param container
+	 *            IParserCallback object that represents the owner declaration.
+	 * @return declarator that this parsing produced.
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy,
+			boolean forTypeID, boolean skipArrayDeclarator)
+			throws EndOfFileException, BacktrackException {
+
+		IToken la = LA(1);
+		int startingOffset = la.getOffset();
+		la = null;
+		IASTDeclarator innerDecl = null;
+		IASTName declaratorName = null;
+		List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
+		List parameters = Collections.EMPTY_LIST;
+		List arrayMods = Collections.EMPTY_LIST;
+		List exceptionSpecIds = Collections.EMPTY_LIST;
+		boolean encounteredVarArgs = false;
+		boolean tryEncountered = false;
+		IASTExpression bitField = null;
+		boolean isFunction = false;
+		boolean isPureVirtual = false, isConst = false, isVolatile = false;
+		int finalOffset = startingOffset;
+		overallLoop: do {
+
+			consumePointerOperators(pointerOps);
+			if (!pointerOps.isEmpty())
+				finalOffset = calculateEndOffset((IASTNode) pointerOps
+						.get(pointerOps.size() - 1));
+
+			if (!forTypeID && LT(1) == IToken.tLPAREN) {
+				IToken mark = mark();
+				try {
+					consume();
+					innerDecl = declarator(strategy, forTypeID,
+							skipArrayDeclarator);
+					finalOffset = consume(IToken.tRPAREN).getEndOffset();
+				} catch (BacktrackException bte) {
+					backup(mark);
+				}
+				declaratorName = createName();
+			} else {
+				try {
+					declaratorName = consumeTemplatedOperatorName();
+					finalOffset = calculateEndOffset(declaratorName);
+					if (declaratorName instanceof ICPPASTQualifiedName
+							&& ((ICPPASTQualifiedName) declaratorName)
+									.isConversionOrOperator())
+						isFunction = true;
+				} catch (BacktrackException bt) {
+					declaratorName = createName();
+				}
+			}
+
+			for (;;) {
+				switch (LT(1)) {
+				case IToken.tLPAREN:
+
+					boolean failed = false;
+
+					// temporary fix for initializer/function declaration
+					// ambiguity
+					if (!LA(2).looksLikeExpression()
+							&& strategy != SimpleDeclarationStrategy.TRY_VARIABLE) {
+						if (LT(2) == IToken.tIDENTIFIER) {
+							IToken newMark = mark();
+							consume(IToken.tLPAREN);
+							try {
+								name();
+								// TODO - we need to lookup/resolve this name
+								// see if its a type ...
+								// if it is a type, failed = false
+								// else failed = true
+								failed = false;
+							} catch (BacktrackException b) {
+								failed = true;
+							}
+
+							backup(newMark);
+						}
+					}
+					if ((!LA(2).looksLikeExpression()
+							&& strategy != SimpleDeclarationStrategy.TRY_VARIABLE
+							&& !failed && !forTypeID)) {
+						// parameterDeclarationClause
+						isFunction = true;
+						// TODO need to create a temporary scope object here
+						IToken last = consume(IToken.tLPAREN);
+						finalOffset = last.getEndOffset();
+						boolean seenParameter = false;
+						parameterDeclarationLoop: for (;;) {
+							switch (LT(1)) {
+							case IToken.tRPAREN:
+								last = consume();
+								finalOffset = last.getEndOffset();
+								break parameterDeclarationLoop;
+							case IToken.tELLIPSIS:
+								last = consume();
+								encounteredVarArgs = true;
+								finalOffset = last.getEndOffset();
+								break;
+							case IToken.tCOMMA:
+								last = consume();
+								seenParameter = false;
+								finalOffset = last.getEndOffset();
+								break;
+							default:
+								int endOffset = (last != null) ? last
+										.getEndOffset() : LA(1).getEndOffset();
+								if (seenParameter)
+									throwBacktrack(startingOffset, endOffset
+											- startingOffset);
+								IASTParameterDeclaration p = parameterDeclaration();
+								finalOffset = calculateEndOffset(p);
+								if (parameters == Collections.EMPTY_LIST)
+									parameters = new ArrayList(
+											DEFAULT_PARM_LIST_SIZE);
+								parameters.add(p);
+								seenParameter = true;
+							}
+						}
+					}
+
+					if (LT(1) == IToken.tCOLON)
+						break overallLoop;
+
+					if (LT(1) == IToken.t_try) {
+						tryEncountered = true;
+						break overallLoop;
+					}
+
+					IToken beforeCVModifier = mark();
+					IToken[] cvModifiers = new IToken[2];
+					int numCVModifiers = 0;
+					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
+					while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile)
+							&& numCVModifiers < 2) {
+						IToken t = consume();
+						finalOffset = t.getEndOffset();
+						cvModifiers[numCVModifiers++] = t;
+						afterCVModifier = mark();
+					}
+					// check for throws clause here
+
+					if (LT(1) == IToken.t_throw) {
+						exceptionSpecIds = new ArrayList(
+								DEFAULT_SIZE_EXCEPTIONS_LIST);
+						consume(IToken.t_throw); // throw
+						consume(IToken.tLPAREN); // (
+						boolean done = false;
+						while (!done) {
+							switch (LT(1)) {
+							case IToken.tRPAREN:
+								finalOffset = consume().getEndOffset();
+								done = true;
+								break;
+							case IToken.tCOMMA:
+								consume();
+								break;
+							default:
+								try {
+									exceptionSpecIds.add(typeId(false, false));
+								} catch (BacktrackException e) {
+									IASTProblem p = failParse(e);
+									IASTProblemTypeId typeIdProblem = createTypeIDProblem();
+									typeIdProblem.setProblem(p);
+									((CPPASTNode) typeIdProblem)
+											.setOffsetAndLength(((CPPASTNode) p));
+									p.setParent(typeIdProblem);
+									p
+											.setPropertyInParent(IASTProblemHolder.PROBLEM);
+									exceptionSpecIds.add(typeIdProblem);
+								}
+								break;
+							}
+						}
+					}
+					// check for optional pure virtual
+					if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) {
+						char[] image = LA(2).getCharImage();
+						if (image.length == 1 && image[0] == '0') {
+							consume(IToken.tASSIGN);
+							finalOffset = consume(IToken.tINTEGER)
+									.getEndOffset();
+							isPureVirtual = true;
+						}
+					}
+					if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI
+							|| LT(1) == IToken.tLBRACE) {
+						// There were C++-specific clauses after
+						// const/volatile modifier
+						// Then it is a marker for the method
+						if (numCVModifiers > 0) {
+							for (int i = 0; i < numCVModifiers; i++) {
+								if (cvModifiers[i].getType() == IToken.t_const)
+									isConst = true;
+								if (cvModifiers[i].getType() == IToken.t_volatile)
+									isVolatile = 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:
+					if (skipArrayDeclarator)
+						break;
+					arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
+					consumeArrayModifiers(arrayMods);
+					if (!arrayMods.isEmpty())
+						finalOffset = calculateEndOffset((IASTNode) arrayMods
+								.get(arrayMods.size() - 1));
+					continue;
+				case IToken.tCOLON:
+					consume(IToken.tCOLON);
+					bitField = constantExpression();
+					finalOffset = calculateEndOffset(bitField);
+					break;
+				default:
+					break;
+				}
+				break;
+			}
+			if (LA(1).getType() != IToken.tIDENTIFIER)
+				break;
+
+		} while (true);
+
+		IASTDeclarator d = null;
+		if (isFunction) {
+
+			ICPPASTFunctionDeclarator fc = null;
+			if (tryEncountered)
+				fc = createTryBlockDeclarator();
+			else
+				fc = createFunctionDeclarator();
+			fc.setVarArgs(encounteredVarArgs);
+			for (int i = 0; i < parameters.size(); ++i) {
+				IASTParameterDeclaration p = (IASTParameterDeclaration) parameters
+						.get(i);
+				p.setParent(fc);
+				p
+						.setPropertyInParent(IASTStandardFunctionDeclarator.FUNCTION_PARAMETER);
+				fc.addParameterDeclaration(p);
+			}
+			fc.setConst(isConst);
+			fc.setVolatile(isVolatile);
+			fc.setPureVirtual(isPureVirtual);
+			for (int i = 0; i < exceptionSpecIds.size(); ++i) {
+				IASTTypeId typeId = (IASTTypeId) exceptionSpecIds.get(i);
+				fc.addExceptionSpecificationTypeId(typeId);
+				typeId.setParent(fc);
+				typeId
+						.setPropertyInParent(ICPPASTFunctionDeclarator.EXCEPTION_TYPEID);
+			}
+			d = fc;
+		} else if (arrayMods != Collections.EMPTY_LIST) {
+			d = createArrayDeclarator();
+			for (int i = 0; i < arrayMods.size(); ++i) {
+				IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i);
+				m.setParent(d);
+				m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER);
+				((IASTArrayDeclarator) d).addArrayModifier(m);
+			}
+		} else if (bitField != null) {
+			IASTFieldDeclarator fl = createFieldDeclarator();
+			fl.setBitFieldSize(bitField);
+			bitField.setParent(fl);
+			bitField.setPropertyInParent(IASTFieldDeclarator.FIELD_SIZE);
+			d = fl;
+		} else {
+			d = createDeclarator();
+		}
+		for (int i = 0; i < pointerOps.size(); ++i) {
+			IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i);
+			d.addPointerOperator(po);
+			po.setParent(d);
+			po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR);
+		}
+		if (innerDecl != null) {
+			d.setNestedDeclarator(innerDecl);
+			innerDecl.setParent(d);
+			innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR);
+		}
+		if (declaratorName != null) {
+			d.setName(declaratorName);
+			declaratorName.setParent(d);
+			declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME);
+		}
+
+		((ASTNode) d).setOffsetAndLength(startingOffset, finalOffset
+				- startingOffset);
+		return d;
+
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTProblemTypeId createTypeIDProblem() {
+		return new CPPASTProblemTypeId();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTFunctionTryBlockDeclarator createTryBlockDeclarator() {
+		return new CPPASTFunctionTryBlockDeclarator();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTFunctionDeclarator createFunctionDeclarator() {
+		return new CPPASTFunctionDeclarator();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTFieldDeclarator createFieldDeclarator() {
+		return new CPPASTFieldDeclarator();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTDeclarator createArrayDeclarator() {
+		return new CPPASTArrayDeclarator();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTDeclarator createDeclarator() {
+		return new CPPASTDeclarator();
+	}
+
+	protected IASTName consumeTemplatedOperatorName()
+			throws EndOfFileException, BacktrackException {
+		TemplateParameterManager argumentList = TemplateParameterManager
+				.getInstance();
+		try {
+			if (LT(1) == IToken.t_operator)
+				return operatorId(null, null);
+
+			try {
+				return createName(name());
+			} catch (BacktrackException bt) {
+			}
+			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 = consumeTemplateArguments(end, argumentList);
+				}
+
+				while (LT(1) == IToken.tCOLONCOLON
+						|| LT(1) == IToken.tIDENTIFIER) {
+					end = consume();
+					if (end.getType() == IToken.tIDENTIFIER) {
+						end = consumeTemplateArguments(end, argumentList);
+					}
+				}
+
+				if (LT(1) == IToken.t_operator) {
+					return operatorId(start, argumentList);
+				}
+
+				int endOffset = (end != null) ? end.getEndOffset() : 0;
+				backup(mark);
+				throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
+			}
+			int endOffset = (mark != null) ? mark.getEndOffset() : 0;
+			backup(mark);
+			throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
+
+			return null;
+		} finally {
+			TemplateParameterManager.returnInstance(argumentList);
+		}
+	}
+
+	/**
+	 * Parse a class/struct/union definition. classSpecifier : classKey name
+	 * (baseClause)? "{" (memberSpecification)* "}"
+	 * 
+	 * @param owner
+	 *            IParserCallback object that represents the declaration that
+	 *            owns this classSpecifier
+	 * @return TODO
+	 * @throws BacktrackException
+	 *             request a backtrack
+	 */
+	protected ICPPASTCompositeTypeSpecifier classSpecifier()
+			throws BacktrackException, EndOfFileException {
+		int classKind = 0;
+		IToken classKey = null;
+		IToken mark = mark();
+
+		// class key
+		switch (LT(1)) {
+		case IToken.t_class:
+			classKey = consume();
+			classKind = ICPPASTCompositeTypeSpecifier.k_class;
+			break;
+		case IToken.t_struct:
+			classKey = consume();
+			classKind = IASTCompositeTypeSpecifier.k_struct;
+			break;
+		case IToken.t_union:
+			classKey = consume();
+			classKind = IASTCompositeTypeSpecifier.k_union;
+			break;
+		default:
+			throwBacktrack(mark.getOffset(), mark.getLength());
+		}
+
+		IASTName name = null;
+
+		// class name
+		if (LT(1) == IToken.tIDENTIFIER)
+			name = createName(name());
+		else
+			name = createName();
+
+		if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) {
+			IToken errorPoint = LA(1);
+			backup(mark);
+			throwBacktrack(errorPoint.getOffset(), errorPoint.getLength());
+		}
+
+		ICPPASTCompositeTypeSpecifier astClassSpecifier = createClassSpecifier();
+		((ASTNode) astClassSpecifier).setOffset(classKey.getOffset());
+		astClassSpecifier.setKey(classKind);
+		astClassSpecifier.setName(name);
+		name.setParent(astClassSpecifier);
+		name.setPropertyInParent(IASTCompositeTypeSpecifier.TYPE_NAME);
+
+		// base clause
+		if (LT(1) == IToken.tCOLON) {
+			baseSpecifier(astClassSpecifier);
+		}
+
+		if (LT(1) == IToken.tLBRACE) {
+			consume(IToken.tLBRACE);
+
+			
+				memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) {
+					int checkToken = LA(1).hashCode();
+					switch (LT(1)) {
+					case IToken.t_public:
+					case IToken.t_protected:
+					case IToken.t_private:
+						IToken key = consume();
+						int l = consume(IToken.tCOLON).getEndOffset();
+						ICPPASTVisiblityLabel label = createVisibilityLabel();
+						((ASTNode) label).setOffsetAndLength(key.getOffset(), l
+								- key.getOffset());
+						label.setVisibility(token2Visibility(key.getType()));
+						astClassSpecifier.addMemberDeclaration(label);
+						label.setParent(astClassSpecifier);
+						label
+								.setPropertyInParent(ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL);
+						break;
+					case IToken.tRBRACE:
+						consume(IToken.tRBRACE);
+						break memberDeclarationLoop;
+					default:
+						try {
+							IASTDeclaration d = declaration();
+							astClassSpecifier.addMemberDeclaration(d);
+							d.setParent(astClassSpecifier);
+							d
+									.setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION);
+						} catch (BacktrackException bt) {
+							IASTProblem p = failParse(bt);
+							IASTProblemDeclaration pd = createProblemDeclaration();
+							pd.setProblem(p);
+							((CPPASTNode) pd)
+									.setOffsetAndLength(((CPPASTNode) p));
+							p.setParent(pd);
+							p.setPropertyInParent(IASTProblemHolder.PROBLEM);
+							astClassSpecifier.addMemberDeclaration(pd);
+							pd.setParent(astClassSpecifier);
+							pd
+									.setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION);
+							if (checkToken == LA(1).hashCode())
+								errorHandling();
+						}
+
+						if (checkToken == LA(1).hashCode())
+							failParseWithErrorHandling();
+					}
+				}
+		
+			// consume the }
+			int l = consume(IToken.tRBRACE).getEndOffset();
+			((ASTNode) astClassSpecifier).setLength(l - classKey.getOffset());
+
+		}
+		return astClassSpecifier;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTCompositeTypeSpecifier createClassSpecifier() {
+		return new CPPASTCompositeTypeSpecifier();
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTVisiblityLabel createVisibilityLabel() {
+		return new CPPASTVisibilityLabel();
+	}
+
+	/**
+	 * @param type
+	 * @return
+	 */
+	protected int token2Visibility(int type) {
+		switch (type) {
+		case IToken.t_public:
+			return ICPPASTVisiblityLabel.v_public;
+		case IToken.t_protected:
+			return ICPPASTVisiblityLabel.v_protected;
+		case IToken.t_private:
+			return ICPPASTVisiblityLabel.v_private;
+		}
+		return 0;
+	}
+
+	/**
+	 * 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(ICPPASTCompositeTypeSpecifier astClassSpec)
+			throws EndOfFileException, BacktrackException {
+
+		IToken last = consume(IToken.tCOLON);
+
+		boolean isVirtual = false;
+		int visibility = 0; // ASTAccessVisibility.PUBLIC;
+		IASTName name = null;
+		IToken firstToken = null;
+		baseSpecifierLoop: for (;;) {
+			switch (LT(1)) {
+			case IToken.t_virtual:
+				if (firstToken == null) {
+					firstToken = consume(IToken.t_virtual);
+					last = firstToken;
+				} else
+					last = consume(IToken.t_virtual);
+				isVirtual = true;
+				break;
+			case IToken.t_public:
+				visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public;
+				if (firstToken == null) {
+					firstToken = consume();
+					last = firstToken;
+				} else
+					last = consume();
+				break;
+			case IToken.t_protected:
+				visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected;
+				if (firstToken == null) {
+					firstToken = consume();
+					last = firstToken;
+				} else
+					last = consume();
+				break;
+			case IToken.t_private:
+				visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private;
+				if (firstToken == null) {
+					firstToken = consume();
+					last = firstToken;
+				} else
+					last = consume();
+				break;
+			case IToken.tCOLONCOLON:
+			case IToken.tIDENTIFIER:
+				// to get templates right we need to use the class as the scope
+				ITokenDuple d = name();
+				name = createName(d);
+				if (firstToken == null)
+					firstToken = d.getFirstToken();
+				last = d.getLastToken();
+				break;
+			case IToken.tCOMMA:
+				if (name == null)
+					name = createName();
+				consume();
+				ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = createBaseSpecifier();
+				if (firstToken != null)
+					((ASTNode) baseSpec).setOffsetAndLength(firstToken
+							.getOffset(), last.getEndOffset()
+							- firstToken.getOffset());
+				baseSpec.setVirtual(isVirtual);
+				baseSpec.setVisibility(visibility);
+				baseSpec.setName(name);
+				name.setParent(baseSpec);
+				name
+						.setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME);
+
+				astClassSpec.addBaseSpecifier(baseSpec);
+				baseSpec.setParent(astClassSpec);
+				baseSpec
+						.setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER);
+
+				isVirtual = false;
+				visibility = 0;
+				name = null;
+				firstToken = null;
+
+				continue baseSpecifierLoop;
+			case IToken.tLBRACE:
+				if (name == null)
+					name = createName();
+				baseSpec = createBaseSpecifier();
+				if (firstToken != null)
+					((ASTNode) baseSpec).setOffsetAndLength(firstToken
+							.getOffset(), last.getEndOffset()
+							- firstToken.getOffset());
+				baseSpec.setVirtual(isVirtual);
+				baseSpec.setVisibility(visibility);
+				baseSpec.setName(name);
+				name.setParent(baseSpec);
+				name
+						.setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME);
+
+				astClassSpec.addBaseSpecifier(baseSpec);
+				baseSpec.setParent(astClassSpec);
+				baseSpec
+						.setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER);
+			// fall through
+			default:
+				break baseSpecifierLoop;
+			}
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTBaseSpecifier createBaseSpecifier() {
+		return new CPPASTBaseSpecifier();
+	}
+
+	protected void catchHandlerSequence(List collection)
+			throws EndOfFileException, BacktrackException {
+		if (LT(1) != IToken.t_catch) {
+			IToken la = LA(1);
+			throwBacktrack(la.getOffset(), la.getLength()); // error, need at
+			// least
+			// one of these
+		}
+		while (LT(1) == IToken.t_catch) {
+			int startOffset = consume(IToken.t_catch).getOffset();
+			consume(IToken.tLPAREN);
+			boolean isEllipsis = false;
+			IASTDeclaration decl = null;
+			try {
+				if (LT(1) == IToken.tELLIPSIS) {
+					consume(IToken.tELLIPSIS);
+					isEllipsis = true;
+				} else {
+					decl = simpleDeclaration(
+							SimpleDeclarationStrategy.TRY_VARIABLE, true);
+				}
+				consume(IToken.tRPAREN);
+			} catch (BacktrackException bte) {
+				IASTProblem p = failParse(bte);
+				IASTProblemDeclaration pd = createProblemDeclaration();
+				pd.setProblem(p);
+				((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
+				p.setParent(pd);
+				p.setPropertyInParent(IASTProblemHolder.PROBLEM);
+				decl = pd;
+			}
+
+			IASTStatement compoundStatement = catchBlockCompoundStatement();
+			ICPPASTCatchHandler handler = createCatchHandler();
+			((ASTNode) handler).setOffsetAndLength(startOffset,
+					calculateEndOffset(compoundStatement) - startOffset);
+			handler.setIsCatchAll(isEllipsis);
+			if (decl != null) {
+				handler.setDeclaration(decl);
+				decl.setParent(handler);
+				decl.setPropertyInParent(ICPPASTCatchHandler.DECLARATION);
+			}
+			if (compoundStatement != null) {
+				handler.setCatchBody(compoundStatement);
+				compoundStatement.setParent(handler);
+				compoundStatement
+						.setPropertyInParent(ICPPASTCatchHandler.CATCH_BODY);
+			}
+			collection.add(handler);
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTCatchHandler createCatchHandler() {
+		return new CPPASTCatchHandler();
+	}
+
+	protected IASTStatement catchBlockCompoundStatement()
+			throws BacktrackException, EndOfFileException {
+		if (mode == ParserMode.QUICK_PARSE
+				|| mode == ParserMode.STRUCTURAL_PARSE) {
+			IToken curr = LA(1);
+			IToken last = skipOverCompoundStatement();
+			IASTCompoundStatement cs = createCompoundStatement();
+			((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last
+					.getEndOffset()
+					- curr.getOffset());
+			return cs;
+		} else if (mode == ParserMode.COMPLETION_PARSE
+				|| mode == ParserMode.SELECTION_PARSE) {
+			if (scanner.isOnTopContext())
+				return compoundStatement();
+			IToken curr = LA(1);
+			IToken last = skipOverCompoundStatement();
+			IASTCompoundStatement cs = createCompoundStatement();
+			((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last
+					.getEndOffset()
+					- curr.getOffset());
+			return cs;
+		}
+		return compoundStatement();
+	}
+
+	/**
+	 * @throws BacktrackException
+	 */
+	protected IASTNode forInitStatement() throws BacktrackException,
+			EndOfFileException {
+		IToken mark = mark();
+		try {
+			IASTExpression e = null;
+			if (LT(1) != IToken.tSEMI)
+				e = expression();
+			consume(IToken.tSEMI);
+			return e;
+		} catch (BacktrackException bt) {
+			backup(mark);
+			try {
+				return simpleDeclarationStrategyUnion();
+			} catch (BacktrackException b) {
+				failParse();
+				throwBacktrack(b);
+				return null;
+			}
+		}
+	}
+
+	/**
+	 * This is the top-level entry point into the ANSI C++ grammar.
+	 * translationUnit : (declaration)*
+	 */
+	protected void translationUnit() {
+		try {
+			translationUnit = createTranslationUnit();
+		} catch (Exception e2) {
+			logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$
+			return;
+		}
+		translationUnit.setLocationResolver(scanner.getLocationResolver());
+
+		while (true) {
+			try {
+				if (LT(1) == IToken.tEOC)
+					break;
+				int checkOffset = LA(1).hashCode();
+				IASTDeclaration declaration = declaration();
+				translationUnit.addDeclaration(declaration);
+				declaration.setParent(translationUnit);
+				declaration
+						.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION);
+
+				if (LA(1).hashCode() == checkOffset)
+					failParseWithErrorHandling();
+			} catch (EndOfFileException e) {
+				if (translationUnit.getDeclarations().length != 0) {
+					CPPASTNode d = (CPPASTNode) translationUnit
+							.getDeclarations()[translationUnit
+							.getDeclarations().length - 1];
+					((CPPASTNode) translationUnit).setLength(d.getOffset()
+							+ d.getLength());
+				} else
+					((CPPASTNode) translationUnit).setLength(0);
+				break;
+			} catch (BacktrackException b) {
+				try {
+					// Mark as failure and try to reach a recovery point
+					IASTProblem p = failParse(b);
+					IASTProblemDeclaration pd = createProblemDeclaration();
+					p.setParent(pd);
+					pd.setProblem(p);
+					((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p));
+					p.setPropertyInParent(IASTProblemHolder.PROBLEM);
+					translationUnit.addDeclaration(pd);
+					pd.setParent(translationUnit);
+					pd
+							.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION);
+					errorHandling();
+				} catch (EndOfFileException e) {
+					break;
+				}
+			} catch (OutOfMemoryError oome) {
+				logThrowable("translationUnit", oome); //$NON-NLS-1$
+				throw oome;
+			} catch (Exception e) {
+				logException("translationUnit", e); //$NON-NLS-1$
+				try {
+					failParseWithErrorHandling();
+				} catch (EndOfFileException e3) {
+					// nothing
+				}
+			} catch (ParseError perr) {
+				throw perr;
+			} catch (Throwable e) {
+				logThrowable("translationUnit", e); //$NON-NLS-1$
+				try {
+					failParseWithErrorHandling();
+				} catch (EndOfFileException e3) {
+					// break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTProblemDeclaration createProblemDeclaration() {
+		return new CPPASTProblemDeclaration();
+	}
+
+	/**
+	 * @return
+	 */
+	protected CPPASTTranslationUnit createTranslationUnit() {
+		return new CPPASTTranslationUnit();
+	}
+
+	protected void consumeArrayModifiers(List collection)
+			throws EndOfFileException, BacktrackException {
+		while (LT(1) == IToken.tLBRACKET) {
+			int o = consume(IToken.tLBRACKET).getOffset(); // eat the '['
+
+			IASTExpression exp = null;
+			if (LT(1) != IToken.tRBRACKET) {
+				exp = constantExpression();
+			}
+			int l = consume(IToken.tRBRACKET).getEndOffset();
+			IASTArrayModifier arrayMod = createArrayModifier();
+			((ASTNode) arrayMod).setOffsetAndLength(o, l - o);
+			if (exp != null) {
+				arrayMod.setConstantExpression(exp);
+				exp.setParent(arrayMod);
+				exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION);
+			}
+			collection.add(arrayMod);
+		}
+		return;
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTArrayModifier createArrayModifier() {
+		return new CPPASTArrayModifier();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit()
+	 */
+	protected IASTTranslationUnit getTranslationUnit() {
+		return translationUnit;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement()
+	 */
+	protected IASTCompoundStatement createCompoundStatement() {
+		return new CPPASTCompoundStatement();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression()
+	 */
+	protected IASTBinaryExpression createBinaryExpression() {
+		return new CPPASTBinaryExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression()
+	 */
+	protected IASTConditionalExpression createConditionalExpression() {
+		return new CPPASTConditionalExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression()
+	 */
+	protected IASTUnaryExpression createUnaryExpression() {
+		return new CPPASTUnaryExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression()
+	 */
+	protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() {
+		return new CPPASTCompoundStatementExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList()
+	 */
+	protected IASTExpressionList createExpressionList() {
+		return new CPPASTExpressionList();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken)
+	 */
+	protected IASTName createName(IToken token) {
+		IASTName n = null;
+
+		if (token instanceof OperatorTokenDuple) {
+			n = createOperatorName((OperatorTokenDuple) token, n);
+		} else {
+			n = new CPPASTName(token.getCharImage());
+		}
+
+		switch (token.getType()) {
+		case IToken.tCOMPLETION:
+		case IToken.tEOC:
+			createCompletionNode(token).addName(n);
+			break;
+		}
+		((ASTNode) n).setOffsetAndLength(token.getOffset(), token.getLength());
+
+		return n;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName()
+	 */
+	protected IASTName createName() {
+		return new CPPASTName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator()
+	 */
+	protected IASTEnumerator createEnumerator() {
+		return new CPPASTEnumerator();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#buildTypeIdExpression(int,
+	 *      org.eclipse.cdt.core.dom.ast.IASTTypeId, int)
+	 */
+	protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId,
+			int startingOffset, int endingOffset) {
+		ICPPASTTypeIdExpression typeIdExpression = createTypeIdExpression();
+		((ASTNode) typeIdExpression).setOffsetAndLength(startingOffset,
+				endingOffset - startingOffset);
+		((ASTNode) typeIdExpression).setLength(endingOffset - startingOffset);
+		typeIdExpression.setOperator(op);
+		typeIdExpression.setTypeId(typeId);
+		typeId.setParent(typeIdExpression);
+		typeId.setPropertyInParent(IASTTypeIdExpression.TYPE_ID);
+		return typeIdExpression;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTypeIdExpression createTypeIdExpression() {
+		return new CPPASTTypeIdExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerationSpecifier()
+	 */
+	protected IASTEnumerationSpecifier createEnumerationSpecifier() {
+		return new CPPASTEnumerationSpecifier();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTLabelStatement createLabelStatement() {
+		return new CPPASTLabelStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTGotoStatement createGoToStatement() {
+		return new CPPASTGotoStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTReturnStatement createReturnStatement() {
+		return new CPPASTReturnStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTForStatement createForStatement() {
+		return new CPPASTForStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTContinueStatement createContinueStatement() {
+		return new CPPASTContinueStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTDoStatement createDoStatement() {
+		return new CPPASTDoStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTBreakStatement createBreakStatement() {
+		return new CPPASTBreakStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTWhileStatement createWhileStatement() {
+		return new CPPASTWhileStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTNullStatement createNullStatement() {
+		return new CPPASTNullStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTSwitchStatement createSwitchStatement() {
+		return new CPPASTSwitchStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTIfStatement createIfStatement() {
+		return new CPPASTIfStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTDefaultStatement createDefaultStatement() {
+		return new CPPASTDefaultStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTCaseStatement createCaseStatement() {
+		return new CPPASTCaseStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTExpressionStatement createExpressionStatement() {
+		return new CPPASTExpressionStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTDeclarationStatement createDeclarationStatement() {
+		return new CPPASTDeclarationStatement();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTASMDeclaration createASMDirective() {
+		return new CPPASTASMDeclaration();
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTCastExpression createCastExpression() {
+		return new CPPASTCastExpression();
+	}
+
+	protected IASTStatement statement() throws EndOfFileException,
+			BacktrackException {
+
+		switch (LT(1)) {
+		// labeled statements
+		case IToken.t_case:
+			return parseCaseStatement();
+		case IToken.t_default:
+			return parseDefaultStatement();
+		// compound statement
+		case IToken.tLBRACE:
+			return parseCompoundStatement();
+		// selection statement
+		case IToken.t_if:
+			return parseIfStatement();
+		case IToken.t_switch:
+			return parseSwitchStatement();
+		// iteration statements
+		case IToken.t_while:
+			return parseWhileStatement();
+		case IToken.t_do:
+			return parseDoStatement();
+		case IToken.t_for:
+			return parseForStatement();
+		// jump statement
+		case IToken.t_break:
+			return parseBreakStatement();
+		case IToken.t_continue:
+			return parseContinueStatement();
+		case IToken.t_return:
+			return parseReturnStatement();
+		case IToken.t_goto:
+			return parseGotoStatement();
+		case IToken.tSEMI:
+			return parseNullStatement();
+		case IToken.t_try:
+			return parseTryStatement();
+		default:
+			// can be many things:
+			// label
+			if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
+				return parseLabelStatement();
+			}
+
+			return parseDeclarationOrExpressionStatement();
+		}
+	}
+
+	/**
+	 * @return
+	 * @throws EndOfFileException
+	 * @throws BacktrackException
+	 */
+	protected IASTStatement parseTryStatement() throws EndOfFileException,
+			BacktrackException {
+		int startO = consume().getOffset();
+		IASTStatement tryBlock = compoundStatement();
+		List catchHandlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE);
+		catchHandlerSequence(catchHandlers);
+		ICPPASTTryBlockStatement tryStatement = createTryBlockStatement();
+		((ASTNode) tryStatement).setOffset(startO);
+		tryStatement.setTryBody(tryBlock);
+		tryBlock.setParent(tryStatement);
+		tryBlock.setPropertyInParent(ICPPASTTryBlockStatement.BODY);
+
+		for (int i = 0; i < catchHandlers.size(); ++i) {
+			ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers
+					.get(i);
+			tryStatement.addCatchHandler(handler);
+			handler.setParent(tryStatement);
+			handler.setPropertyInParent(ICPPASTTryBlockStatement.CATCH_HANDLER);
+			((ASTNode) tryStatement).setLength(calculateEndOffset(handler)
+					- startO);
+		}
+		return tryStatement;
+	}
+
+	/**
+	 * @return
+	 */
+	protected ICPPASTTryBlockStatement createTryBlockStatement() {
+		return new CPPASTTryBlockStatement();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit()
+	 */
+	protected void nullifyTranslationUnit() {
+		translationUnit = null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement()
+	 */
+	protected IASTProblemStatement createProblemStatement() {
+		return new CPPASTProblemStatement();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression()
+	 */
+	protected IASTProblemExpression createProblemExpression() {
+		return new CPPASTProblemExpression();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int,
+	 *      int, int)
+	 */
+	protected IASTProblem createProblem(int signal, int offset, int length) {
+		IASTProblem result = new CPPASTProblem(signal, EMPTY_STRING, false,
+				true);
+		((ASTNode) result).setOffsetAndLength(offset, length);
+		((ASTNode) result).setLength(length);
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#resolveOtherAmbiguitiesAsDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement,
+	 *      org.eclipse.cdt.core.dom.ast.IASTExpressionStatement)
+	 */
+	protected boolean resolveOtherAmbiguitiesAsDeclaration(
+			IASTDeclarationStatement ds,
+			IASTExpressionStatement expressionStatement) {
+		if (expressionStatement.getExpression() instanceof IASTArraySubscriptExpression) {
+			IASTArraySubscriptExpression arraySub = (IASTArraySubscriptExpression) expressionStatement
+					.getExpression();
+			if (!(arraySub.getArrayExpression() instanceof IASTIdExpression
+					|| arraySub.getArrayExpression() instanceof IASTArraySubscriptExpression || arraySub
+					.getArrayExpression() instanceof IASTFieldReference))
+				return true;
+		}
+		// A & B = C;
+		if (expressionStatement.getExpression() instanceof IASTBinaryExpression) {
+			IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement
+					.getExpression();
+			if (exp.getOperator() == IASTBinaryExpression.op_assign) {
+				IASTExpression lhs = exp.getOperand1();
+				if (lhs instanceof IASTBinaryExpression
+						&& ((IASTBinaryExpression) lhs).getOperator() == IASTBinaryExpression.op_binaryAnd) {
+
+					return true;
+				}
+			}
+		}
+
+		return super.resolveOtherAmbiguitiesAsDeclaration(ds,
+				expressionStatement);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#parseWhileStatement()
+	 */
+	protected IASTStatement parseWhileStatement() throws EndOfFileException,
+			BacktrackException {
+		int startOffset = consume(IToken.t_while).getOffset();
+		consume(IToken.tLPAREN);
+		IASTNode while_condition = whileCondition();
+		consume(IToken.tRPAREN);
+		IASTStatement while_body = statement();
+
+		ICPPASTWhileStatement while_statement = (ICPPASTWhileStatement) createWhileStatement();
+		((ASTNode) while_statement).setOffsetAndLength(startOffset,
+				calculateEndOffset(while_body) - startOffset);
+		if (while_condition instanceof IASTExpression) {
+			while_statement.setCondition((IASTExpression) while_condition);
+			while_condition.setParent(while_statement);
+			while_condition
+					.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
+		} else if (while_condition instanceof IASTDeclaration) {
+			while_statement
+					.setConditionDeclaration((IASTDeclaration) while_condition);
+			while_condition.setParent(while_statement);
+			while_condition
+					.setPropertyInParent(ICPPASTWhileStatement.CONDITIONDECLARATION);
+		}
+		while_statement.setBody(while_body);
+		while_body.setParent(while_statement);
+		while_body.setPropertyInParent(IASTWhileStatement.BODY);
+		return while_statement;
+
+	}
+
+	/**
+	 * @return
+	 */
+	protected IASTNode whileCondition() throws BacktrackException,
+			EndOfFileException {
+		IToken mark = mark();
+		try {
+			IASTExpression e = expression();
+			if (LT(1) != IToken.tRPAREN)
+				throwBacktrack(LA(1));
+			return e;
+		} catch (BacktrackException bt) {
+			backup(mark);
+			try {
+				return simpleDeclaration(
+						SimpleDeclarationStrategy.TRY_VARIABLE, true);
+			} catch (BacktrackException b) {
+				failParse();
+				throwBacktrack(b);
+				return null;
+			}
+		}
+	}
+
+	static class HeuristicTypeDetector extends CPPASTVisitor {
+		IASTName searchName;
+
+		boolean found = false;
+		{
+			shouldVisitDeclarations = true;
+		}
+
+		public HeuristicTypeDetector(IASTName name) {
+			this.searchName = name;
+		}
+
+		public int visit(IASTDeclaration declaration) {
+			if (declaration instanceof IASTSimpleDeclaration) {
+				IASTSimpleDeclaration sd = (IASTSimpleDeclaration) declaration;
+				if (sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
+					IASTDeclarator[] declarators = sd.getDeclarators();
+					for (int i = 0; i < declarators.length; ++i)
+						if (CharArrayUtils.equals(declarators[i].getName()
+								.toCharArray(), searchName.toCharArray())) {
+							found = true;
+							return PROCESS_ABORT;
+						}
+				} else if (sd.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) {
+					IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) sd
+							.getDeclSpecifier();
+					if (CharArrayUtils.equals(comp.getName().toCharArray(),
+							searchName.toCharArray())) {
+						found = true;
+						return PROCESS_ABORT;
+					}
+				}
+			}
+			return PROCESS_CONTINUE;
+		}
+	}
+
+	protected boolean queryIsTypeName(IASTName name) {
+		HeuristicTypeDetector visitor = new HeuristicTypeDetector(name);
+		translationUnit.accept(visitor);
+		return visitor.found;
+	}
+
+	protected void resolveAmbiguities() {
+		// TODO Auto-generated method stub
+
+	}
 
 }
\ No newline at end of file