/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann - Contributions for
 *								bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
 *								bug 383973 - [1.8][compiler] syntax recovery in the presence of default methods
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration;

/**
 * OTDT changes:
 * What: support callin/callouts.
 *
 * Internal type structure for parsing recovery
 */

@SuppressWarnings({"rawtypes", "unchecked"})
public class RecoveredType extends RecoveredStatement implements TerminalTokens {
	public static final int MAX_TYPE_DEPTH = 256;

	public TypeDeclaration typeDeclaration;

	public RecoveredAnnotation[] annotations;
	public int annotationCount;

	public int modifiers;
	public int modifiersStart;

	public RecoveredType[] memberTypes;
	public int memberTypeCount;
	public RecoveredField[] fields;
	public int fieldCount;
	public RecoveredMethod[] methods;
	public int methodCount;
//{ObjectTeams:
	public RecoveredMethodMapping[] methodMappings;
	public int methodMappingCount;
// SH}

	public boolean preserveContent = false;	// only used for anonymous types
	public int bodyEnd;

	public boolean insideEnumConstantPart = false;

	public TypeParameter[] pendingTypeParameters;
	public int pendingTypeParametersStart;

	int pendingModifiers;
	int pendingModifersSourceStart = -1;
	RecoveredAnnotation[] pendingAnnotations;
	int pendingAnnotationCount;

public RecoveredType(TypeDeclaration typeDeclaration, RecoveredElement parent, int bracketBalance){
	super(typeDeclaration, parent, bracketBalance);
	this.typeDeclaration = typeDeclaration;
	if(typeDeclaration.allocation != null && typeDeclaration.allocation.type == null) {
		// an enum constant body can not exist if there is no opening brace
		this.foundOpeningBrace = true;
	} else {
		this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
	}
	this.insideEnumConstantPart = TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL;
	if(this.foundOpeningBrace) {
		this.bracketBalance++;
	}

	this.preserveContent = parser().methodRecoveryActivated || parser().statementRecoveryActivated;
}
@Override
public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {

	/* do not consider a method starting passed the type end (if set)
		it must be belonging to an enclosing type */
	if (this.typeDeclaration.declarationSourceEnd != 0
		&& methodDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd){
		this.pendingTypeParameters = null;
		resetPendingModifiers();

		return this.parent.add(methodDeclaration, bracketBalanceValue);
	}

	if (this.methods == null) {
		this.methods = new RecoveredMethod[5];
		this.methodCount = 0;
	} else {
		if (this.methodCount == this.methods.length) {
			System.arraycopy(
				this.methods,
				0,
				(this.methods = new RecoveredMethod[2 * this.methodCount]),
				0,
				this.methodCount);
		}
	}
	RecoveredMethod element = new RecoveredMethod(methodDeclaration, this, bracketBalanceValue, this.recoveringParser);
	this.methods[this.methodCount++] = element;

	if(this.pendingTypeParameters != null) {
		element.attach(this.pendingTypeParameters, this.pendingTypeParametersStart);
		this.pendingTypeParameters = null;
	}

	if(this.pendingAnnotationCount > 0 || this.pendingModifiers != 0) {
		element.attach(
				this.pendingAnnotations,
				this.pendingAnnotationCount,
//{ObjectTeams: AccTeam was obviously not meant for us:
/* orig:
				this.pendingModifiers,
  :giro */
				this.pendingModifiers & ~ExtraCompilerModifiers.AccTeam,
// SH}
				this.pendingModifersSourceStart);
	}
	resetPendingModifiers();

	this.insideEnumConstantPart = false;

	/* consider that if the opening brace was not found, it is there */
	if (!this.foundOpeningBrace){
		this.foundOpeningBrace = true;
		this.bracketBalance++;
	}
	/* if method not finished, then method becomes current */
	if (methodDeclaration.declarationSourceEnd == 0) return element;
	return this;
}
@Override
public RecoveredElement add(Block nestedBlockDeclaration,int bracketBalanceValue) {
	this.pendingTypeParameters = null;
	resetPendingModifiers();

	int mods = ClassFileConstants.AccDefault;
	if(parser().recoveredStaticInitializerStart != 0) {
		mods = ClassFileConstants.AccStatic;
	}
	return this.add(new Initializer(nestedBlockDeclaration, mods), bracketBalanceValue);
}
//{ObjectTeams: MethodMapping:
@Override
public RecoveredElement add(AbstractMethodMappingDeclaration methodMapping, int bracketBalanceValue) {

	/* do not consider a method mapping starting passed the type end (if set)
		it must be belonging to an enclosing type */
	if (this.typeDeclaration.declarationSourceEnd != 0
		&& methodMapping.declarationSourceStart > this.typeDeclaration.declarationSourceEnd){
		this.pendingTypeParameters = null;
		return this.parent.add(methodMapping, bracketBalanceValue);
	}

	if (this.methodMappings == null) {
		this.methodMappings = new RecoveredMethodMapping[5];
		this.methodMappingCount = 0;
	} else {
		if (this.methodMappingCount == this.methodMappings.length) {
			System.arraycopy(
				this.methodMappings,
				0,
				(this.methodMappings = new RecoveredMethodMapping[2 * this.methodMappingCount]),
				0,
				this.methodMappingCount);
		}
	}
	RecoveredMethodMapping element = new RecoveredMethodMapping(methodMapping, this, bracketBalanceValue, this.recoveringParser);
	this.methodMappings[this.methodMappingCount++] = element;

	this.insideEnumConstantPart = false;

	/* consider that if the opening brace (of this type) was not found, it is there */
	if (!this.foundOpeningBrace){
		this.foundOpeningBrace = true;
		this.bracketBalance++;
	}
	/* if methodMapping not finished, then methodMapping becomes current */
	if (methodMapping.declarationSourceEnd == 0) return element;
	return this;
}
// SH}
@Override
public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
	this.pendingTypeParameters = null;

