/***********************************************************************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: IBM Corporation - initial API and implementation
 **********************************************************************************************************************************/
package net.sourceforge.phpdt.internal.compiler;

import net.sourceforge.phpdt.core.compiler.IProblem;
import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;

import org.eclipse.core.resources.IResource;

/*
 * A document element parser extracts structural information from a piece of source, providing detailed source positions info.
 * 
 * also see @IDocumentElementRequestor
 * 
 * The structural investigation includes: - the package statement - import statements - top-level types: package member, member
 * types (member types of member types...) - fields - methods
 * 
 * Any (parsing) problem encountered is also provided.
 */
public class DocumentElementParser extends UnitParser {
  IDocumentElementRequestor requestor;

  private int localIntPtr;

  private int lastFieldEndPosition;

  private int lastFieldBodyEndPosition;

  private int typeStartPosition;

  private long selectorSourcePositions;

  private int typeDims;

  private int extendsDim;

  private int declarationSourceStart;

  /* int[] stack for storing javadoc positions */
  int[][] intArrayStack;

  int intArrayPtr;

  //	CompilerOptions options;

  public DocumentElementParser(final IDocumentElementRequestor requestor, IProblemFactory problemFactory,
      CompilerOptions options) {
    super(new ProblemReporter(DefaultErrorHandlingPolicies.exitAfterAllProblems(), options, problemFactory) {
      public void record(IProblem problem, CompilationResult unitResult) {
        requestor.acceptProblem(problem);
      }
    });
    //	false,
    //	options.sourceLevel >= CompilerOptions.JDK1_4);
    this.requestor = requestor;
    intArrayStack = new int[30][];
    this.options = options;
  }