	/* do not consider a field starting passed the type end (if set)
	it must be belonging to an enclosing type */
	if (this.typeDeclaration.declarationSourceEnd != 0
		&& fieldDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd) {

		resetPendingModifiers();

		return this.parent.add(fieldDeclaration, bracketBalanceValue);
	}
	if (this.fields == null) {
		this.fields = new RecoveredField[5];
		this.fieldCount = 0;
	} else {
		if (this.fieldCount == this.fields.length) {
			System.arraycopy(
				this.fields,
				0,
				(this.fields = new RecoveredField[2 * this.fieldCount]),
				0,
				this.fieldCount);
		}
	}
	RecoveredField element;
	switch (fieldDeclaration.getKind()) {
		case AbstractVariableDeclaration.FIELD:
		case AbstractVariableDeclaration.ENUM_CONSTANT:
			element = new RecoveredField(fieldDeclaration, this, bracketBalanceValue);
			break;
		case AbstractVariableDeclaration.INITIALIZER:
			element = new RecoveredInitializer(fieldDeclaration, this, bracketBalanceValue);
			break;
		default:
			// never happens, as field is always identified
			return this;
	}
	this.fields[this.fieldCount++] = element;

	if(this.pendingAnnotationCount > 0) {
		element.attach(
				this.pendingAnnotations,
				this.pendingAnnotationCount,
				this.pendingModifiers,
				this.pendingModifersSourceStart);
	}
	resetPendingModifiers();

	/* consider that if the opening brace was not found, it is there */
	if (!this.foundOpeningBrace){
		this.foundOpeningBrace = true;
		this.bracketBalance++;
	}
	/* if field not finished, then field becomes current */
	if (fieldDeclaration.declarationSourceEnd == 0) return element;
	return this;
}
@Override
public RecoveredElement add(TypeDeclaration memberTypeDeclaration, int bracketBalanceValue) {
	this.pendingTypeParameters = null;

	/* do not consider a type starting passed the type end (if set)
		it must be belonging to an enclosing type */
	if (this.typeDeclaration.declarationSourceEnd != 0
		&& memberTypeDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd){

		resetPendingModifiers();

		return this.parent.add(memberTypeDeclaration, bracketBalanceValue);
	}

	this.insideEnumConstantPart = false;

	if ((memberTypeDeclaration.bits & ASTNode.IsAnonymousType) != 0){
		if (this.methodCount > 0) {
			// add it to the last method body
			RecoveredMethod lastMethod = this.methods[this.methodCount-1];
			lastMethod.methodDeclaration.bodyEnd = 0; // reopen method
			lastMethod.methodDeclaration.declarationSourceEnd = 0; // reopen method
			lastMethod.bracketBalance++; // expect one closing brace

			resetPendingModifiers();

			return lastMethod.add(memberTypeDeclaration, bracketBalanceValue);
		} else {
			// ignore
			return this;
		}
	}

	if (this.memberTypes == null) {
		this.memberTypes = new RecoveredType[5];
		this.memberTypeCount = 0;
	} else {
		if (this.memberTypeCount == this.memberTypes.length) {
			System.arraycopy(
				this.memberTypes,
				0,
				(this.memberTypes = new RecoveredType[2 * this.memberTypeCount]),
				0,
				this.memberTypeCount);
		}
	}
	RecoveredType element = new RecoveredType(memberTypeDeclaration, this, bracketBalanceValue);
	this.memberTypes[this.memberTypeCount++] = element;
//{ObjectTeams: mark members of a team as roles:
	if (this.typeDeclaration.isTeam() && (memberTypeDeclaration.modifiers & ClassFileConstants.AccEnum) == 0)
		memberTypeDeclaration.modifiers |= ExtraCompilerModifiers.AccRole;
// SH}
	if(this.pendingAnnotationCount > 0) {
		element.attach(
				this.pendingAnnotations,
				this.pendingAnnotationCount,
				this.pendingModifiers,
				this.pendingModifersSourceStart);
	}
	resetPendingModifiers();

	/* consider that if the opening brace was not found, it is there */
	if (!this.foundOpeningBrace){
		this.foundOpeningBrace = true;
		this.bracketBalance++;
	}
	/* if member type not finished, then member type becomes current */
	if (memberTypeDeclaration.declarationSourceEnd == 0) return element;
	return this;
}
public void add(TypeParameter[] parameters, int startPos) {
	this.pendingTypeParameters = parameters;
	this.pendingTypeParametersStart = startPos;
}
@Override
public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
	if (this.pendingAnnotations == null) {
		this.pendingAnnotations = new RecoveredAnnotation[5];
		this.pendingAnnotationCount = 0;
	} else {
		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
			System.arraycopy(
				this.pendingAnnotations,
				0,
				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
				0,
				this.pendingAnnotationCount);
		}
	}

	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);

	this.pendingAnnotations[this.pendingAnnotationCount++] = element;

	return element;
}
@Override
public void addModifier(int flag, int modifiersSourceStart) {
	this.pendingModifiers |= flag;

	if (this.pendingModifersSourceStart < 0) {
		this.pendingModifersSourceStart = modifiersSourceStart;
	}
}
public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
	if (annotCount > 0) {
		Annotation[] existingAnnotations = this.typeDeclaration.annotations;
		if (existingAnnotations != null) {
			this.annotations = new RecoveredAnnotation[annotCount];
			this.annotationCount = 0;
			next : for (int i = 0; i < annotCount; i++) {
				for (int j = 0; j < existingAnnotations.length; j++) {
					if (annots[i].annotation == existingAnnotations[j]) continue next;
				}
				this.annotations[this.annotationCount++] = annots[i];
			}
		} else {
			this.annotations = annots;
			this.annotationCount = annotCount;
		}
	}

	if (mods != 0) {
		this.modifiers = mods;
		this.modifiersStart = modsSourceStart;
	}
}
/*
 * Answer the body end of the corresponding parse node
 */
public int bodyEnd(){
	if (this.bodyEnd == 0) return this.typeDeclaration.declarationSourceEnd;
	return this.bodyEnd;
}
public boolean bodyStartsAtHeaderEnd(){
	if (this.typeDeclaration.superInterfaces == null){
		if (this.typeDeclaration.superclass == null){
			if(this.typeDeclaration.typeParameters == null) {
				return this.typeDeclaration.bodyStart == this.typeDeclaration.sourceEnd+1;
			} else {
				return this.typeDeclaration.bodyStart == this.typeDeclaration.typeParameters[this.typeDeclaration.typeParameters.length-1].sourceEnd+1;
			}
		} else {
			return this.typeDeclaration.bodyStart == this.typeDeclaration.superclass.sourceEnd+1;
		}
	} else {
		if (this.typeDeclaration.permittedTypes != null)
			return this.typeDeclaration.bodyStart
			== this.typeDeclaration.permittedTypes[this.typeDeclaration.permittedTypes.length-1].sourceEnd+1;
		return this.typeDeclaration.bodyStart
				== this.typeDeclaration.superInterfaces[this.typeDeclaration.superInterfaces.length-1].sourceEnd+1;
	}
}
/*
 * Answer the enclosing type node, or null if none
 */