  /**
   * 
   * INTERNAL USE-ONLY
   */
  //protected void adjustInterfaceModifiers() {
  //	intStack[intPtr - 2] |= AccInterface;
  //}
  /*
   * Will clear the comment stack when looking for a potential JavaDoc which might contain @deprecated.
   * 
   * Additionally, before investigating for @deprecated, retrieve the positions of the JavaDoc comments so as to notify requestor
   * with them.
   */
  //public void checkAnnotation() {
  //
  //	/* persisting javadoc positions */
  //	pushOnIntArrayStack(this.getJavaDocPositions());
  //	boolean deprecated = false;
  //	int lastAnnotationIndex = -1;
  //	int commentPtr = scanner.commentPtr;
  //
  //	//since jdk1.2 look only in the last java doc comment...
  //	nextComment : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){
  //		//look for @deprecated into the first javadoc comment preceeding the declaration
  //		int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
  //		// javadoc only (non javadoc comment have negative end positions.)
  //		if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
  //			continue nextComment;
  //		}
  //		if (scanner.commentStops[lastAnnotationIndex] < 0) {
  //			continue nextComment;
  //		}
  //		int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
  //		char[] comment = scanner.source;
  //
  //		deprecated =
  //			checkDeprecation(
  //				commentSourceStart,
  //				commentSourceEnd,
  //				comment);
  //		break nextComment;
  //	}
  //	if (deprecated) {
  //		checkAndSetModifiers(AccDeprecated);
  //	}
  //	// modify the modifier source start to point at the first comment
  //	if (commentPtr >= 0) {
  //		declarationSourceStart = scanner.commentStarts[0];
  //	}
  //}
  /**
   * 
   * INTERNAL USE-ONLY
   */
  //protected void consumeClassBodyDeclaration() {
  //	// ClassBodyDeclaration ::= Diet Block
  //	//push an Initializer
  //	//optimize the push/pop
  //
  //	super.consumeClassBodyDeclaration();
  //	Initializer initializer = (Initializer) astStack[astPtr];
  //	requestor.acceptInitializer(
  //		initializer.declarationSourceStart,
  //		initializer.declarationSourceEnd,
  //		intArrayStack[intArrayPtr--],
  //		0,
  //		modifiersSourceStart,
  //		initializer.block.sourceStart,
  //		initializer.block.sourceEnd);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeClassDeclaration() {
  //	super.consumeClassDeclaration();
  //	// we know that we have a TypeDeclaration on the top of the astStack
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		return;
  //	}
  //	requestor.exitClass(endStatementPosition, // '}' is the end of the body
  //	 ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeClassHeader() {
  //	//ClassHeader ::= $empty
  //	super.consumeClassHeader();
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		intArrayPtr--;
  //		return;
  //	}
  //	TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
  //	TypeReference[] superInterfaces = typeDecl.superInterfaces;
  //	char[][] interfaceNames = null;
  //	int[] interfaceNameStarts = null;
  //	int[] interfaceNameEnds = null;
  //	if (superInterfaces != null) {
  //		int superInterfacesLength = superInterfaces.length;
  //		interfaceNames = new char[superInterfacesLength][];
  //		interfaceNameStarts = new int[superInterfacesLength];
  //		interfaceNameEnds = new int[superInterfacesLength];
  //		for (int i = 0; i < superInterfacesLength; i++) {
  //			TypeReference superInterface = superInterfaces[i];
  //			interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.');
  //			interfaceNameStarts[i] = superInterface.sourceStart;
  //			interfaceNameEnds[i] = superInterface.sourceEnd;
  //		}
  //	}
  //	// flush the comments related to the class header
  //	scanner.commentPtr = -1;
  //	TypeReference superclass = typeDecl.superclass;
  //	if (superclass == null) {
  //		requestor.enterClass(
  //			typeDecl.declarationSourceStart,
  //			intArrayStack[intArrayPtr--],
  //			typeDecl.modifiers,
  //			typeDecl.modifiersSourceStart,
  //			typeStartPosition,
  //			typeDecl.name,
  //			typeDecl.sourceStart,
  //			typeDecl.sourceEnd,
  //			null,
  //			-1,
  //			-1,
  //			interfaceNames,
  //			interfaceNameStarts,
  //			interfaceNameEnds,
  //			scanner.currentPosition - 1);
  //	} else {
  //		requestor.enterClass(
  //			typeDecl.declarationSourceStart,
  //			intArrayStack[intArrayPtr--],
  //			typeDecl.modifiers,
  //			typeDecl.modifiersSourceStart,
  //			typeStartPosition,
  //			typeDecl.name,
  //			typeDecl.sourceStart,
  //			typeDecl.sourceEnd,
  //			CharOperation.concatWith(superclass.getTypeName(), '.'),
  //			superclass.sourceStart,
  //			superclass.sourceEnd,
  //			interfaceNames,
  //			interfaceNameStarts,
  //			interfaceNameEnds,
  //			scanner.currentPosition - 1);
  //
  //	}
  //}
  //protected void consumeClassHeaderName() {
  //	// ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
  //	TypeDeclaration typeDecl;
  //	if (nestedMethod[nestedType] == 0) {
  //		if (nestedType != 0) {
  //			typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
  //		} else {
  //			typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
  //		}
  //	} else {
  //		// Record that the block has a declaration for local types
  //		typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
  //		markEnclosingMemberWithLocalType();
  //		blockReal();
  //	}
  //
  //	//highlight the name of the type
  //	long pos = identifierPositionStack[identifierPtr];
  //	typeDecl.sourceEnd = (int) pos;
  //	typeDecl.sourceStart = (int) (pos >>> 32);
  //	typeDecl.name = identifierStack[identifierPtr--];
  //	identifierLengthPtr--;
  //
  //	//compute the declaration source too
  //	// 'class' and 'interface' push an int position
  //	typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--];
  //	intPtr--;
  //	int declarationSourceStart = intStack[intPtr--];
  //	typeDecl.modifiersSourceStart = intStack[intPtr--];
  //	typeDecl.modifiers = intStack[intPtr--];
  //	if (typeDecl.declarationSourceStart > declarationSourceStart) {
  //		typeDecl.declarationSourceStart = declarationSourceStart;
  //	}
  //	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
  //	pushOnAstStack(typeDecl);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeCompilationUnit() {
  //	// CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
  //	requestor.exitCompilationUnit(scanner.source.length - 1);
  //}
  /**
   * 
   * INTERNAL USE-ONLY
   */
  //protected void consumeConstructorDeclaration() {
  //	// ConstructorDeclaration ::= ConstructorHeader ConstructorBody
  //	super.consumeConstructorDeclaration();
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		return;
  //	}
  //	ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
  //	requestor.exitConstructor(endStatementPosition, cd.declarationSourceEnd);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeConstructorHeader() {
  //	// ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
  //	super.consumeConstructorHeader();
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		intArrayPtr--;
  //		return;
  //	}
  //	ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
  //	Argument[] arguments = cd.arguments;
  //	char[][] argumentTypes = null;
  //	char[][] argumentNames = null;
  //	int[] argumentTypeStarts = null;
  //	int[] argumentTypeEnds = null;
  //	int[] argumentNameStarts = null;
  //	int[] argumentNameEnds = null;
  //	if (arguments != null) {
  //		int argumentLength = arguments.length;
  //		argumentTypes = new char[argumentLength][];
  //		argumentNames = new char[argumentLength][];
  //		argumentNameStarts = new int[argumentLength];
  //		argumentNameEnds = new int[argumentLength];
  //		argumentTypeStarts = new int[argumentLength];
  //		argumentTypeEnds = new int[argumentLength];
  //		for (int i = 0; i < argumentLength; i++) {
  //			Argument argument = arguments[i];
  //			TypeReference argumentType = argument.type;
  //			argumentTypes[i] = returnTypeName(argumentType);
  //			argumentNames[i] = argument.name;
  //			argumentNameStarts[i] = argument.sourceStart;
  //			argumentNameEnds[i] = argument.sourceEnd;
  //			argumentTypeStarts[i] = argumentType.sourceStart;
  //			argumentTypeEnds[i] = argumentType.sourceEnd;
  //		}
  //	}
  //	TypeReference[] thrownExceptions = cd.thrownExceptions;
  //	char[][] exceptionTypes = null;
  //	int[] exceptionTypeStarts = null;
  //	int[] exceptionTypeEnds = null;
  //	if (thrownExceptions != null) {
  //		int thrownExceptionLength = thrownExceptions.length;
  //		exceptionTypes = new char[thrownExceptionLength][];
  //		exceptionTypeStarts = new int[thrownExceptionLength];
  //		exceptionTypeEnds = new int[thrownExceptionLength];
  //		for (int i = 0; i < thrownExceptionLength; i++) {
  //			TypeReference exception = thrownExceptions[i];
  //			exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
  //			exceptionTypeStarts[i] = exception.sourceStart;
  //			exceptionTypeEnds[i] = exception.sourceEnd;
  //		}
  //	}
  //	requestor
  //		.enterConstructor(
  //			cd.declarationSourceStart,
  //			intArrayStack[intArrayPtr--],
  //			cd.modifiers,
  //			cd.modifiersSourceStart,
  //			cd.selector,
  //			cd.sourceStart,
  //			(int) (selectorSourcePositions & 0xFFFFFFFFL),
  //			// retrieve the source end of the name
  //			argumentTypes,
  //			argumentTypeStarts,
  //			argumentTypeEnds,
  //			argumentNames,
  //			argumentNameStarts,
  //			argumentNameEnds,
  //			rParenPos,
  //			// right parenthesis
  //			exceptionTypes,
  //			exceptionTypeStarts,
  //			exceptionTypeEnds,
  //			scanner.currentPosition - 1);
  //}
  //protected void consumeConstructorHeaderName() {
  //	// ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
  //	ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
  //
  //	//name -- this is not really revelant but we do .....
  //	cd.selector = identifierStack[identifierPtr];
  //	selectorSourcePositions = identifierPositionStack[identifierPtr--];
  //	identifierLengthPtr--;
  //
  //	//modifiers
  //	cd.declarationSourceStart = intStack[intPtr--];
  //	cd.modifiersSourceStart = intStack[intPtr--];
  //	cd.modifiers = intStack[intPtr--];
  //
  //	//highlight starts at the selector starts
  //	cd.sourceStart = (int) (selectorSourcePositions >>> 32);
  //	pushOnAstStack(cd);
  //
  //	cd.sourceEnd = lParenPos;
  //	cd.bodyStart = lParenPos + 1;
  //}
  //protected void consumeDefaultModifiers() {
  //	checkAnnotation(); // might update modifiers with AccDeprecated
  //	pushOnIntStack(modifiers); // modifiers
  //	pushOnIntStack(-1);
  //	pushOnIntStack(
  //		declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition);
  //	resetModifiers();
  //}
  //protected void consumeDiet() {
  //	// Diet ::= $empty
  //	super.consumeDiet();
  //	/* persisting javadoc positions
  //	 * Will be consume in consumeClassBodyDeclaration
  //	 */
  //	pushOnIntArrayStack(this.getJavaDocPositions());
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeEnterCompilationUnit() {
  //	// EnterCompilationUnit ::= $empty
  //	requestor.enterCompilationUnit();
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeEnterVariable() {
  //	// EnterVariable ::= $empty
  //	boolean isLocalDeclaration = isLocalDeclaration();
  //	if (!isLocalDeclaration && (variablesCounter[nestedType] != 0)) {
  //		requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition);
  //	}
  //	char[] name = identifierStack[identifierPtr];
  //	long namePosition = identifierPositionStack[identifierPtr--];
  //	int extendedTypeDimension = intStack[intPtr--];
  //
  //	AbstractVariableDeclaration declaration;
  //	if (nestedMethod[nestedType] != 0) {
  //		// create the local variable declarations
  //		declaration =
  //			new LocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
  //	} else {
  //		// create the field declaration
  //		declaration =
  //			new FieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
  //	}
  //	identifierLengthPtr--;
  //	TypeReference type;
  //	int variableIndex = variablesCounter[nestedType];
  //	int typeDim = 0;
  //	if (variableIndex == 0) {
  //		// first variable of the declaration (FieldDeclaration or LocalDeclaration)
  //		if (nestedMethod[nestedType] != 0) {
  //			// local declaration
  //			declaration.declarationSourceStart = intStack[intPtr--];
  //			declaration.modifiersSourceStart = intStack[intPtr--];
  //			declaration.modifiers = intStack[intPtr--];
  //			type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
  //			pushOnAstStack(type);
  //		} else {
  //			// field declaration
  //			type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
  //			pushOnAstStack(type);
  //			declaration.declarationSourceStart = intStack[intPtr--];
  //			declaration.modifiersSourceStart = intStack[intPtr--];
  //			declaration.modifiers = intStack[intPtr--];
  //		}
  //	} else {
  //		type = (TypeReference) astStack[astPtr - variableIndex];
  //		typeDim = type.dimensions();
  //		AbstractVariableDeclaration previousVariable =
  //			(AbstractVariableDeclaration) astStack[astPtr];
  //		declaration.declarationSourceStart = previousVariable.declarationSourceStart;
  //		declaration.modifiers = previousVariable.modifiers;
  //		declaration.modifiersSourceStart = previousVariable.modifiersSourceStart;
  //	}
  //
  //	localIntPtr = intPtr;
  //
  //	if (extendedTypeDimension == 0) {
  //		declaration.type = type;
  //	} else {
  //		int dimension = typeDim + extendedTypeDimension;
  //		//on the identifierLengthStack there is the information about the type....
  //		int baseType;
  //		if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
  //			//it was a baseType
  //			declaration.type = TypeReference.baseTypeReference(-baseType, dimension);
  //			declaration.type.sourceStart = type.sourceStart;
  //			declaration.type.sourceEnd = type.sourceEnd;
  //		} else {
  //			declaration.type = this.copyDims(type, dimension);
  //		}
  //	}
  //	variablesCounter[nestedType]++;
  //	nestedMethod[nestedType]++;
  //	pushOnAstStack(declaration);
  //
  //	int[] javadocPositions = intArrayStack[intArrayPtr];
  //	if (!isLocalDeclaration) {
  //		requestor
  //			.enterField(
  //				declaration.declarationSourceStart,
  //				javadocPositions,
  //				declaration.modifiers,
  //				declaration.modifiersSourceStart,
  //				returnTypeName(declaration.type),
  //				type.sourceStart,
  //				type.sourceEnd,
  //				typeDims,
  //				name,
  //				(int) (namePosition >>> 32),
  //				(int) namePosition,
  //				extendedTypeDimension,
  //				extendedTypeDimension == 0 ? -1 : endPosition);
  //	}
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeExitVariableWithInitialization() {
  //	// ExitVariableWithInitialization ::= $empty
  //	// the scanner is located after the comma or the semi-colon.
  //	// we want to include the comma or the semi-colon
  //	super.consumeExitVariableWithInitialization();
  //	nestedMethod[nestedType]--;
  //	lastFieldEndPosition = scanner.currentPosition - 1;
  //	lastFieldBodyEndPosition = ((AbstractVariableDeclaration) astStack[astPtr]).initialization.sourceEnd;
  //}
  //protected void consumeExitVariableWithoutInitialization() {
  //	// ExitVariableWithoutInitialization ::= $empty
  //	// do nothing by default
  //	super.consumeExitVariableWithoutInitialization();
  //	nestedMethod[nestedType]--;
  //	lastFieldEndPosition = scanner.currentPosition - 1;
  //	lastFieldBodyEndPosition = scanner.startPosition - 1;
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeFieldDeclaration() {
  //	// See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
  //	// FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
  //	// the super.consumeFieldDeclaration will reinitialize the variableCounter[nestedType]
  //	int variableIndex = variablesCounter[nestedType];
  //	super.consumeFieldDeclaration();
  //	intArrayPtr--;
  //	if (isLocalDeclaration())
  //		return;
  //	if (variableIndex != 0) {
  //		requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition);
  //	}
  //}
  //protected void consumeFormalParameter() {
  //	// FormalParameter ::= Type VariableDeclaratorId ==> false
  //	// FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
  //	/*
  //	astStack :
  //	identifierStack : type identifier
  //	intStack : dim dim
  //	 ==>
  //	astStack : Argument
  //	identifierStack :
  //	intStack :
  //	*/
  //
  //	identifierLengthPtr--;
  //	char[] name = identifierStack[identifierPtr];
  //	long namePositions = identifierPositionStack[identifierPtr--];
  //	TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
  //	intPtr -= 3;
  //	Argument arg =
  //		new Argument(
  //			name,
  //			namePositions,
  //			type,
  //			intStack[intPtr + 1]); // modifiers
  //	pushOnAstStack(arg);
  //	intArrayPtr--;
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeInterfaceDeclaration() {
  //	super.consumeInterfaceDeclaration();
  //	// we know that we have a TypeDeclaration on the top of the astStack
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		return;
  //	}
  //	requestor.exitInterface(endStatementPosition, // the '}' is the end of the body
  //	 ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeInterfaceHeader() {
  //	//InterfaceHeader ::= $empty
  //	super.consumeInterfaceHeader();
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		intArrayPtr--;
  //		return;
  //	}
  //	TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
  //	TypeReference[] superInterfaces = typeDecl.superInterfaces;
  //	char[][] interfaceNames = null;
  //	int[] interfaceNameStarts = null;
  //	int[] interfacenameEnds = null;
  //	int superInterfacesLength = 0;
  //	if (superInterfaces != null) {
  //		superInterfacesLength = superInterfaces.length;
  //		interfaceNames = new char[superInterfacesLength][];
  //		interfaceNameStarts = new int[superInterfacesLength];
  //		interfacenameEnds = new int[superInterfacesLength];
  //	}
  //	if (superInterfaces != null) {
  //		for (int i = 0; i < superInterfacesLength; i++) {
  //			TypeReference superInterface = superInterfaces[i];
  //			interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.');
  //			interfaceNameStarts[i] = superInterface.sourceStart;
  //			interfacenameEnds[i] = superInterface.sourceEnd;
  //		}
  //	}
  //	// flush the comments related to the interface header
  //	scanner.commentPtr = -1;
  //	requestor.enterInterface(
  //		typeDecl.declarationSourceStart,
  //		intArrayStack[intArrayPtr--],
  //		typeDecl.modifiers,
  //		typeDecl.modifiersSourceStart,
  //		typeStartPosition,
  //		typeDecl.name,
  //		typeDecl.sourceStart,
  //		typeDecl.sourceEnd,
  //		interfaceNames,
  //		interfaceNameStarts,
  //		interfacenameEnds,
  //		scanner.currentPosition - 1);
  //}
  //protected void consumeInterfaceHeaderName() {
  //	// InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
  //	TypeDeclaration typeDecl;
  //	if (nestedMethod[nestedType] == 0) {
  //		if (nestedType != 0) {
  //			typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
  //		} else {
  //			typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
  //		}
  //	} else {
  //		// Record that the block has a declaration for local types
  //		typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
  //		markEnclosingMemberWithLocalType();
  //		blockReal();
  //	}
  //
  //	//highlight the name of the type
  //	long pos = identifierPositionStack[identifierPtr];
  //	typeDecl.sourceEnd = (int) pos;
  //	typeDecl.sourceStart = (int) (pos >>> 32);
  //	typeDecl.name = identifierStack[identifierPtr--];
  //	identifierLengthPtr--;
  //
  //	//compute the declaration source too
  //	// 'class' and 'interface' push an int position
  //	typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--];
  //	intPtr--;
  //	int declarationSourceStart = intStack[intPtr--];
  //	typeDecl.modifiersSourceStart = intStack[intPtr--];
  //	typeDecl.modifiers = intStack[intPtr--];
  //	if (typeDecl.declarationSourceStart > declarationSourceStart) {
  //		typeDecl.declarationSourceStart = declarationSourceStart;
  //	}
  //	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
  //	pushOnAstStack(typeDecl);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeLocalVariableDeclaration() {
  //	// See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
  //	// FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
  //
  //	super.consumeLocalVariableDeclaration();
  //	intArrayPtr--;
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeMethodDeclaration(boolean isNotAbstract) {
  //	// MethodDeclaration ::= MethodHeader MethodBody
  //	// AbstractMethodDeclaration ::= MethodHeader ';'
  //	super.consumeMethodDeclaration(isNotAbstract);
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		return;
  //	}
  //	MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
  //	requestor.exitMethod(endStatementPosition, md.declarationSourceEnd);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeMethodHeader() {
  //	// MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
  //	super.consumeMethodHeader();
  //	if (isLocalDeclaration()) {
  //		// we ignore the local variable declarations
  //		intArrayPtr--;
  //		return;
  //	}
  //	MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
  //
  //	TypeReference returnType = md.returnType;
  //	char[] returnTypeName = returnTypeName(returnType);
  //	Argument[] arguments = md.arguments;
  //	char[][] argumentTypes = null;
  //	char[][] argumentNames = null;
  //	int[] argumentTypeStarts = null;
  //	int[] argumentTypeEnds = null;
  //	int[] argumentNameStarts = null;
  //	int[] argumentNameEnds = null;
  //	if (arguments != null) {
  //		int argumentLength = arguments.length;
  //		argumentTypes = new char[argumentLength][];
  //		argumentNames = new char[argumentLength][];
  //		argumentNameStarts = new int[argumentLength];
  //		argumentNameEnds = new int[argumentLength];
  //		argumentTypeStarts = new int[argumentLength];
  //		argumentTypeEnds = new int[argumentLength];
  //		for (int i = 0; i < argumentLength; i++) {
  //			Argument argument = arguments[i];
  //			TypeReference argumentType = argument.type;
  //			argumentTypes[i] = returnTypeName(argumentType);
  //			argumentNames[i] = argument.name;
  //			argumentNameStarts[i] = argument.sourceStart;
  //			argumentNameEnds[i] = argument.sourceEnd;
  //			argumentTypeStarts[i] = argumentType.sourceStart;
  //			argumentTypeEnds[i] = argumentType.sourceEnd;
  //		}
  //	}
  //	TypeReference[] thrownExceptions = md.thrownExceptions;
  //	char[][] exceptionTypes = null;
  //	int[] exceptionTypeStarts = null;
  //	int[] exceptionTypeEnds = null;
  //	if (thrownExceptions != null) {
  //		int thrownExceptionLength = thrownExceptions.length;
  //		exceptionTypeStarts = new int[thrownExceptionLength];
  //		exceptionTypeEnds = new int[thrownExceptionLength];
  //		exceptionTypes = new char[thrownExceptionLength][];
  //		for (int i = 0; i < thrownExceptionLength; i++) {
  //			TypeReference exception = thrownExceptions[i];
  //			exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
  //			exceptionTypeStarts[i] = exception.sourceStart;
  //			exceptionTypeEnds[i] = exception.sourceEnd;
  //		}
  //	}
  //	requestor
  //		.enterMethod(
  //			md.declarationSourceStart,
  //			intArrayStack[intArrayPtr--],
  //			md.modifiers,
  //			md.modifiersSourceStart,
  //			returnTypeName,
  //			returnType.sourceStart,
  //			returnType.sourceEnd,
  //			typeDims,
  //			md.selector,
  //			md.sourceStart,
  //			(int) (selectorSourcePositions & 0xFFFFFFFFL),
  //			argumentTypes,
  //			argumentTypeStarts,
  //			argumentTypeEnds,
  //			argumentNames,
  //			argumentNameStarts,
  //			argumentNameEnds,
  //			rParenPos,
  //			extendsDim,
  //			extendsDim == 0 ? -1 : endPosition,
  //			exceptionTypes,
  //			exceptionTypeStarts,
  //			exceptionTypeEnds,
  //			scanner.currentPosition - 1);
  //}
  //protected void consumeMethodHeaderExtendedDims() {
  //	// MethodHeaderExtendedDims ::= Dimsopt
  //	// now we update the returnType of the method
  //	MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
  //	int extendedDims = intStack[intPtr--];
  //	extendsDim = extendedDims;
  //	if (extendedDims != 0) {
  //		TypeReference returnType = md.returnType;
  //		md.sourceEnd = endPosition;
  //		int dims = returnType.dimensions() + extendedDims;
  //		int baseType;
  //		if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
  //			//it was a baseType
  //			int sourceStart = returnType.sourceStart;
  //			int sourceEnd = returnType.sourceEnd;
  //			returnType = TypeReference.baseTypeReference(-baseType, dims);
  //			returnType.sourceStart = sourceStart;
  //			returnType.sourceEnd = sourceEnd;
  //			md.returnType = returnType;
  //		} else {
  //			md.returnType = this.copyDims(md.returnType, dims);
  //		}
  //		if (currentToken == TokenNameLBRACE) {
  //			md.bodyStart = endPosition + 1;
  //		}
  //	}
  //}
  //protected void consumeMethodHeaderName() {
  //	// MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
  //	MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
  //
  //	//name
  //	md.selector = identifierStack[identifierPtr];
  //	selectorSourcePositions = identifierPositionStack[identifierPtr--];
  //	identifierLengthPtr--;
  //	//type
  //	md.returnType = getTypeReference(typeDims = intStack[intPtr--]);
  //	//modifiers
  //	md.declarationSourceStart = intStack[intPtr--];
  //	md.modifiersSourceStart = intStack[intPtr--];
  //	md.modifiers = intStack[intPtr--];
  //
  //	//highlight starts at selector start
  //	md.sourceStart = (int) (selectorSourcePositions >>> 32);
  //	pushOnAstStack(md);
  //	md.bodyStart = scanner.currentPosition-1;
  //}
  //protected void consumeModifiers() {
  //	checkAnnotation(); // might update modifiers with AccDeprecated
  //	pushOnIntStack(modifiers); // modifiers
  //	pushOnIntStack(modifiersSourceStart);
  //	pushOnIntStack(
  //		declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart);
  //	resetModifiers();
  //}
  /**
   * 
   * INTERNAL USE-ONLY
   */
  //protected void consumePackageDeclarationName() {
  //	/* persisting javadoc positions */
  //	pushOnIntArrayStack(this.getJavaDocPositions());
  //
  //	super.consumePackageDeclarationName();
  //	ImportReference importReference = compilationUnit.currentPackage;
  //
  //	requestor.acceptPackage(
  //		importReference.declarationSourceStart,
  //		importReference.declarationSourceEnd,
  //		intArrayStack[intArrayPtr--],
  //		CharOperation.concatWith(importReference.getImportName(), '.'),
  //		importReference.sourceStart);
  //}
  //protected void consumePushModifiers() {
  //	checkAnnotation(); // might update modifiers with AccDeprecated
  //	pushOnIntStack(modifiers); // modifiers
  //	if (modifiersSourceStart < 0) {
  //		pushOnIntStack(-1);
  //		pushOnIntStack(
  //			declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition);
  //	} else {
  //		pushOnIntStack(modifiersSourceStart);
  //		pushOnIntStack(
  //			declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart);
  //	}
  //	resetModifiers();
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeSingleTypeImportDeclarationName() {
  //	// SingleTypeImportDeclarationName ::= 'import' Name
  //
  //	/* persisting javadoc positions */
  //	pushOnIntArrayStack(this.getJavaDocPositions());
  //
  //	super.consumeSingleTypeImportDeclarationName();
  //	ImportReference importReference = (ImportReference) astStack[astPtr];
  //	requestor.acceptImport(
  //		importReference.declarationSourceStart,
  //		importReference.declarationSourceEnd,
  //		intArrayStack[intArrayPtr--],
  //		CharOperation.concatWith(importReference.getImportName(), '.'),
  //		importReference.sourceStart,
  //		false);
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeStaticInitializer() {
  //	// StaticInitializer ::= StaticOnly Block
  //	//push an Initializer
  //	//optimize the push/pop
  //	super.consumeStaticInitializer();
  //	Initializer initializer = (Initializer) astStack[astPtr];
  //	requestor.acceptInitializer(
  //		initializer.declarationSourceStart,
  //		initializer.declarationSourceEnd,
  //		intArrayStack[intArrayPtr--],
  //		AccStatic,
  //		intStack[intPtr--],
  //		initializer.block.sourceStart,
  //		initializer.declarationSourceEnd);
  //}
  //protected void consumeStaticOnly() {
  //	// StaticOnly ::= 'static'
  //	checkAnnotation(); // might update declaration source start
  //	pushOnIntStack(modifiersSourceStart);
  //	pushOnIntStack(
  //		declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart);
  //	jumpOverMethodBody();
  //	nestedMethod[nestedType]++;
  //	resetModifiers();
  //}
  ///**
  // *
  // * INTERNAL USE-ONLY
  // */
  //protected void consumeTypeImportOnDemandDeclarationName() {
  //	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
  //
  //	/* persisting javadoc positions */
  //	pushOnIntArrayStack(this.getJavaDocPositions());
  //
  //	super.consumeTypeImportOnDemandDeclarationName();
  //	ImportReference importReference = (ImportReference) astStack[astPtr];
  //	requestor.acceptImport(
  //		importReference.declarationSourceStart,
  //		importReference.declarationSourceEnd,
  //		intArrayStack[intArrayPtr--],
  //		CharOperation.concatWith(importReference.getImportName(), '.'),
  //		importReference.sourceStart,
  //		true);
  //}
  public CompilationUnitDeclaration endParse(int act) {
    if (scanner.recordLineSeparator) {
      requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
    }
    return super.endParse(act);
  }

  /*
   * Flush annotations defined prior to a given positions.
   * 
   * Note: annotations are stacked in syntactical order
   * 
   * Either answer given <position>, or the end position of a comment line immediately following the <position> (same line)
   * 
   * e.g. void foo(){ } // end of method foo
   */

  //public int flushAnnotationsDefinedPriorTo(int position) {
  //
  //	return lastFieldEndPosition = super.flushAnnotationsDefinedPriorTo(position);
  //}
  //protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
  //This variable is a type reference and dim will be its dimensions*/
  //
  //	int length;
  //	TypeReference ref;
  //	if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
  //		// single variable reference
  //		if (dim == 0) {
  //			ref =
  //				new SingleTypeReference(
  //					identifierStack[identifierPtr],
  //					identifierPositionStack[identifierPtr--]);
  //		} else {
  //			ref =
  //				new ArrayTypeReference(
  //					identifierStack[identifierPtr],
  //					dim,
  //					identifierPositionStack[identifierPtr--]);
  //			ref.sourceEnd = endPosition;
  //		}
  //	} else {
  //		if (length < 0) { //flag for precompiled type reference on base types
  //			ref = TypeReference.baseTypeReference(-length, dim);
  //			ref.sourceStart = intStack[intPtr--];
  //			if (dim == 0) {
  //				ref.sourceEnd = intStack[intPtr--];
  //			} else {
  //				intPtr--;
  //				ref.sourceEnd = endPosition;
  //			}
  //		} else { //Qualified variable reference
  //			char[][] tokens = new char[length][];
  //			identifierPtr -= length;
  //			long[] positions = new long[length];
  //			System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
  //			System.arraycopy(
  //				identifierPositionStack,
  //				identifierPtr + 1,
  //				positions,
  //				0,
  //				length);
  //			if (dim == 0) {
  //				ref = new QualifiedTypeReference(tokens, positions);
  //			} else {
  //				ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
  //				ref.sourceEnd = endPosition;
  //			}
  //		}
  //	};
  //	return ref;
  //}
  public void initialize() {
    //positionning the parser for a new compilation unit
    //avoiding stack reallocation and all that....
    super.initialize(false);
    intArrayPtr = -1;
  }

  /**
   * 
   * INTERNAL USE-ONLY
   */
  //private boolean isLocalDeclaration() {
  //	int nestedDepth = nestedType;
  //	while (nestedDepth >= 0) {
  //		if (nestedMethod[nestedDepth] != 0) {
  //			return true;
  //		}
  //		nestedDepth--;
  //	}
  //	return false;
  //}
  /*
   * Investigate one entire unit.
   */
  public void parseCompilationUnit(ICompilationUnit unit) {
    char[] regionSource = unit.getContents();
    try {
      initialize();
      goForCompilationUnit();
      referenceContext = compilationUnit = compilationUnit = new CompilationUnitDeclaration(problemReporter(),
          new CompilationResult(unit, 0, 0, 10), //this.options.maxProblemsPerUnit),
          regionSource.length);
      scanner.resetTo(0, regionSource.length);
      scanner.setSource(regionSource);
      parse();
    } catch (AbortCompilation ex) {
    }
  }

  /*
   * Investigate one constructor declaration.
   */
  //public void parseConstructor(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForClassBodyDeclarations();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, 10), //this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //}
  /*
   * Investigate one field declaration statement (might have multiple declarations in it).
   */
  //public void parseField(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForFieldDeclaration();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  ///*
  // * Investigate one import statement declaration.
  // */
  //public void parseImport(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForImportDeclaration();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  ///*
  // * Investigate one initializer declaration.
  // * regionSource need to content exactly an initializer declaration.
  // * e.g: static { i = 4; }
  // * { name = "test"; }
  // */
  //public void parseInitializer(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForInitializer();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  ///*
  // * Investigate one method declaration.
  // */
  //public void parseMethod(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForGenericMethodDeclaration();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  ///*
  // * Investigate one package statement declaration.
  // */
  //public void parsePackage(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForPackageDeclaration();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  ///*
  // * Investigate one type declaration, its fields, methods and member types.
  // */
  //public void parseType(char[] regionSource) {
  //	try {
  //		initialize();
  //		goForTypeDeclaration();
  //		referenceContext =
  //			compilationUnit =
  //				compilationUnit =
  //					new CompilationUnitDeclaration(
  //						problemReporter(),
  //						new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
  //						regionSource.length);
  //		scanner.resetTo(0, regionSource.length);
  //		scanner.setSource(regionSource);
  //		parse();
  //	} catch (AbortCompilation ex) {
  //	}
  //
  //}
  /**
   * Returns this parser's problem reporter initialized with its reference context. Also it is assumed that a problem is going to be
   * reported, so initializes the compilation result's line positions.
   */
  public ProblemReporter problemReporter() {
    problemReporter.referenceContext = referenceContext;
    return problemReporter;
  }

  protected void pushOnIntArrayStack(int[] positions) {

    try {
      intArrayStack[++intArrayPtr] = positions;
    } catch (IndexOutOfBoundsException e) {
      //intPtr is correct
      int oldStackLength = intArrayStack.length;
      int oldStack[][] = intArrayStack;
      intArrayStack = new int[oldStackLength + StackIncrement][];
      System.arraycopy(oldStack, 0, intArrayStack, 0, oldStackLength);
      intArrayStack[intArrayPtr] = positions;
    }
  }

  //protected void resetModifiers() {
  //	super.resetModifiers();
  //	declarationSourceStart = -1;
  //}
  /*
   * Syntax error was detected. Will attempt to perform some recovery action in order to resume to the regular parse loop.
   */
  protected boolean resumeOnSyntaxError() {
    return false;
  }
  /*
   * Answer a char array representation of the type name formatted like: - type name + dimensions Example: "A[][]".toCharArray()
   * "java.lang.String".toCharArray()
   */
  //private char[] returnTypeName(TypeReference type) {
  //	int dimension = type.dimensions();
  //	if (dimension != 0) {
  //		char[] dimensionsArray = new char[dimension * 2];
  //		for (int i = 0; i < dimension; i++) {
  //			dimensionsArray[i*2] = '[';
  //			dimensionsArray[(i*2) + 1] = ']';
  //		}
  //		return CharOperation.concat(
  //			CharOperation.concatWith(type.getTypeName(), '.'),
  //			dimensionsArray);
  //	}
  //	return CharOperation.concatWith(type.getTypeName(), '.');
  //}
  //public String toString() {
  //	StringBuffer buffer = new StringBuffer();
  //	buffer.append("intArrayPtr = " + intArrayPtr + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
  //	buffer.append(super.toString());
  //	return buffer.toString();
  //}
  ///**
  // * INTERNAL USE ONLY
  // */
  //protected TypeReference typeReference(
  //	int dim,
  //	int localIdentifierPtr,
  //	int localIdentifierLengthPtr) {
  //	/* build a Reference on a variable that may be qualified or not
  //	 * This variable is a type reference and dim will be its dimensions.
  //	 * We don't have any side effect on the stacks' pointers.
  //	 */
  //
  //	int length;
  //	TypeReference ref;
  //	if ((length = identifierLengthStack[localIdentifierLengthPtr]) == 1) {
  //		// single variable reference
  //		if (dim == 0) {
  //			ref =
  //				new SingleTypeReference(
  //					identifierStack[localIdentifierPtr],
  //					identifierPositionStack[localIdentifierPtr--]);
  //		} else {
  //			ref =
  //				new ArrayTypeReference(
  //					identifierStack[localIdentifierPtr],
  //					dim,
  //					identifierPositionStack[localIdentifierPtr--]);
  //			ref.sourceEnd = endPosition;
  //		}
  //	} else {
  //		if (length < 0) { //flag for precompiled type reference on base types
  //			ref = TypeReference.baseTypeReference(-length, dim);
  //			ref.sourceStart = intStack[localIntPtr--];
  //			if (dim == 0) {
  //				ref.sourceEnd = intStack[localIntPtr--];
  //			} else {
  //				localIntPtr--;
  //				ref.sourceEnd = endPosition;
  //			}
  //		} else { //Qualified variable reference
  //			char[][] tokens = new char[length][];
  //			localIdentifierPtr -= length;
  //			long[] positions = new long[length];
  //			System.arraycopy(identifierStack, localIdentifierPtr + 1, tokens, 0, length);
  //			System.arraycopy(
  //				identifierPositionStack,
  //				localIdentifierPtr + 1,
  //				positions,
  //				0,
  //				length);
  //			if (dim == 0)
  //				ref = new QualifiedTypeReference(tokens, positions);
  //			else
  //				ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
  //		}
  //	};
  //	return ref;
  //}
}