@Override
public RecoveredType enclosingType(){
	RecoveredElement current = this.parent;
	while (current != null){
		if (current instanceof RecoveredType){
			return (RecoveredType) current;
		}
		current = current.parent;
	}
	return null;
}
public int lastMemberEnd() {
	int lastMemberEnd = this.typeDeclaration.bodyStart;

	if (this.fieldCount > 0) {
		FieldDeclaration lastField = this.fields[this.fieldCount - 1].fieldDeclaration;
		if (lastMemberEnd < lastField.declarationSourceEnd && lastField.declarationSourceEnd != 0) {
			lastMemberEnd = lastField.declarationSourceEnd;
		}
	}

	if (this.methodCount > 0) {
		AbstractMethodDeclaration lastMethod = this.methods[this.methodCount - 1].methodDeclaration;
		if (lastMemberEnd < lastMethod.declarationSourceEnd && lastMethod.declarationSourceEnd != 0) {
			lastMemberEnd = lastMethod.declarationSourceEnd;
		}
	}

	if (this.memberTypeCount > 0) {
		TypeDeclaration lastType = this.memberTypes[this.memberTypeCount - 1].typeDeclaration;
		if (lastMemberEnd < lastType.declarationSourceEnd && lastType.declarationSourceEnd != 0) {
			lastMemberEnd = lastType.declarationSourceEnd;
		}
	}

	return lastMemberEnd;
}
@Override
public int getLastStart() {
	int lastMemberStart = this.typeDeclaration.bodyStart;

	if (this.fieldCount > 0) {
		FieldDeclaration lastField = this.fields[this.fieldCount - 1].fieldDeclaration;
		if (lastMemberStart < lastField.declarationSourceStart && lastField.declarationSourceStart != 0) {
			lastMemberStart = lastField.declarationSourceStart;
		}
	}

	if (this.methodCount > 0) {
		AbstractMethodDeclaration lastMethod = this.methods[this.methodCount - 1].methodDeclaration;
		if (lastMemberStart < lastMethod.declarationSourceStart && lastMethod.declarationSourceStart != 0) {
			lastMemberStart = lastMethod.declarationSourceStart;
		}
	}

	if (this.memberTypeCount > 0) {
		TypeDeclaration lastType = this.memberTypes[this.memberTypeCount - 1].typeDeclaration;
		if (lastMemberStart < lastType.declarationSourceStart && lastType.declarationSourceStart != 0) {
			lastMemberStart = lastType.declarationSourceStart;
		}
	}

	return lastMemberStart;
}
public char[] name(){
	return this.typeDeclaration.name;
}
/*
 * Answer the associated parsed structure
 */
@Override
public ASTNode parseTree(){
	return this.typeDeclaration;
}
@Override
public void resetPendingModifiers() {
	this.pendingAnnotations = null;
	this.pendingAnnotationCount = 0;
	this.pendingModifiers = 0;
	this.pendingModifersSourceStart = -1;
}
/*
 * Answer the very source end of the corresponding parse node
 */
@Override
public int sourceEnd(){
	return this.typeDeclaration.declarationSourceEnd;
}
@Override
public String toString(int tab) {
	StringBuffer result = new StringBuffer(tabString(tab));
	result.append("Recovered type:\n"); //$NON-NLS-1$
	if ((this.typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
		result.append(tabString(tab));
		result.append(" "); //$NON-NLS-1$
	}
	this.typeDeclaration.print(tab + 1, result);
	if (this.annotations != null) {
		for (int i = 0; i < this.annotationCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.annotations[i].toString(tab + 1));
		}
	}
	if (this.memberTypes != null) {
		for (int i = 0; i < this.memberTypeCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.memberTypes[i].toString(tab + 1));
		}
	}
	if (this.fields != null) {
		for (int i = 0; i < this.fieldCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.fields[i].toString(tab + 1));
		}
	}
	if (this.methods != null) {
		for (int i = 0; i < this.methodCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.methods[i].toString(tab + 1));
		}
	}
//{ObjectTeams:
	if (this.methodMappings != null) {
		for (int i = 0; i < this.methodMappingCount; i++) {
			result.append("\n"); //$NON-NLS-1$
			result.append(this.methodMappings[i].toString(tab + 1));
		}
	}
// SH}
	return result.toString();
}
/*
 * Update the bodyStart of the corresponding parse node
 */
@Override
public void updateBodyStart(int bodyStart){
	this.foundOpeningBrace = true;
	this.typeDeclaration.bodyStart = bodyStart;
}
@Override
public Statement updatedStatement(int depth, Set knownTypes){

	// ignore closed anonymous type
	if ((this.typeDeclaration.bits & ASTNode.IsAnonymousType) != 0 && !this.preserveContent){
		return null;
	}

	TypeDeclaration updatedType = updatedTypeDeclaration(depth + 1, knownTypes);
	if (updatedType != null && (updatedType.bits & ASTNode.IsAnonymousType) != 0){
		/* in presence of an anonymous type, we want the full allocation expression */
		QualifiedAllocationExpression allocation = updatedType.allocation;

		if (allocation.statementEnd == -1) {
			allocation.statementEnd = updatedType.declarationSourceEnd;
		}
		return allocation;
	}
	return updatedType;
}
public TypeDeclaration updatedTypeDeclaration(int depth, Set<TypeDeclaration> knownTypes){
	if (depth >= MAX_TYPE_DEPTH) return null;

	if(knownTypes.contains(this.typeDeclaration)) return null;
	knownTypes.add(this.typeDeclaration);

	int lastEnd = this.typeDeclaration.bodyStart;
	/* update annotations */
	if (this.modifiers != 0) {
		this.typeDeclaration.modifiers |= this.modifiers;
		if (this.modifiersStart < this.typeDeclaration.declarationSourceStart) {
			this.typeDeclaration.declarationSourceStart = this.modifiersStart;
		}
	}
	/* update annotations */
	if (this.annotationCount > 0){
		int existingCount = this.typeDeclaration.annotations == null ? 0 : this.typeDeclaration.annotations.length;
		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
		if (existingCount > 0){
			System.arraycopy(this.typeDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
		}
		for (int i = 0; i < this.annotationCount; i++){
			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
		}
		this.typeDeclaration.annotations = annotationReferences;

		int start = this.annotations[0].annotation.sourceStart;
		if (start < this.typeDeclaration.declarationSourceStart) {
			this.typeDeclaration.declarationSourceStart = start;
		}
	}
	/* update member types */
	if (this.memberTypeCount > 0){
		int existingCount = this.typeDeclaration.memberTypes == null ? 0 : this.typeDeclaration.memberTypes.length;
		TypeDeclaration[] memberTypeDeclarations = new TypeDeclaration[existingCount + this.memberTypeCount];
		if (existingCount > 0){
			System.arraycopy(this.typeDeclaration.memberTypes, 0, memberTypeDeclarations, 0, existingCount);
		}
		// may need to update the declarationSourceEnd of the last type
		if (this.memberTypes[this.memberTypeCount - 1].typeDeclaration.declarationSourceEnd == 0){
			int bodyEndValue = bodyEnd();
			this.memberTypes[this.memberTypeCount - 1].typeDeclaration.declarationSourceEnd = bodyEndValue;
			this.memberTypes[this.memberTypeCount - 1].typeDeclaration.bodyEnd =  bodyEndValue;
		}

		int updatedCount = 0;
		for (int i = 0; i < this.memberTypeCount; i++){
			TypeDeclaration updatedTypeDeclaration = this.memberTypes[i].updatedTypeDeclaration(depth + 1, knownTypes);
			if (updatedTypeDeclaration != null) {
				memberTypeDeclarations[existingCount + (updatedCount++)] = updatedTypeDeclaration;
			}
		}
		if (updatedCount < this.memberTypeCount) {
			int length = existingCount + updatedCount;
			System.arraycopy(memberTypeDeclarations, 0, memberTypeDeclarations = new TypeDeclaration[length], 0, length);
		}

		if (memberTypeDeclarations.length > 0) {
			this.typeDeclaration.memberTypes = memberTypeDeclarations;
			if(memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd > lastEnd) {
				lastEnd = memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd;
			}
		}
	}
	/* update fields */
	if (this.fieldCount > 0){
		int existingCount = this.typeDeclaration.fields == null ? 0 : this.typeDeclaration.fields.length;
		FieldDeclaration[] fieldDeclarations = new FieldDeclaration[existingCount + this.fieldCount];
		if (existingCount > 0){
			System.arraycopy(this.typeDeclaration.fields, 0, fieldDeclarations, 0, existingCount);
		}
		// may need to update the declarationSourceEnd of the last field
		if (this.fields[this.fieldCount - 1].fieldDeclaration.declarationSourceEnd == 0){
			int temp = bodyEnd();
			FieldDeclaration fieldDeclaration = this.fields[this.fieldCount - 1].fieldDeclaration;
			if (temp == 0 && fieldDeclaration.sourceEnd > 0) {
				temp = fieldDeclaration.sourceEnd;
				if (lastEnd > temp) lastEnd = temp;
			}
			fieldDeclaration.declarationSourceEnd = temp;
			fieldDeclaration.declarationEnd = temp;
		}
		for (int i = 0; i < this.fieldCount; i++){
			fieldDeclarations[existingCount + i] = this.fields[i].updatedFieldDeclaration(depth, knownTypes);
		}

		for (int i = this.fieldCount - 1; 0 < i; i--) {
			if (fieldDeclarations[existingCount + i - 1].declarationSourceStart == fieldDeclarations[existingCount + i].declarationSourceStart) {
				fieldDeclarations[existingCount + i - 1].declarationSourceEnd = fieldDeclarations[existingCount + i].declarationSourceEnd;
				fieldDeclarations[existingCount + i - 1].declarationEnd = fieldDeclarations[existingCount + i].declarationEnd;
			}
		}

		this.typeDeclaration.fields = fieldDeclarations;
		if(fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd > lastEnd) {
			lastEnd = fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd;
		}
	}
	/* update methods */
	int existingCount = this.typeDeclaration.methods == null ? 0 : this.typeDeclaration.methods.length;
	boolean hasConstructor = false, hasRecoveredConstructor = false;
	boolean hasAbstractMethods = false;
	int defaultConstructorIndex = -1;
	if (this.methodCount > 0){
		AbstractMethodDeclaration[] methodDeclarations = new AbstractMethodDeclaration[existingCount + this.methodCount];
		for (int i = 0; i < existingCount; i++){
			AbstractMethodDeclaration m = this.typeDeclaration.methods[i];
			if (m.isDefaultConstructor()) defaultConstructorIndex = i;
			if (m.isAbstract()) hasAbstractMethods = true;
			methodDeclarations[i] = m;
		}
		// may need to update the declarationSourceEnd of the last method
		if (this.methods[this.methodCount - 1].methodDeclaration.declarationSourceEnd == 0){
			int bodyEndValue = bodyEnd();
			this.methods[this.methodCount - 1].methodDeclaration.declarationSourceEnd = bodyEndValue;
			this.methods[this.methodCount - 1].methodDeclaration.bodyEnd = bodyEndValue;
		}
		int totalMethods = existingCount;
		next:
		for (int i = 0; i < this.methodCount; i++){
			for (int j = 0; j < existingCount; j++) {
				if (methodDeclarations[j] == this.methods[i].methodDeclaration)
					continue next;
			}
			AbstractMethodDeclaration updatedMethod = this.methods[i].updatedMethodDeclaration(depth, knownTypes);
			if (updatedMethod.isConstructor()) hasRecoveredConstructor = true;
			if (updatedMethod.isAbstract()) hasAbstractMethods = true;
			methodDeclarations[totalMethods ++] = updatedMethod;
		}
		if (totalMethods != methodDeclarations.length)
			System.arraycopy(methodDeclarations, 0, methodDeclarations = new AbstractMethodDeclaration[totalMethods], 0, totalMethods);
		this.typeDeclaration.methods = methodDeclarations;
		if(methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd > lastEnd) {
			lastEnd = methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd;
		}
		if (hasAbstractMethods) this.typeDeclaration.bits |= ASTNode.HasAbstractMethods;
		hasConstructor = this.typeDeclaration.checkConstructors(parser());
	} else {
		for (int i = 0; i < existingCount; i++){
			if (this.typeDeclaration.methods[i].isConstructor()) hasConstructor = true;
		}
	}
//{ObjectTeams:callins/callouts:
	/* update method mappings */
	if (this.methodMappingCount > 0){
		existingCount = this.typeDeclaration.callinCallouts == null ? 0 : this.typeDeclaration.callinCallouts.length;
		AbstractMethodMappingDeclaration[] mappingDecls = new AbstractMethodMappingDeclaration[existingCount + this.methodMappingCount];
		if (existingCount > 0){
			System.arraycopy(this.typeDeclaration.callinCallouts, 0, mappingDecls, 0, existingCount);
		}
		// may need to update the declarationSourceEnd of the last field
		int bodyEndValue = bodyEnd();
		if (this.methodMappings[this.methodMappingCount - 1].methodMappingDeclaration.declarationSourceEnd == 0){
			this.methodMappings[this.methodMappingCount - 1].methodMappingDeclaration.declarationSourceEnd = bodyEndValue;
			this.methodMappings[this.methodMappingCount - 1].methodMappingDeclaration.bodyEnd = bodyEndValue;
		}
		for (int i = 0; i < this.methodMappingCount; i++){
			mappingDecls[existingCount + i] = this.methodMappings[i].updatedMethodMappingDeclaration(bodyEndValue);
		}
		this.typeDeclaration.callinCallouts = mappingDecls;
	}
	this.typeDeclaration.copyPredicates(); // otherwise done in Parser.dispatchDeclarationInto
// SH}
	/* add clinit ? */
	if (this.typeDeclaration.needClassInitMethod()){
		boolean alreadyHasClinit = false;
		for (int i = 0; i < existingCount; i++){
			if (this.typeDeclaration.methods[i].isClinit()){
				alreadyHasClinit = true;
				break;
			}
		}
		if (!alreadyHasClinit) this.typeDeclaration.addClinit();
	}
	/* add default constructor ? */
	if (defaultConstructorIndex >= 0 && hasRecoveredConstructor){
		/* should discard previous default construtor */
		AbstractMethodDeclaration[] methodDeclarations = new AbstractMethodDeclaration[this.typeDeclaration.methods.length - 1];
		if (defaultConstructorIndex != 0){
			System.arraycopy(this.typeDeclaration.methods, 0, methodDeclarations, 0, defaultConstructorIndex);
		}
		if (defaultConstructorIndex != this.typeDeclaration.methods.length-1){
			System.arraycopy(
				this.typeDeclaration.methods,
				defaultConstructorIndex+1,
				methodDeclarations,
				defaultConstructorIndex,
				this.typeDeclaration.methods.length - defaultConstructorIndex - 1);
		}
		this.typeDeclaration.methods = methodDeclarations;
	} else {
		int kind = TypeDeclaration.kind(this.typeDeclaration.modifiers);
		if (!hasConstructor &&
				kind != TypeDeclaration.INTERFACE_DECL &&
				kind != TypeDeclaration.ANNOTATION_TYPE_DECL &&
				kind != TypeDeclaration.RECORD_DECL &&
				this.typeDeclaration.allocation == null) {// if was already reduced, then constructor
			boolean insideFieldInitializer = false;
			RecoveredElement parentElement = this.parent;
			while (parentElement != null){
				if (parentElement instanceof RecoveredField){
						insideFieldInitializer = true;
						break;
				}
				parentElement = parentElement.parent;
			}
			this.typeDeclaration.createDefaultConstructor(!parser().diet || insideFieldInitializer, true);
		}
	}
	if (this.parent instanceof RecoveredType){
		this.typeDeclaration.bits |= ASTNode.IsMemberType;
	} else if (this.parent instanceof RecoveredMethod){
		this.typeDeclaration.bits |= ASTNode.IsLocalType;
	}
	if(this.typeDeclaration.declarationSourceEnd == 0) {
		this.typeDeclaration.declarationSourceEnd = lastEnd;
		this.typeDeclaration.bodyEnd = lastEnd;
	}
	return this.typeDeclaration;
}
/*
 * Update the corresponding parse node from parser state which
 * is about to disappear because of restarting recovery
 */
@Override
public void updateFromParserState(){

	// anymous type and enum constant doesn't need to be updated
	if(bodyStartsAtHeaderEnd() && this.typeDeclaration.allocation == null){
		Parser parser = parser();
		/* might want to recover implemented interfaces */
		// protection for bugs 15142
		if (parser.listLength > 0 && parser.astLengthPtr > 0){ // awaiting interface type references
			int length = parser.astLengthStack[parser.astLengthPtr];
			int astPtr = parser.astPtr - length;
			boolean canConsume = astPtr >= 0;
			if(canConsume) {
				if((!(parser.astStack[astPtr] instanceof TypeDeclaration))) {
					canConsume = false;
				}
				for (int i = 1, max = length + 1; i < max; i++) {
					if(!(parser.astStack[astPtr + i ] instanceof TypeReference)) {
						canConsume = false;
						break;
					}
				}
			}
			if(canConsume) {
				parser.consumeClassHeaderImplements();
				// will reset typeListLength to zero
				// thus this check will only be performed on first errorCheck after class X implements Y,Z,
			}
		} else if (parser.listTypeParameterLength > 0) {
			int length = parser.listTypeParameterLength;
			int genericsPtr = parser.genericsPtr;
			boolean canConsume = genericsPtr + 1 >= length && parser.astPtr > -1;
			if(canConsume) {
				if (!(parser.astStack[parser.astPtr] instanceof TypeDeclaration)) {
					canConsume = false;
				}
				while(genericsPtr + 1 > length && !(parser.genericsStack[genericsPtr] instanceof TypeParameter)) {
					genericsPtr--;
				}
				for (int i = 0; i < length; i++) {
					if(!(parser.genericsStack[genericsPtr - i] instanceof TypeParameter)) {
						canConsume = false;
						break;
					}
				}
			}
			if(canConsume) {
				TypeDeclaration typeDecl = (TypeDeclaration)parser.astStack[parser.astPtr];
				System.arraycopy(parser.genericsStack, genericsPtr - length + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
				typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
				parser.listTypeParameterLength = 0;
				parser.lastCheckPoint = typeDecl.bodyStart;
			}
		}
	}
//{ObjectTeams: update unfinished type-level predicate:
	if (   this.typeDeclaration.predicate != null
		&& this.typeDeclaration.predicate.bodyStart == 0)
	{
		Parser parser = parser();
		if (parser.expressionPtr > -1)
			parser.consumePredicateExpression();
		else
			this.typeDeclaration.predicate.tagAsHavingErrors();
		// will be copied to methods by updatedTypeDeclaration.
	}
// SH}
}
/*
 * A closing brace got consumed, might have closed the current element,
 * in which case both the currentElement is exited
 */
@Override
public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
	if ((--this.bracketBalance <= 0) && (this.parent != null)){
		this.updateSourceEndIfNecessary(braceStart, braceEnd);
		this.bodyEnd = braceStart - 1;
		return this.parent;
	}
	return this;
}
/*
 * An opening brace got consumed, might be the expected opening one of the current element,
 * in which case the bodyStart is updated.
 */
@Override
public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
	/* in case the opening brace is not close enough to the signature, ignore it */
	if (this.bracketBalance == 0){
		/*
			if (parser.scanner.searchLineNumber(typeDeclaration.sourceEnd)
				!= parser.scanner.searchLineNumber(braceEnd)){
		 */
		Parser parser = parser();
		switch(parser.lastIgnoredToken){
			case -1 :
			case TokenNameextends :
			case TokenNameimplements :
			case TokenNameRestrictedIdentifierpermits:
			case TokenNameGREATER :
			case TokenNameRIGHT_SHIFT :
			case TokenNameUNSIGNED_RIGHT_SHIFT :
				if (parser.recoveredStaticInitializerStart == 0) break;
			//$FALL-THROUGH$
			default:
				this.foundOpeningBrace = true;
				this.bracketBalance = 1; // pretend the brace was already there
		}
	}
	// might be an initializer
	if (this.bracketBalance == 1){
		Block block = new Block(0);
		Parser parser = parser();
		block.sourceStart = parser.scanner.startPosition;
		Initializer init;
		if (parser.recoveredStaticInitializerStart == 0){
			init = new Initializer(block, ClassFileConstants.AccDefault);
		} else {
			init = new Initializer(block, ClassFileConstants.AccStatic);
			init.declarationSourceStart = parser.recoveredStaticInitializerStart;
		}
		init.bodyStart = parser.scanner.currentPosition;
		return this.add(init, 1);
	}
	return super.updateOnOpeningBrace(braceStart, braceEnd);
}
@Override
public void updateParseTree(){
	updatedTypeDeclaration(0, new HashSet());
}
/*
 * Update the declarationSourceEnd of the corresponding parse node
 */
@Override
public void updateSourceEndIfNecessary(int start, int end){
	if (this.typeDeclaration.declarationSourceEnd == 0){
		this.bodyEnd = 0;
		this.typeDeclaration.declarationSourceEnd = end;
		this.typeDeclaration.bodyEnd = end;
	}
}
public void annotationsConsumed(Annotation[] consumedAnnotations) {
	RecoveredAnnotation[] keep = new RecoveredAnnotation[this.pendingAnnotationCount];
	int numKeep = 0;
	int pendingCount = this.pendingAnnotationCount;
	int consumedLength = consumedAnnotations.length;
	outerLoop:
	for (int i = 0; i < pendingCount; i++) {
		Annotation pendingAnnotationAST = this.pendingAnnotations[i].annotation;
		for (int j = 0; j < consumedLength; j++) {
			if (consumedAnnotations[j] == pendingAnnotationAST)
				continue outerLoop;
		}
		keep[numKeep++] = this.pendingAnnotations[i];
	}
	if (numKeep != this.pendingAnnotationCount) {
		this.pendingAnnotations = keep;
		this.pendingAnnotationCount = numKeep;
	}
}
//{ObjectTeams: remove an unwanted method:
// (a) for methods converted to MethodSpecLong
// (b) if a syntax error in method binding is detected too late
void removeCurrentMethod () {
    this.methods[--this.methodCount] = null;
}
// SH}

}
