/*******************************************************************************
 * Copyright (c) 2000, 2014 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Jesper S Moller - Contributions for
 *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
 *							Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile
 *							Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit)
 *							Bug 412149 - [1.8][compiler] Emit repeated annotations into the designated container
 *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
 *                          Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
 *                          Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly
 *                          Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped
 *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
 *                          Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
 *                          Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
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.codegen.AnnotationContext;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
import org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackDepthMarker;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker;
import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
import org.eclipse.jdt.internal.compiler.util.Messages;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.ModelElement;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TypeModel;

/**
 * Represents a class file wrapper on bytes, it is aware of its actual
 * type name.
 *
 * Public APIs are listed below:
 *
 * byte[] getBytes();
 *		Answer the actual bytes of the class file
 *
 * char[][] getCompoundName();
 * 		Answer the compound name of the class file.
 * 		For example, {{java}, {util}, {Hashtable}}.
 *
 * byte[] getReducedBytes();
 * 		Answer a smaller byte format, which is only contains some structural
 *      information. Those bytes are decodable with a regular class file reader,
 *      such as DietClassFileReader
 *
 * OTDT changes:
 * What: write OT-specific class attributes + Synthetic
 *
 * What: change sourceName() -> internalName()
 * Why:  avoid beautified name of role classes
 *
 * What: isRequiredToClearPrivateModifier also clears AccProtected for interface methods.
 * Why:  role ifc methods can have any modifiers, but they must be public in the byte code.
 *
 * What: allow resizing of the contents from AbstractAttribute and its subclasses.
 *
 * What: Pass class file name from AbstractImageBuilder down to TypeModel
 *       (See comment near field generatingModel).
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class ClassFile implements TypeConstants, TypeIds {

	private byte[] bytes;
	public CodeStream codeStream;
	public ConstantPool constantPool;

	public int constantPoolOffset;

	// the header contains all the bytes till the end of the constant pool
	public byte[] contents;

	public int contentsOffset;

	protected boolean creatingProblemType;

	public ClassFile enclosingClassFile;
	public byte[] header;
	// that collection contains all the remaining bytes of the .class file
	public int headerOffset;
	public Set innerClassesBindings;
	public List bootstrapMethods = null;
	public int methodCount;
	public int methodCountOffset;
	// pool managment
	boolean isShared = false;
	// used to generate private access methods
	// debug and stack map attributes
	public int produceAttributes;
	public SourceTypeBinding referenceBinding;
	public boolean isNestedType;
	public long targetJDK;

	public List missingTypes = null;

	public Set visitedTypes;

	public static final int INITIAL_CONTENTS_SIZE = 400;
	public static final int INITIAL_HEADER_SIZE = 1500;
	public static final int INNER_CLASSES_SIZE = 5;

	/**
	 * INTERNAL USE-ONLY
	 * Request the creation of a ClassFile compatible representation of a problematic type
	 *
	 * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
	 * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
	 */
	public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
//{ObjectTeams: don't generate code from types that have entered the compilation process
//      via SourceTypeConverter (at least line number positions are missing).
//      There should be no need to generate this code (except for copy inheritance??).
//      See also TypeDeclaration.generateCode().
//		Note that a converted role file may be a membertype of another (non-converted) type.
		if (typeDeclaration.isConverted)
			return;
//SH}

		SourceTypeBinding typeBinding = typeDeclaration.binding;
		ClassFile classFile = ClassFile.getNewInstance(typeBinding);
		classFile.initialize(typeBinding, null, true);

		if (typeBinding.hasMemberTypes()) {
			// see bug 180109
			ReferenceBinding[] members = typeBinding.memberTypes;
			for (int i = 0, l = members.length; i < l; i++)
				classFile.recordInnerClasses(members[i]);
		}
		// TODO (olivier) handle cases where a field cannot be generated (name too long)
		// TODO (olivier) handle too many methods
		// inner attributes
		if (typeBinding.isNestedType()) {
			classFile.recordInnerClasses(typeBinding);
		}
		TypeVariableBinding[] typeVariables = typeBinding.typeVariables();
		for (int i = 0, max = typeVariables.length; i < max; i++) {
			TypeVariableBinding typeVariableBinding = typeVariables[i];
			if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
				Util.recordNestedType(classFile, typeVariableBinding);
			}
		}
		// add its fields
		FieldBinding[] fields = typeBinding.fields();
		if ((fields != null) && (fields != Binding.NO_FIELDS)) {
			classFile.addFieldInfos();
		} else {
			// we have to set the number of fields to be equals to 0
			classFile.contents[classFile.contentsOffset++] = 0;
			classFile.contents[classFile.contentsOffset++] = 0;
		}
		// leave some space for the methodCount
		classFile.setForMethodInfos();
		// add its user defined methods
		int problemsLength;
		CategorizedProblem[] problems = unitResult.getErrors();
		if (problems == null) {
			problems = new CategorizedProblem[0];
		}
		CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);

		AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
		boolean abstractMethodsOnly = false;
		if (methodDecls != null) {
			if (typeBinding.isInterface()) {
				if (typeBinding.scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8)
					abstractMethodsOnly = true;
				// We generate a clinit which contains all the problems, since we may not be able to generate problem methods (< 1.8) and problem constructors (all levels).
				classFile.addProblemClinit(problemsCopy);
			}
			for (int i = 0, length = methodDecls.length; i < length; i++) {
				AbstractMethodDeclaration methodDecl = methodDecls[i];
				MethodBinding method = methodDecl.binding;
				if (method == null) continue;
//{ObjectTeams: may still need to keep abstract flag:
				boolean isAbstractRoleModel = method.isStatic() && method.declaringClass.isRole();
// orig:
				if (abstractMethodsOnly) {
					method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
				}
// :giro
				if (isAbstractRoleModel) method.modifiers |= ClassFileConstants.AccStatic;
// SH}
				if (method.isConstructor()) {
					if (typeBinding.isInterface()) continue;
					classFile.addProblemConstructor(methodDecl, method, problemsCopy);
				} else if (method.isAbstract()) {
					classFile.addAbstractMethod(methodDecl, method);
				} else {
					classFile.addProblemMethod(methodDecl, method, problemsCopy);
				}
			}
			// add abstract methods
			classFile.addDefaultAbstractMethods();
		}

		// propagate generation of (problem) member types
		if (typeDeclaration.memberTypes != null) {
			for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
				TypeDeclaration memberType = typeDeclaration.memberTypes[i];
				if (memberType.binding != null) {
					ClassFile.createProblemType(memberType, unitResult);
				}
			}
		}
		classFile.addAttributes();
		unitResult.record(typeBinding.constantPoolName(), classFile);
	}
	public static ClassFile getNewInstance(SourceTypeBinding typeBinding) {
		LookupEnvironment env = typeBinding.scope.environment();
		return env.classFilePool.acquire(typeBinding);
	}
	/**
	 * INTERNAL USE-ONLY
	 * This methods creates a new instance of the receiver.
	 */
	protected ClassFile() {
		// default constructor for subclasses
	}

	public ClassFile(SourceTypeBinding typeBinding) {
		// default constructor for subclasses
		this.constantPool = new ConstantPool(this);
		final CompilerOptions options = typeBinding.scope.compilerOptions();
		this.targetJDK = options.targetJDK;
		this.produceAttributes = options.produceDebugAttributes;
		this.referenceBinding = typeBinding;
		this.isNestedType = typeBinding.isNestedType();
		if (this.targetJDK >= ClassFileConstants.JDK1_6) {
			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
			if (this.targetJDK >= ClassFileConstants.JDK1_8) {
				this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
				this.codeStream = new TypeAnnotationCodeStream(this);
				if (options.produceMethodParameters) {
					this.produceAttributes |= ClassFileConstants.ATTR_METHOD_PARAMETERS;
				}
			} else {
				this.codeStream = new StackMapFrameCodeStream(this);
			}
		} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
			this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
			this.codeStream = new StackMapFrameCodeStream(this);
		} else {
			this.codeStream = new CodeStream(this);
		}
		initByteArrays();
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a bogus method.
	 *
	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
	 */
	public void addAbstractMethod(
			AbstractMethodDeclaration method,
			MethodBinding methodBinding) {

//{ObjectTeams: role ifc methods may have funny modifiers (static, callin), don't destroy the original binding 
		if (methodBinding.declaringClass.isSynthInterface())
			methodBinding = new MethodBinding(methodBinding, methodBinding.declaringClass);
// SH}
		this.generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		int attributeNumber = this.generateMethodInfoAttributes(methodBinding);
		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
	}

	/**
	 * INTERNAL USE-ONLY
	 * This methods generate all the attributes for the receiver.
	 * For a class they could be:
	 * - source file attribute
	 * - inner classes attribute
	 * - deprecated attribute
	 */
	public void addAttributes() {
		// update the method count
		this.contents[this.methodCountOffset++] = (byte) (this.methodCount >> 8);
		this.contents[this.methodCountOffset] = (byte) this.methodCount;

		int attributesNumber = 0;
		// leave two bytes for the number of attributes and store the current offset
		int attributeOffset = this.contentsOffset;
		this.contentsOffset += 2;

		// source attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) {
			String fullFileName =
				new String(this.referenceBinding.scope.referenceCompilationUnit().getFileName());
			fullFileName = fullFileName.replace('\\', '/');
			int lastIndex = fullFileName.lastIndexOf('/');
			if (lastIndex != -1) {
				fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
			}
			attributesNumber += generateSourceAttribute(fullFileName);
		}
//{ObjectTeams: write OT-specific attributes:
        attributesNumber += ModelElement.writeAttributes(this.referenceBinding, this);
// SH}
//{ObjectTeams: convert synthetic flag to attribute :(
		if (this.referenceBinding.isSynthInterface()) {
			// Synthetic attribute
			// Check that there is enough space to write the Synthetic attribute
			if (this.contentsOffset + 6 >= this.contents.length) {
				resizeContents(6);
			}
			int syntheticAttributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
			this.contents[this.contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) syntheticAttributeNameIndex;
			// the length of a synthetic attribute is equals to 0
			this.contents[this.contentsOffset++] = 0;
			this.contents[this.contentsOffset++] = 0;
			this.contents[this.contentsOffset++] = 0;
			this.contents[this.contentsOffset++] = 0;

			attributesNumber++;
		}
// SH}
		// Deprecated attribute
		if (this.referenceBinding.isDeprecated()) {
			// check that there is enough space to write all the bytes for the field info corresponding
			// to the @fieldBinding
			attributesNumber += generateDeprecatedAttribute();
		}
		// add signature attribute
		char[] genericSignature = this.referenceBinding.genericSignature();
		if (genericSignature != null) {
			attributesNumber += generateSignatureAttribute(genericSignature);
		}
		if (this.targetJDK >= ClassFileConstants.JDK1_5
				&& this.referenceBinding.isNestedType()
				&& !this.referenceBinding.isMemberType()) {
			// add enclosing method attribute (1.5 mode only)
			attributesNumber += generateEnclosingMethodAttribute();
		}
		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
			TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
			if (typeDeclaration != null) {
				final Annotation[] annotations = typeDeclaration.annotations;
				if (annotations != null) {
					long targetMask;
					if (typeDeclaration.isPackageInfo())
						targetMask = TagBits.AnnotationForPackage;
					else if (this.referenceBinding.isAnnotationType())
						targetMask = TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType;
					else
						targetMask = TagBits.AnnotationForType | TagBits.AnnotationForTypeUse;
					attributesNumber += generateRuntimeAnnotations(annotations, targetMask); 
				}
			}
		}

		if (this.referenceBinding.isHierarchyInconsistent()) {
			ReferenceBinding superclass = this.referenceBinding.superclass;
			if (superclass != null) {
				this.missingTypes = superclass.collectMissingTypes(this.missingTypes);
			}
			ReferenceBinding[] superInterfaces = this.referenceBinding.superInterfaces();
			for (int i = 0, max = superInterfaces.length; i < max; i++) {
				this.missingTypes = superInterfaces[i].collectMissingTypes(this.missingTypes);
			}
			attributesNumber += generateHierarchyInconsistentAttribute();
		}
		// Functional expression and lambda bootstrap methods
		if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) {
			attributesNumber += generateBootstrapMethods(this.bootstrapMethods);
		}
		// Inner class attribute
		int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
		if (numberOfInnerClasses != 0) {
			ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses];
			this.innerClassesBindings.toArray(innerClasses);
			Arrays.sort(innerClasses, new Comparator() {
				public int compare(Object o1, Object o2) {
					TypeBinding binding1 = (TypeBinding) o1;
					TypeBinding binding2 = (TypeBinding) o2;
					return CharOperation.compareTo(binding1.constantPoolName(), binding2.constantPoolName());
				}
			});
			attributesNumber += generateInnerClassAttribute(numberOfInnerClasses, innerClasses);
		}
		if (this.missingTypes != null) {
			generateMissingTypesAttribute();
			attributesNumber++;
		}
		
		attributesNumber += generateTypeAnnotationAttributeForTypeDeclaration();
		
		// update the number of attributes
		if (attributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[attributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[attributeOffset] = (byte) attributesNumber;

		// resynchronize all offsets of the classfile
		this.header = this.constantPool.poolContent;
		this.headerOffset = this.constantPool.currentOffset;
		int constantPoolCount = this.constantPool.currentIndex;
		this.header[this.constantPoolOffset++] = (byte) (constantPoolCount >> 8);
		this.header[this.constantPoolOffset] = (byte) constantPoolCount;
	}
	/**
	 * INTERNAL USE-ONLY
	 * This methods generate all the default abstract method infos that correpond to
	 * the abstract methods inherited from superinterfaces.
	 */
	public void addDefaultAbstractMethods() { // default abstract methods
		MethodBinding[] defaultAbstractMethods =
			this.referenceBinding.getDefaultAbstractMethods();
		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
			MethodBinding methodBinding = defaultAbstractMethods[i];
			generateMethodInfoHeader(methodBinding);
			int methodAttributeOffset = this.contentsOffset;
			int attributeNumber = generateMethodInfoAttributes(methodBinding);
			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
		}
	}

	private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffset) {
		int attributesNumber = 0;
		// 4.7.2 only static constant fields get a ConstantAttribute
		// Generate the constantValueAttribute
		Constant fieldConstant = fieldBinding.constant();
		if (fieldConstant != Constant.NotAConstant){
			attributesNumber += generateConstantValueAttribute(fieldConstant, fieldBinding, fieldAttributeOffset);
		}
		if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) {
			attributesNumber += generateSyntheticAttribute();
		}
		if (fieldBinding.isDeprecated()) {
			attributesNumber += generateDeprecatedAttribute();
		}
		// add signature attribute
		char[] genericSignature = fieldBinding.genericSignature();
		if (genericSignature != null) {
			attributesNumber += generateSignatureAttribute(genericSignature);
		}
		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
			FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
			if (fieldDeclaration != null) {
				Annotation[] annotations = fieldDeclaration.annotations;
				if (annotations != null) {
					attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForField);
				}

				if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
					List allTypeAnnotationContexts = new ArrayList();
					if (annotations != null && (fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
						fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
					}
					int invisibleTypeAnnotationsCounter = 0;
					int visibleTypeAnnotationsCounter = 0;
					TypeReference fieldType = fieldDeclaration.type;
					if (fieldType != null && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) {
						fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
					}
					int size = allTypeAnnotationContexts.size();
					if (size != 0) {
						AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
						allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
						for (int i = 0, max = allTypeAnnotationContextsArray.length; i < max; i++) {
							AnnotationContext annotationContext = allTypeAnnotationContextsArray[i];
							if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
								invisibleTypeAnnotationsCounter++;
								allTypeAnnotationContexts.add(annotationContext);
							} else {
								visibleTypeAnnotationsCounter++;
								allTypeAnnotationContexts.add(annotationContext);
							}
						}
						attributesNumber += generateRuntimeTypeAnnotations(
								allTypeAnnotationContextsArray,
								visibleTypeAnnotationsCounter,
								invisibleTypeAnnotationsCounter);
					}
				}
			}
		}
		if ((fieldBinding.tagBits & TagBits.HasMissingType) != 0) {
			this.missingTypes = fieldBinding.type.collectMissingTypes(this.missingTypes);
		}
		return attributesNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * This methods generates the bytes for the given field binding
	 * @param fieldBinding the given field binding
	 */
	private void addFieldInfo(FieldBinding fieldBinding) {
		// check that there is enough space to write all the bytes for the field info corresponding
		// to the @fieldBinding
		if (this.contentsOffset + 8 >= this.contents.length) {
			resizeContents(8);
		}
		// Now we can generate all entries into the byte array
		// First the accessFlags
		int accessFlags = fieldBinding.getAccessFlags();
		if (this.targetJDK < ClassFileConstants.JDK1_5) {
			// pre 1.5, synthetic was an attribute, not a modifier
			accessFlags &= ~ClassFileConstants.AccSynthetic;
		}
//{ObjectTeams: clear private/protected for fields in synthetic role interfaces:
		if ((fieldBinding.tagBits & TagBits.ClearPrivateModifier) != 0) {
            accessFlags &= ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected);
            accessFlags |= ClassFileConstants.AccPublic;
		}
// SH}
		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
		this.contents[this.contentsOffset++] = (byte) accessFlags;
		// Then the nameIndex
		int nameIndex = this.constantPool.literalIndex(fieldBinding.name);
		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) nameIndex;
		// Then the descriptorIndex
		int descriptorIndex = this.constantPool.literalIndex(fieldBinding.type);
		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
		int fieldAttributeOffset = this.contentsOffset;
		int attributeNumber = 0;
		// leave some space for the number of attributes
		this.contentsOffset += 2;
		attributeNumber += addFieldAttributes(fieldBinding, fieldAttributeOffset);
		if (this.contentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
//{ObjectTeams: write OT-specific byte code attributes
        if (fieldBinding.model != null)
            attributeNumber += fieldBinding.model.writeAttributes(this);
// SH}
		this.contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[fieldAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * This methods generate all the fields infos for the receiver.
	 * This includes:
	 * - a field info for each defined field of that class
	 * - a field info for each synthetic field (e.g. this$0)
	 */
	/**
	 * INTERNAL USE-ONLY
	 * This methods generate all the fields infos for the receiver.
	 * This includes:
	 * - a field info for each defined field of that class
	 * - a field info for each synthetic field (e.g. this$0)
	 */
	public void addFieldInfos() {
		SourceTypeBinding currentBinding = this.referenceBinding;
		FieldBinding[] syntheticFields = currentBinding.syntheticFields();
		int fieldCount = 	currentBinding.fieldCount() + (syntheticFields == null ? 0 : syntheticFields.length);

		// write the number of fields
		if (fieldCount > 0xFFFF) {
			this.referenceBinding.scope.problemReporter().tooManyFields(this.referenceBinding.scope.referenceType());
		}
		this.contents[this.contentsOffset++] = (byte) (fieldCount >> 8);
		this.contents[this.contentsOffset++] = (byte) fieldCount;

//{ObjectTeams: fields for value parameters (don't bother to generate AST for those)
		for (SyntheticArgumentBinding argBinding : currentBinding.valueParamSynthArgs())
			if (argBinding.matchingField != null)
				addFieldInfo(argBinding.matchingField);
// SH}

		FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields;
		for (int i = 0, max = fieldDecls == null ? 0 : fieldDecls.length; i < max; i++) {
			FieldDeclaration fieldDecl = fieldDecls[i];
			if (fieldDecl.binding != null) {
				addFieldInfo(fieldDecl.binding);
			}
		}

		if (syntheticFields != null) {
			for (int i = 0, max = syntheticFields.length; i < max; i++) {
				addFieldInfo(syntheticFields[i]);
			}
		}
	}

	private void addMissingAbstractProblemMethod(MethodDeclaration methodDeclaration, MethodBinding methodBinding, CategorizedProblem problem, CompilationResult compilationResult) {
		// always clear the strictfp/native/abstract bit for a problem method
		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
		int methodAttributeOffset = this.contentsOffset;
		int attributeNumber = generateMethodInfoAttributes(methodBinding);

		// Code attribute
		attributeNumber++;

		int codeAttributeOffset = this.contentsOffset;
		generateCodeAttributeHeader();
		StringBuffer buffer = new StringBuffer(25);
		buffer.append("\t"  + problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.insert(0, Messages.compilation_unresolvedProblem);
		String problemString = buffer.toString();

		this.codeStream.init(this);
		this.codeStream.preserveUnusedLocals = true;
		this.codeStream.initializeMaxLocals(methodBinding);

		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
		this.codeStream.generateCodeAttributeForProblemMethod(problemString);

		completeCodeAttributeForMissingAbstractProblemMethod(
			methodBinding,
			codeAttributeOffset,
			compilationResult.getLineSeparatorPositions(),
			problem.getSourceLineNumber());

		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem clinit method info that correspond to a boggus method.
	 *
	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
	 */
	public void addProblemClinit(CategorizedProblem[] problems) {
		generateMethodInfoHeaderForClinit();
		// leave two spaces for the number of attributes
		this.contentsOffset -= 2;
		int attributeOffset = this.contentsOffset;
		this.contentsOffset += 2;
		int attributeNumber = 0;

		int codeAttributeOffset = this.contentsOffset;
		generateCodeAttributeHeader();
		this.codeStream.resetForProblemClinit(this);
		String problemString = "" ; //$NON-NLS-1$
		int problemLine = 0;
		if (problems != null) {
			int max = problems.length;
			StringBuffer buffer = new StringBuffer(25);
			int count = 0;
			for (int i = 0; i < max; i++) {
				CategorizedProblem problem = problems[i];
				if ((problem != null) && (problem.isError())) {
					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
					count++;
					if (problemLine == 0) {
						problemLine = problem.getSourceLineNumber();
					}
					problems[i] = null;
				}
			} // insert the top line afterwards, once knowing how many problems we have to consider
			if (count > 1) {
				buffer.insert(0, Messages.compilation_unresolvedProblems);
			} else {
				buffer.insert(0, Messages.compilation_unresolvedProblem);
			}
			problemString = buffer.toString();
		}

		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
		attributeNumber++; // code attribute
		completeCodeAttributeForClinit(
			codeAttributeOffset,
			problemLine);
		if (this.contentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[attributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[attributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a boggus constructor.
	 *
	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
	 */
	public void addProblemConstructor(
		AbstractMethodDeclaration method,
		MethodBinding methodBinding,
		CategorizedProblem[] problems) {
		
		if (methodBinding.declaringClass.isInterface()) {
			method.abort(ProblemSeverities.AbortType, null);
		}

		// always clear the strictfp/native/abstract bit for a problem method
		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
		int methodAttributeOffset = this.contentsOffset;
		int attributesNumber = generateMethodInfoAttributes(methodBinding);

		// Code attribute
		attributesNumber++;
		int codeAttributeOffset = this.contentsOffset;
		generateCodeAttributeHeader();
		this.codeStream.reset(method, this);
		String problemString = "" ; //$NON-NLS-1$
		int problemLine = 0;
		if (problems != null) {
			int max = problems.length;
			StringBuffer buffer = new StringBuffer(25);
			int count = 0;
			for (int i = 0; i < max; i++) {
				CategorizedProblem problem = problems[i];
				if ((problem != null) && (problem.isError())) {
					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
					count++;
					if (problemLine == 0) {
						problemLine = problem.getSourceLineNumber();
					}
				}
			} // insert the top line afterwards, once knowing how many problems we have to consider
			if (count > 1) {
				buffer.insert(0, Messages.compilation_unresolvedProblems);
			} else {
				buffer.insert(0, Messages.compilation_unresolvedProblem);
			}
			problemString = buffer.toString();
		}

		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
		completeCodeAttributeForProblemMethod(
			method,
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions(),
			problemLine);
		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
	}
	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a boggus constructor.
	 * Reset the position inside the contents byte array to the savedOffset.
	 *
	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
	 * @param savedOffset <CODE>int</CODE>
	 */
	public void addProblemConstructor(
		AbstractMethodDeclaration method,
		MethodBinding methodBinding,
		CategorizedProblem[] problems,
		int savedOffset) {
		// we need to move back the contentsOffset to the value at the beginning of the method
		this.contentsOffset = savedOffset;
		this.methodCount--; // we need to remove the method that causes the problem
		addProblemConstructor(method, methodBinding, problems);
	}
	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a boggus method.
	 *
	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
	 */
	public void addProblemMethod(
		AbstractMethodDeclaration method,
		MethodBinding methodBinding,
		CategorizedProblem[] problems) {
		if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) {
			method.abort(ProblemSeverities.AbortType, null);
		}
		// always clear the strictfp/native/abstract bit for a problem method
		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
		int methodAttributeOffset = this.contentsOffset;
		int attributesNumber = generateMethodInfoAttributes(methodBinding);
//{ObjectTeams: write OT-specific byte code attributes
        if (method.model != null)
            attributesNumber += method.model.writeAttributes(this);
// SH}

		// Code attribute
		attributesNumber++;

		int codeAttributeOffset = this.contentsOffset;
		generateCodeAttributeHeader();
		this.codeStream.reset(method, this);
		String problemString = "" ; //$NON-NLS-1$
		int problemLine = 0;
		if (problems != null) {
			int max = problems.length;
			StringBuffer buffer = new StringBuffer(25);
			int count = 0;
			for (int i = 0; i < max; i++) {
				CategorizedProblem problem = problems[i];
				if ((problem != null)
					&& (problem.isError())
					&& (problem.getSourceStart() >= method.declarationSourceStart)
					&& (problem.getSourceEnd() <= method.declarationSourceEnd)) {
					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
					count++;
					if (problemLine == 0) {
						problemLine = problem.getSourceLineNumber();
					}
					problems[i] = null;
				}
			} // insert the top line afterwards, once knowing how many problems we have to consider
			if (count > 1) {
				buffer.insert(0, Messages.compilation_unresolvedProblems);
			} else {
				buffer.insert(0, Messages.compilation_unresolvedProblem);
			}
			problemString = buffer.toString();
		}

		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
		completeCodeAttributeForProblemMethod(
			method,
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions(),
			problemLine);
		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a boggus method.
	 * Reset the position inside the contents byte array to the savedOffset.
	 *
	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
	 * @param savedOffset <CODE>int</CODE>
	 */
	public void addProblemMethod(
		AbstractMethodDeclaration method,
		MethodBinding methodBinding,
		CategorizedProblem[] problems,
		int savedOffset) {
		// we need to move back the contentsOffset to the value at the beginning of the method
		this.contentsOffset = savedOffset;
		this.methodCount--; // we need to remove the method that causes the problem
		addProblemMethod(method, methodBinding, problems);
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for all the special method infos.
	 * They are:
	 * - synthetic access methods
	 * - default abstract methods
	 * - lambda methods.
	 */
	public void addSpecialMethods() {

		// add all methods (default abstract methods and synthetic)

		// default abstract methods
		generateMissingAbstractMethods(this.referenceBinding.scope.referenceType().missingAbstractMethods, this.referenceBinding.scope.referenceCompilationUnit().compilationResult);

		MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods();
		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
			MethodBinding methodBinding = defaultAbstractMethods[i];
			generateMethodInfoHeader(methodBinding);
			int methodAttributeOffset = this.contentsOffset;
			int attributeNumber = generateMethodInfoAttributes(methodBinding);
			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
		}
		
		// add synthetic methods infos
		int emittedSyntheticsCount = 0;
		boolean continueScanningSynthetics = true;
		while (continueScanningSynthetics) {
			continueScanningSynthetics = false;
			SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods();
			int currentSyntheticsCount = syntheticMethods == null ? 0: syntheticMethods.length;
			if (emittedSyntheticsCount != currentSyntheticsCount) {
				for (int i = emittedSyntheticsCount, max = currentSyntheticsCount; i < max; i++) {
					SyntheticMethodBinding syntheticMethod = syntheticMethods[i];
					switch (syntheticMethod.purpose) {
						case SyntheticMethodBinding.FieldReadAccess :
						case SyntheticMethodBinding.SuperFieldReadAccess :
							// generate a method info to emulate an reading access to
							// a non-accessible field
							addSyntheticFieldReadAccessMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.FieldWriteAccess :
						case SyntheticMethodBinding.SuperFieldWriteAccess :
							// generate a method info to emulate an writing access to
							// a non-accessible field
							addSyntheticFieldWriteAccessMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.MethodAccess :
						case SyntheticMethodBinding.SuperMethodAccess :
						case SyntheticMethodBinding.BridgeMethod :
//{ObjectTeams: more kinds:
						case SyntheticMethodBinding.RoleMethodBridgeInner :
						case SyntheticMethodBinding.RoleMethodBridgeOuter :
// SH}
							// generate a method info to emulate an access to a non-accessible method / super-method or bridge method
							addSyntheticMethodAccessMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.ConstructorAccess :
							// generate a method info to emulate an access to a non-accessible constructor
							addSyntheticConstructorAccessMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.EnumValues :
							// generate a method info to define <enum>#values()
							addSyntheticEnumValuesMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.EnumValueOf :
							// generate a method info to define <enum>#valueOf(String)
							addSyntheticEnumValueOfMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.SwitchTable :
							// generate a method info to define the switch table synthetic method
							addSyntheticSwitchTable(syntheticMethod);
							break;
						case SyntheticMethodBinding.TooManyEnumsConstants :
							addSyntheticEnumInitializationMethod(syntheticMethod);
							break;
						case SyntheticMethodBinding.LambdaMethod:
							syntheticMethod.lambda.generateCode(this.referenceBinding.scope, this);
							continueScanningSynthetics = true; // lambda code generation could schedule additional nested lambdas for code generation.
							break;
						case SyntheticMethodBinding.ArrayConstructor:
							addSyntheticArrayConstructor(syntheticMethod);
							break;
						case SyntheticMethodBinding.ArrayClone:
							addSyntheticArrayClone(syntheticMethod);
							break;
						case SyntheticMethodBinding.FactoryMethod:
							addSyntheticFactoryMethod(syntheticMethod);
							break;	
						case SyntheticMethodBinding.DeserializeLambda:
							// TODO [andy] do we need to do this after the loop to ensure it is done last?
							addSyntheticDeserializeLambda(syntheticMethod,this.referenceBinding.syntheticMethods()); 
							break;
					}
				}
				emittedSyntheticsCount = currentSyntheticsCount;
			}
		}
	}

	public void addSyntheticArrayConstructor(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForArrayConstructor(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}
	public void addSyntheticArrayClone(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForArrayClone(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}
	public void addSyntheticFactoryMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForFactoryMethod(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}
	/**
	 * INTERNAL USE-ONLY
	 * Generate the bytes for a synthetic method that provides an access to a private constructor.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForConstructorAccess(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 *  Generate the bytes for a synthetic method that implements Enum#valueOf(String) for a given enum type
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForEnumValueOf(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) {
			attributeNumber += generateMethodParameters(methodBinding);
		}
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 *  Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForEnumValues(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	public void addSyntheticEnumInitializationMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForEnumInitializationMethod(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}
	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a synthetic method that
	 * generate an read access to a private field.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for a problem method info that correspond to a synthetic method that
	 * generate an write access to a private field.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the bytes for a synthetic method that provides access to a private method.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
	 */
	public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
//{ObjectTeams: base call surrogate may have callin flags to store the original return type
		if (methodBinding.model != null)
			attributeNumber += methodBinding.model.writeAttributes(this);
// SH}
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
		completeCodeAttributeForSyntheticMethod(
			true,
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 *
	 * @param codeAttributeOffset <CODE>int</CODE>
	 */
	public void completeCodeAttribute(int codeAttributeOffset) {
		// reinitialize the localContents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside localContents byte array before we started to write
		// any information about the codeAttribute
		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
		// to get the right position, 6 for the max_stack etc...
		int code_length = this.codeStream.position;
		if (code_length > 65535) {
			if (this.codeStream.methodDeclaration != null) {
				this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.methodDeclaration);
			} else {
				this.codeStream.lambdaExpression.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.lambdaExpression);
			}
		}
		if (localContentsOffset + 20 >= this.contents.length) {
			resizeContents(20);
		}
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;

		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
		// write the exception table
		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
		}
		int exSize = exceptionHandlersCount * 8 + 2;
		if (exSize + localContentsOffset >= this.contents.length) {
			resizeContents(exSize);
		}
		// there is no exception table, so we need to offset by 2 the current offset and move
		// on the attribute generation
		this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
		this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
			ExceptionLabel exceptionLabel = exceptionLabels[i];
			if (exceptionLabel != null) {
				int iRange = 0, maxRange = exceptionLabel.getCount();
				if ((maxRange & 1) != 0) {
					if (this.codeStream.methodDeclaration != null) {
						this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
								this.codeStream.methodDeclaration);
					} else {
						this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.lambdaExpression.binding.selector)),
								this.codeStream.lambdaExpression);
					}
				}
				while (iRange < maxRange) {
					int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
					this.contents[localContentsOffset++] = (byte) (start >> 8);
					this.contents[localContentsOffset++] = (byte) start;
					int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
					this.contents[localContentsOffset++] = (byte) (end >> 8);
					this.contents[localContentsOffset++] = (byte) end;
					int handlerPC = exceptionLabel.position;
					if (addStackMaps) {
						StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
						stackMapFrameCodeStream.addFramePosition(handlerPC);
//						stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
					}
					this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
					this.contents[localContentsOffset++] = (byte) handlerPC;
					if (exceptionLabel.exceptionType == null) {
						// any exception handler
						this.contents[localContentsOffset++] = 0;
						this.contents[localContentsOffset++] = 0;
					} else {
						int nameIndex;
						if (exceptionLabel.exceptionType == TypeBinding.NULL) {
							/* represents ClassNotFoundException, see class literal access*/
							nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
						} else {
							nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
						}
						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
						this.contents[localContentsOffset++] = (byte) nameIndex;
					}
				}
			}
		}
		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0;
		// leave two bytes for the attribute_length
		localContentsOffset += 2;
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;

		// first we handle the linenumber attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
			attributesNumber += generateLineNumberAttribute();
		}
		// then we do the local variable attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.isStatic() : this.codeStream.lambdaExpression.binding.isStatic();
			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
		}

		if (addStackMaps) {
			attributesNumber += generateStackMapTableAttribute(
					this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}
		
		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
			attributesNumber += generateTypeAnnotationsOnCodeAttribute();
		}

		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;

		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}
	
	public int generateTypeAnnotationsOnCodeAttribute() {
		int attributesNumber = 0;
		
		List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts;
		int invisibleTypeAnnotationsCounter = 0;
		int visibleTypeAnnotationsCounter = 0;

		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
			LocalVariableBinding localVariable = this.codeStream.locals[i];
			if (localVariable.isCatchParameter()) continue;
			LocalDeclaration declaration = localVariable.declaration;
			if (declaration == null
					|| (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0))
					|| (localVariable.initializationCount == 0)
					|| ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
				continue;
			}
			int targetType = ((localVariable.tagBits & TagBits.IsResource) == 0) ? AnnotationTargetTypeConstants.LOCAL_VARIABLE : AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
			declaration.getAllAnnotationContexts(targetType, localVariable, allTypeAnnotationContexts);
		}
		
		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
			ExceptionLabel exceptionLabel = exceptionLabels[i];
			if (exceptionLabel.exceptionTypeReference != null && (exceptionLabel.exceptionTypeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
				exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, i, allTypeAnnotationContexts, exceptionLabel.se7Annotations);
			}
		}
		
		int size = allTypeAnnotationContexts.size();
		if (size != 0) {
			AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
			allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
			for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
				AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
					invisibleTypeAnnotationsCounter++;
				} else {
					visibleTypeAnnotationsCounter++;
				}
			}
			attributesNumber += generateRuntimeTypeAnnotations(
					allTypeAnnotationContextsArray,
					visibleTypeAnnotationsCounter,
					invisibleTypeAnnotationsCounter);
		}
		return attributesNumber;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 *
	 * @param codeAttributeOffset <CODE>int</CODE>
	 */
	public void completeCodeAttributeForClinit(int codeAttributeOffset) {
		// reinitialize the contents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside contents byte array before we started to write
		// any information about the codeAttribute
		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
		// to get the right position, 6 for the max_stack etc...
		int code_length = this.codeStream.position;
		if (code_length > 65535) {
			this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
				this.codeStream.methodDeclaration.scope.referenceType());
		}
		if (localContentsOffset + 20 >= this.contents.length) {
			resizeContents(20);
		}
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;

		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
		// write the exception table
		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
		}
		int exSize = exceptionHandlersCount * 8 + 2;
		if (exSize + localContentsOffset >= this.contents.length) {
			resizeContents(exSize);
		}
		// there is no exception table, so we need to offset by 2 the current offset and move
		// on the attribute generation
		this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
		this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
			ExceptionLabel exceptionLabel = exceptionLabels[i];
			if (exceptionLabel != null) {
				int iRange = 0, maxRange = exceptionLabel.getCount();
				if ((maxRange & 1) != 0) {
					this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
							Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
							this.codeStream.methodDeclaration);
				}
				while  (iRange < maxRange) {
					int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
					this.contents[localContentsOffset++] = (byte) (start >> 8);
					this.contents[localContentsOffset++] = (byte) start;
					int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
					this.contents[localContentsOffset++] = (byte) (end >> 8);
					this.contents[localContentsOffset++] = (byte) end;
					int handlerPC = exceptionLabel.position;
					this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
					this.contents[localContentsOffset++] = (byte) handlerPC;
					if (addStackMaps) {
						StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
						stackMapFrameCodeStream.addFramePosition(handlerPC);
//						stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
					}
					if (exceptionLabel.exceptionType == null) {
						// any exception handler
						this.contents[localContentsOffset++] = 0;
						this.contents[localContentsOffset++] = 0;
					} else {
						int nameIndex;
						if (exceptionLabel.exceptionType == TypeBinding.NULL) {
							/* represents denote ClassNotFoundException, see class literal access*/
							nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
						} else {
							nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
						}
						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
						this.contents[localContentsOffset++] = (byte) nameIndex;
					}
				}
			}
		}
		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0;
		// leave two bytes for the attribute_length
		localContentsOffset += 2;
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;

		// first we handle the linenumber attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
			attributesNumber += generateLineNumberAttribute();
		}
		// then we do the local variable attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
			attributesNumber += generateLocalVariableTableAttribute(code_length, true, false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
			attributesNumber += generateStackMapTableAttribute(
					null,
					code_length,
					codeAttributeOffset,
					max_locals,
					true);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					null,
					code_length,
					codeAttributeOffset,
					max_locals,
					true);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
			attributesNumber += generateTypeAnnotationsOnCodeAttribute();
		}

		// update the number of attributes
		// ensure first that there is enough space available inside the contents array
		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 */
	public void completeCodeAttributeForClinit(
			int codeAttributeOffset,
			int problemLine) {
		// reinitialize the contents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside contents byte array before we started to write
		// any information about the codeAttribute
		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
		// to get the right position, 6 for the max_stack etc...
		int code_length = this.codeStream.position;
		if (code_length > 65535) {
			this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
				this.codeStream.methodDeclaration.scope.referenceType());
		}
		if (localContentsOffset + 20 >= this.contents.length) {
			resizeContents(20);
		}
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;

		// write the exception table
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;

		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0; // leave two bytes for the attribute_length
		localContentsOffset += 2; // first we handle the linenumber attribute
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;
		// first we handle the linenumber attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
			attributesNumber += generateLineNumberAttribute(problemLine);
		}
		localContentsOffset = this.contentsOffset;
		// then we do the local variable attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
			int localVariableNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
			if (localContentsOffset + 8 >= this.contents.length) {
				resizeContents(8);
			}
			this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
			this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = 2;
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = 0;
			attributesNumber++;
		}

		this.contentsOffset = localContentsOffset;

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
			attributesNumber += generateStackMapTableAttribute(
					null,
					code_length,
					codeAttributeOffset,
					max_locals,
					true);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					null,
					code_length,
					codeAttributeOffset,
					max_locals,
					true);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
			attributesNumber += generateTypeAnnotationsOnCodeAttribute();
		}
		
		// update the number of attributes
		// ensure first that there is enough space available inside the contents array
		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}


	/**
	 *
	 */
	public void completeCodeAttributeForMissingAbstractProblemMethod(
			MethodBinding binding,
			int codeAttributeOffset,
			int[] startLineIndexes,
			int problemLine) {
		// reinitialize the localContents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		int code_length = this.codeStream.position;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;
		// write the exception table
		if (localContentsOffset + 50 >= this.contents.length) {
			resizeContents(50);
		}
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0; // leave two bytes for the attribute_length
		localContentsOffset += 2; // first we handle the linenumber attribute
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
			if (problemLine == 0) {
				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
			}
			attributesNumber += generateLineNumberAttribute(problemLine);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
			attributesNumber += generateStackMapTableAttribute(
					binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		// then we do the local variable attribute
		// update the number of attributes// ensure first that there is enough space available inside the localContents array
		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 *
	 * @param codeAttributeOffset <CODE>int</CODE>
	 */
	public void completeCodeAttributeForProblemMethod(
			AbstractMethodDeclaration method,
			MethodBinding binding,
			int codeAttributeOffset,
			int[] startLineIndexes,
			int problemLine) {
		// reinitialize the localContents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		int code_length = this.codeStream.position;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;
		// write the exception table
		if (localContentsOffset + 50 >= this.contents.length) {
			resizeContents(50);
		}

		// write the exception table
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0; // leave two bytes for the attribute_length
		localContentsOffset += 2; // first we handle the linenumber attribute
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
			if (problemLine == 0) {
				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
			}
			attributesNumber += generateLineNumberAttribute(problemLine);
		}

		// then we do the local variable attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic();
			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
			attributesNumber += generateStackMapTableAttribute(
					binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		// update the number of attributes// ensure first that there is enough space available inside the localContents array
		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 *
	 * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
	 * @param codeAttributeOffset <CODE>int</CODE>
	 */
	public void completeCodeAttributeForSyntheticMethod(
			boolean hasExceptionHandlers,
			SyntheticMethodBinding binding,
			int codeAttributeOffset,
			int[] startLineIndexes) {
		// reinitialize the contents with the byte modified by the code stream
		this.contents = this.codeStream.bCodeStream;
		int localContentsOffset = this.codeStream.classFileOffset;
		// codeAttributeOffset is the position inside contents byte array before we started to write
		// any information about the codeAttribute
		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
		// to get the right position, 6 for the max_stack etc...
		int max_stack = this.codeStream.stackMax;
		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
		int max_locals = this.codeStream.maxLocals;
		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
		int code_length = this.codeStream.position;
		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
		this.contents[codeAttributeOffset + 13] = (byte) code_length;
		if ((localContentsOffset + 40) >= this.contents.length) {
			resizeContents(40);
		}

		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
		if (hasExceptionHandlers) {
			// write the exception table
			ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
			int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
			for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
				exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
			}
			int exSize = exceptionHandlersCount * 8 + 2;
			if (exSize + localContentsOffset >= this.contents.length) {
				resizeContents(exSize);
			}
			// there is no exception table, so we need to offset by 2 the current offset and move
			// on the attribute generation
			this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
			this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
			for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
				ExceptionLabel exceptionLabel = exceptionLabels[i];
				if (exceptionLabel != null) {
					int iRange = 0, maxRange = exceptionLabel.getCount();
					if ((maxRange & 1) != 0) {
						this.referenceBinding.scope.problemReporter().abortDueToInternalError(
								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(binding.selector),
										this.referenceBinding.scope.problemReporter().referenceContext));
					}
					while  (iRange < maxRange) {
						int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
						this.contents[localContentsOffset++] = (byte) (start >> 8);
						this.contents[localContentsOffset++] = (byte) start;
						int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
						this.contents[localContentsOffset++] = (byte) (end >> 8);
						this.contents[localContentsOffset++] = (byte) end;
						int handlerPC = exceptionLabel.position;
						if (addStackMaps) {
							StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
							stackMapFrameCodeStream.addFramePosition(handlerPC);
						}
						this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
						this.contents[localContentsOffset++] = (byte) handlerPC;
						if (exceptionLabel.exceptionType == null) {
							// any exception handler
							this.contents[localContentsOffset++] = 0;
							this.contents[localContentsOffset++] = 0;
						} else {
							int nameIndex;
							switch(exceptionLabel.exceptionType.id) {
								case T_null :
									/* represents ClassNotFoundException, see class literal access*/
									nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
									break;
								case T_long :
									/* represents NoSuchFieldError, see switch table generation*/
									nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
									break;
								default:
									nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
							}
							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
							this.contents[localContentsOffset++] = (byte) nameIndex;
						}
					}
				}
			}
		} else {
			// there is no exception table, so we need to offset by 2 the current offset and move
			// on the attribute generation
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = 0;
		}
		// debug attributes
		int codeAttributeAttributeOffset = localContentsOffset;
		int attributesNumber = 0;
		// leave two bytes for the attribute_length
		localContentsOffset += 2;
		if (localContentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}

		this.contentsOffset = localContentsOffset;
		// first we handle the linenumber attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
//{ObjectTeams: synthetics have their linenumber stored already:
/* orig:
			int lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
  :giro */
			int lineNumber = binding.getLineNumber();
			if (lineNumber == -1)
				lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
// SH}
			attributesNumber += generateLineNumberAttribute(lineNumber);
		}
		// then we do the local variable attribute
		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
			final boolean methodDeclarationIsStatic = binding.isStatic();
			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true);
		}
		if (addStackMaps) {
			attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false);
		}

		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
			attributesNumber += generateStackMapAttribute(
					binding,
					code_length,
					codeAttributeOffset,
					max_locals,
					false);
		}

		// update the number of attributes
		// ensure first that there is enough space available inside the contents array
		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;

		// update the attribute length
		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method completes the creation of the code attribute by setting
	 * - the attribute_length
	 * - max_stack
	 * - max_locals
	 * - code_length
	 * - exception table
	 * - and debug attributes if necessary.
	 *
	 * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
	 * @param codeAttributeOffset <CODE>int</CODE>
	 */
	public void completeCodeAttributeForSyntheticMethod(
			SyntheticMethodBinding binding,
			int codeAttributeOffset,
			int[] startLineIndexes) {

		this.completeCodeAttributeForSyntheticMethod(
				false,
				binding,
				codeAttributeOffset,
				startLineIndexes);
	}

	/**
	 * INTERNAL USE-ONLY
	 * Complete the creation of a method info by setting up the number of attributes at the right offset.
	 *
	 * @param methodAttributeOffset <CODE>int</CODE>
	 * @param attributesNumber <CODE>int</CODE>
	 */
	public void completeMethodInfo(
			MethodBinding binding,
			int methodAttributeOffset,
			int attributesNumber) {
		
		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
			List allTypeAnnotationContexts = new ArrayList();
			int invisibleTypeAnnotationsCounter = 0;
			int visibleTypeAnnotationsCounter = 0;
			AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
			if (methodDeclaration != null) {
				if ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
					Argument[] arguments = methodDeclaration.arguments;
					if (arguments != null) {
						for (int i = 0, max = arguments.length; i < max; i++) {
							Argument argument = arguments[i];
							if ((argument.bits & ASTNode.HasTypeAnnotations) != 0) {
								argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, i, allTypeAnnotationContexts);
							}
						}
					}
					Receiver receiver = methodDeclaration.receiver;
					if (receiver != null && (receiver.type.bits & ASTNode.HasTypeAnnotations) != 0) {
						receiver.type.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RECEIVER, allTypeAnnotationContexts);
					}
				}
				Annotation[] annotations = methodDeclaration.annotations;
				if (annotations != null && !methodDeclaration.isClinit() && (methodDeclaration.isConstructor() || binding.returnType.id != T_void)) {
					methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
				}
				if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) {
					MethodDeclaration declaration = (MethodDeclaration) methodDeclaration;
					TypeReference typeReference = declaration.returnType;
					if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
						typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
					}
				}
				TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
				if (thrownExceptions != null) {
					for (int i = 0, max = thrownExceptions.length; i < max; i++) {
						TypeReference thrownException = thrownExceptions[i];
						thrownException.getAllAnnotationContexts(AnnotationTargetTypeConstants.THROWS, i, allTypeAnnotationContexts);
					}
				}
				TypeParameter[] typeParameters = methodDeclaration.typeParameters();
				if (typeParameters != null) {
					for (int i = 0, max = typeParameters.length; i < max; i++) {
						TypeParameter typeParameter = typeParameters[i];
						if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
							typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER, i, allTypeAnnotationContexts);
						}
					}
				}
			}
			int size = allTypeAnnotationContexts.size();
			if (size != 0) {
				AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
				allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
				for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
					AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
					if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
						invisibleTypeAnnotationsCounter++;
					} else {
						visibleTypeAnnotationsCounter++;
					}
				}
				attributesNumber += generateRuntimeTypeAnnotations(
						allTypeAnnotationContextsArray,
						visibleTypeAnnotationsCounter,
						invisibleTypeAnnotationsCounter);
			}
		}
		if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) {
			attributesNumber += generateMethodParameters(binding);
		}
		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributesNumber;
	}
	
	private void dumpLocations(int[] locations) {
		if (locations == null) {
			// no type path
			if (this.contentsOffset + 1 >= this.contents.length) {
				resizeContents(1);
			}
			this.contents[this.contentsOffset++] = (byte) 0;
		} else {
			int length = locations.length;
			if (this.contentsOffset + length >= this.contents.length) {
				resizeContents(length + 1);
			}
			this.contents[this.contentsOffset++] = (byte) (locations.length / 2);
			for (int i = 0; i < length; i++) {
				this.contents[this.contentsOffset++] = (byte) locations[i];
			}
		}
	}
	private void dumpTargetTypeContents(int targetType, AnnotationContext annotationContext) {
		switch(targetType) {
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
				// parameter index
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;

			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
				// type_parameter_index
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				// bound_index
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
				break;				
			case AnnotationTargetTypeConstants.FIELD :
			case AnnotationTargetTypeConstants.METHOD_RECEIVER :
			case AnnotationTargetTypeConstants.METHOD_RETURN :
				 // target_info is empty_target
				break;
			case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
				// target_info is parameter index
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
				
			case AnnotationTargetTypeConstants.INSTANCEOF :
			case AnnotationTargetTypeConstants.NEW :
			case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
			case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
			case AnnotationTargetTypeConstants.METHOD_REFERENCE :
				// bytecode offset for new/instanceof/method_reference
				// exception table entry index for exception_parameter
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
			case AnnotationTargetTypeConstants.CAST :
				// bytecode offset
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
				break;
				
			case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
			case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
			case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
			case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
				// bytecode offset
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				// type_argument_index 
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
				break;
				
			case AnnotationTargetTypeConstants.CLASS_EXTENDS :
			case AnnotationTargetTypeConstants.THROWS :			
				// For CLASS_EXTENDS - info is supertype index (-1 = superclass)
				// For THROWS - info is exception table index
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
				
			case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
			case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
				int localVariableTableOffset = this.contentsOffset;
				LocalVariableBinding localVariable = annotationContext.variableBinding;
				int actualSize = 0;
				int initializationCount = localVariable.initializationCount;
				actualSize += 6 * initializationCount;
				// reserve enough space
				if (this.contentsOffset + actualSize >= this.contents.length) {
					resizeContents(actualSize);
				}
				this.contentsOffset += 2;
				int numberOfEntries = 0;
				for (int j = 0; j < initializationCount; j++) {
					int startPC = localVariable.initializationPCs[j << 1];
					int endPC = localVariable.initializationPCs[(j << 1) + 1];
					if (startPC != endPC) { // only entries for non zero length
						// now we can safely add the local entry
						numberOfEntries++;
						this.contents[this.contentsOffset++] = (byte) (startPC >> 8);
						this.contents[this.contentsOffset++] = (byte) startPC;
						int length = endPC - startPC;
						this.contents[this.contentsOffset++] = (byte) (length >> 8);
						this.contents[this.contentsOffset++] = (byte) length;
						int resolvedPosition = localVariable.resolvedPosition;
						this.contents[this.contentsOffset++] = (byte) (resolvedPosition >> 8);
						this.contents[this.contentsOffset++] = (byte) resolvedPosition;
					}
				}
				this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
				this.contents[localVariableTableOffset] = (byte) numberOfEntries;
				break;
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
				break;
		}
	}



	/**
	 * INTERNAL USE-ONLY
	 * This methods returns a char[] representing the file name of the receiver
	 *
	 * @return char[]
	 */
	public char[] fileName() {
		return this.constantPool.UTF8Cache.returnKeyFor(2);
	}

	private void generateAnnotation(Annotation annotation, int currentOffset) {
		int startingContentsOffset = currentOffset;
		if (this.contentsOffset + 4 >= this.contents.length) {
			resizeContents(4);
		}
		TypeBinding annotationTypeBinding = annotation.resolvedType;
		if (annotationTypeBinding == null) {
			this.contentsOffset = startingContentsOffset;
			return;
		}
		if (annotationTypeBinding.isMemberType()) {
			this.recordInnerClasses(annotationTypeBinding);
		}
		final int typeIndex = this.constantPool.literalIndex(annotationTypeBinding.signature());
		this.contents[this.contentsOffset++] = (byte) (typeIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) typeIndex;
		if (annotation instanceof NormalAnnotation) {
			NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
			MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
			if (memberValuePairs != null) {
				final int memberValuePairsLength = memberValuePairs.length;
				this.contents[this.contentsOffset++] = (byte) (memberValuePairsLength >> 8);
				this.contents[this.contentsOffset++] = (byte) memberValuePairsLength;
				for (int i = 0; i < memberValuePairsLength; i++) {
					MemberValuePair memberValuePair = memberValuePairs[i];
					if (this.contentsOffset + 2 >= this.contents.length) {
						resizeContents(2);
					}
					final int elementNameIndex = this.constantPool.literalIndex(memberValuePair.name);
					this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
					this.contents[this.contentsOffset++] = (byte) elementNameIndex;
					MethodBinding methodBinding = memberValuePair.binding;
					if (methodBinding == null) {
						this.contentsOffset = startingContentsOffset;
					} else {
						try {
							generateElementValue(memberValuePair.value, methodBinding.returnType, startingContentsOffset);
						} catch(ClassCastException e) {
							this.contentsOffset = startingContentsOffset;
						} catch(ShouldNotImplement e) {
							this.contentsOffset = startingContentsOffset;
						}
					}
				}
			} else {
				this.contents[this.contentsOffset++] = 0;
				this.contents[this.contentsOffset++] = 0;
			}
		} else if (annotation instanceof SingleMemberAnnotation) {
			SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
			// this is a single member annotation (one member value)
			this.contents[this.contentsOffset++] = 0;
			this.contents[this.contentsOffset++] = 1;
			if (this.contentsOffset + 2 >= this.contents.length) {
				resizeContents(2);
			}
			final int elementNameIndex = this.constantPool.literalIndex(VALUE);
			this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) elementNameIndex;
			MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
			if (methodBinding == null) {
				this.contentsOffset = startingContentsOffset;
			} else {
				try {
					generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType, startingContentsOffset);
				} catch(ClassCastException e) {
					this.contentsOffset = startingContentsOffset;
				} catch(ShouldNotImplement e) {
					this.contentsOffset = startingContentsOffset;
				}
			}
		} else {
			// this is a marker annotation (no member value pairs)
			this.contents[this.contentsOffset++] = 0;
			this.contents[this.contentsOffset++] = 0;
		}
	}

	private int generateAnnotationDefaultAttribute(AnnotationMethodDeclaration declaration, int attributeOffset) {
		int attributesNumber = 0;
		// add an annotation default attribute
		int annotationDefaultNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.AnnotationDefaultName);
		if (this.contentsOffset + 6 >= this.contents.length) {
			resizeContents(6);
		}
		this.contents[this.contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) annotationDefaultNameIndex;
		int attributeLengthOffset = this.contentsOffset;
		this.contentsOffset += 4;
		generateElementValue(declaration.defaultValue, declaration.binding.returnType, attributeOffset);
		if (this.contentsOffset != attributeOffset) {
			int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
			this.contents[attributeLengthOffset++] = (byte) attributeLength;
			attributesNumber++;
		}
		return attributesNumber;
	}
	/**
	 * INTERNAL USE-ONLY
	 * That method generates the header of a code attribute.
	 * - the index inside the constant pool for the attribute name ("Code")
	 * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4).
	 */
	public void generateCodeAttributeHeader() {
		if (this.contentsOffset + 20 >= this.contents.length) {
			resizeContents(20);
		}
		int constantValueNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.CodeName);
		this.contents[this.contentsOffset++] = (byte) (constantValueNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) constantValueNameIndex;
		// leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4)
		this.contentsOffset += 12;
	}
	
	private int generateConstantValueAttribute(Constant fieldConstant, FieldBinding fieldBinding, int fieldAttributeOffset) {
		int localContentsOffset = this.contentsOffset;
		int attributesNumber = 1;
		if (localContentsOffset + 8 >= this.contents.length) {
			resizeContents(8);
		}
		// Now we generate the constant attribute corresponding to the fieldBinding
		int constantValueNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.ConstantValueName);
		this.contents[localContentsOffset++] = (byte) (constantValueNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) constantValueNameIndex;
		// The attribute length = 2 in case of a constantValue attribute
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 2;
		// Need to add the constant_value_index
		switch (fieldConstant.typeID()) {
			case T_boolean :
				int booleanValueIndex =
					this.constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0);
				this.contents[localContentsOffset++] = (byte) (booleanValueIndex >> 8);
				this.contents[localContentsOffset++] = (byte) booleanValueIndex;
				break;
			case T_byte :
			case T_char :
			case T_int :
			case T_short :
				int integerValueIndex =
					this.constantPool.literalIndex(fieldConstant.intValue());
				this.contents[localContentsOffset++] = (byte) (integerValueIndex >> 8);
				this.contents[localContentsOffset++] = (byte) integerValueIndex;
				break;
			case T_float :
				int floatValueIndex =
					this.constantPool.literalIndex(fieldConstant.floatValue());
				this.contents[localContentsOffset++] = (byte) (floatValueIndex >> 8);
				this.contents[localContentsOffset++] = (byte) floatValueIndex;
				break;
			case T_double :
				int doubleValueIndex =
					this.constantPool.literalIndex(fieldConstant.doubleValue());
				this.contents[localContentsOffset++] = (byte) (doubleValueIndex >> 8);
				this.contents[localContentsOffset++] = (byte) doubleValueIndex;
				break;
			case T_long :
				int longValueIndex =
					this.constantPool.literalIndex(fieldConstant.longValue());
				this.contents[localContentsOffset++] = (byte) (longValueIndex >> 8);
				this.contents[localContentsOffset++] = (byte) longValueIndex;
				break;
			case T_JavaLangString :
				int stringValueIndex =
					this.constantPool.literalIndex(
						((StringConstant) fieldConstant).stringValue());
				if (stringValueIndex == -1) {
					if (!this.creatingProblemType) {
						// report an error and abort: will lead to a problem type classfile creation
						TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
						FieldDeclaration[] fieldDecls = typeDeclaration.fields;
						int max = fieldDecls == null ? 0 : fieldDecls.length;
						for (int i = 0; i < max; i++) {
							if (fieldDecls[i].binding == fieldBinding) {
								// problem should abort
								typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(
									fieldDecls[i]);
							}
						}
					} else {
						// already inside a problem type creation : no constant for this field
						this.contentsOffset = fieldAttributeOffset;
						attributesNumber = 0;
					}
				} else {
					this.contents[localContentsOffset++] = (byte) (stringValueIndex >> 8);
					this.contents[localContentsOffset++] = (byte) stringValueIndex;
				}
		}
		this.contentsOffset = localContentsOffset;
		return attributesNumber;
	}
	private int generateDeprecatedAttribute() {
		int localContentsOffset = this.contentsOffset;
		if (localContentsOffset + 6 >= this.contents.length) {
			resizeContents(6);
		}
		int deprecatedAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
		this.contents[localContentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) deprecatedAttributeNameIndex;
		// the length of a deprecated attribute is equals to 0
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private void generateElementValue(
			Expression defaultValue,
			TypeBinding memberValuePairReturnType,
			int attributeOffset) {
		Constant constant = defaultValue.constant;
		TypeBinding defaultValueBinding = defaultValue.resolvedType;
		if (defaultValueBinding == null) {
			this.contentsOffset = attributeOffset;
		} else {
			if (defaultValueBinding.isMemberType()) {
				this.recordInnerClasses(defaultValueBinding);
			}
			if (memberValuePairReturnType.isMemberType()) {
				this.recordInnerClasses(memberValuePairReturnType);
			}
			if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
				// automatic wrapping
				if (this.contentsOffset + 3 >= this.contents.length) {
					resizeContents(3);
				}
				this.contents[this.contentsOffset++] = (byte) '[';
				this.contents[this.contentsOffset++] = (byte) 0;
				this.contents[this.contentsOffset++] = (byte) 1;
			}
			if (constant != null && constant != Constant.NotAConstant) {
				generateElementValue(attributeOffset, defaultValue, constant, memberValuePairReturnType.leafComponentType());
			} else {
				generateElementValueForNonConstantExpression(defaultValue, attributeOffset, defaultValueBinding);
			}
		}
	}
	/**
	 * @param attributeOffset
	 */
	private void generateElementValue(int attributeOffset, Expression defaultValue, Constant constant, TypeBinding binding) {
		if (this.contentsOffset + 3 >= this.contents.length) {
			resizeContents(3);
		}
		switch (binding.id) {
			case T_boolean :
				this.contents[this.contentsOffset++] = (byte) 'Z';
				int booleanValueIndex =
					this.constantPool.literalIndex(constant.booleanValue() ? 1 : 0);
				this.contents[this.contentsOffset++] = (byte) (booleanValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) booleanValueIndex;
				break;
			case T_byte :
				this.contents[this.contentsOffset++] = (byte) 'B';
				int integerValueIndex =
					this.constantPool.literalIndex(constant.intValue());
				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
				break;
			case T_char :
				this.contents[this.contentsOffset++] = (byte) 'C';
				integerValueIndex =
					this.constantPool.literalIndex(constant.intValue());
				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
				break;
			case T_int :
				this.contents[this.contentsOffset++] = (byte) 'I';
				integerValueIndex =
					this.constantPool.literalIndex(constant.intValue());
				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
				break;
			case T_short :
				this.contents[this.contentsOffset++] = (byte) 'S';
				integerValueIndex =
					this.constantPool.literalIndex(constant.intValue());
				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
				break;
			case T_float :
				this.contents[this.contentsOffset++] = (byte) 'F';
				int floatValueIndex =
					this.constantPool.literalIndex(constant.floatValue());
				this.contents[this.contentsOffset++] = (byte) (floatValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) floatValueIndex;
				break;
			case T_double :
				this.contents[this.contentsOffset++] = (byte) 'D';
				int doubleValueIndex =
					this.constantPool.literalIndex(constant.doubleValue());
				this.contents[this.contentsOffset++] = (byte) (doubleValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) doubleValueIndex;
				break;
			case T_long :
				this.contents[this.contentsOffset++] = (byte) 'J';
				int longValueIndex =
					this.constantPool.literalIndex(constant.longValue());
				this.contents[this.contentsOffset++] = (byte) (longValueIndex >> 8);
				this.contents[this.contentsOffset++] = (byte) longValueIndex;
				break;
			case T_JavaLangString :
				this.contents[this.contentsOffset++] = (byte) 's';
				int stringValueIndex =
					this.constantPool.literalIndex(((StringConstant) constant).stringValue().toCharArray());
				if (stringValueIndex == -1) {
					if (!this.creatingProblemType) {
						// report an error and abort: will lead to a problem type classfile creation
						TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
						typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(defaultValue);
					} else {
						// already inside a problem type creation : no attribute
						this.contentsOffset = attributeOffset;
					}
				} else {
					this.contents[this.contentsOffset++] = (byte) (stringValueIndex >> 8);
					this.contents[this.contentsOffset++] = (byte) stringValueIndex;
				}
		}
	}
	
	private void generateElementValueForNonConstantExpression(Expression defaultValue, int attributeOffset, TypeBinding defaultValueBinding) {
		if (defaultValueBinding != null) {
			if (defaultValueBinding.isEnum()) {
				if (this.contentsOffset + 5 >= this.contents.length) {
					resizeContents(5);
				}
				this.contents[this.contentsOffset++] = (byte) 'e';
				FieldBinding fieldBinding = null;
				if (defaultValue instanceof QualifiedNameReference) {
					QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
					fieldBinding = (FieldBinding) nameReference.binding;
				} else if (defaultValue instanceof SingleNameReference) {
					SingleNameReference nameReference = (SingleNameReference) defaultValue;
					fieldBinding = (FieldBinding) nameReference.binding;
				} else {
					this.contentsOffset = attributeOffset;
				}
				if (fieldBinding != null) {
					final int enumConstantTypeNameIndex = this.constantPool.literalIndex(fieldBinding.type.signature());
					final int enumConstantNameIndex = this.constantPool.literalIndex(fieldBinding.name);
					this.contents[this.contentsOffset++] = (byte) (enumConstantTypeNameIndex >> 8);
					this.contents[this.contentsOffset++] = (byte) enumConstantTypeNameIndex;
					this.contents[this.contentsOffset++] = (byte) (enumConstantNameIndex >> 8);
					this.contents[this.contentsOffset++] = (byte) enumConstantNameIndex;
				}
			} else if (defaultValueBinding.isAnnotationType()) {
				if (this.contentsOffset + 1 >= this.contents.length) {
					resizeContents(1);
				}
				this.contents[this.contentsOffset++] = (byte) '@';
				generateAnnotation((Annotation) defaultValue, attributeOffset);
			} else if (defaultValueBinding.isArrayType()) {
				// array type
				if (this.contentsOffset + 3 >= this.contents.length) {
					resizeContents(3);
				}
				this.contents[this.contentsOffset++] = (byte) '[';
				if (defaultValue instanceof ArrayInitializer) {
					ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
					int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
					this.contents[this.contentsOffset++] = (byte) (arrayLength >> 8);
					this.contents[this.contentsOffset++] = (byte) arrayLength;
					for (int i = 0; i < arrayLength; i++) {
						generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType(), attributeOffset);
					}
				} else {
					this.contentsOffset = attributeOffset;
				}
			} else {
				// class type
				if (this.contentsOffset + 3 >= this.contents.length) {
					resizeContents(3);
				}
				this.contents[this.contentsOffset++] = (byte) 'c';
				if (defaultValue instanceof ClassLiteralAccess) {
					ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) defaultValue;
					final int classInfoIndex = this.constantPool.literalIndex(classLiteralAccess.targetType.signature());
					this.contents[this.contentsOffset++] = (byte) (classInfoIndex >> 8);
					this.contents[this.contentsOffset++] = (byte) classInfoIndex;
				} else {
					this.contentsOffset = attributeOffset;
				}
			}
		} else {
			this.contentsOffset = attributeOffset;
		}
	}

	private int generateEnclosingMethodAttribute() {
		int localContentsOffset = this.contentsOffset;
		// add enclosing method attribute (1.5 mode only)
		if (localContentsOffset + 10 >= this.contents.length) {
			resizeContents(10);
		}
		int enclosingMethodAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName);
		this.contents[localContentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) enclosingMethodAttributeNameIndex;
		// the length of a signature attribute is equals to 2
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 4;

		int enclosingTypeIndex = this.constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName());
		this.contents[localContentsOffset++] = (byte) (enclosingTypeIndex >> 8);
		this.contents[localContentsOffset++] = (byte) enclosingTypeIndex;
		byte methodIndexByte1 = 0;
		byte methodIndexByte2 = 0;
		if (this.referenceBinding instanceof LocalTypeBinding) {
			MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod;
			if (methodBinding != null) {
				int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this));
				methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
				methodIndexByte2 = (byte) enclosingMethodIndex;
			}
		}
		this.contents[localContentsOffset++] = methodIndexByte1;
		this.contents[localContentsOffset++] = methodIndexByte2;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private int generateExceptionsAttribute(ReferenceBinding[] thrownsExceptions) {
		int localContentsOffset = this.contentsOffset;
		int length = thrownsExceptions.length;
		int exSize = 8 + length * 2;
		if (exSize + this.contentsOffset >= this.contents.length) {
			resizeContents(exSize);
		}
		int exceptionNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
		this.contents[localContentsOffset++] = (byte) (exceptionNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) exceptionNameIndex;
		// The attribute length = length * 2 + 2 in case of a exception attribute
		int attributeLength = length * 2 + 2;
		this.contents[localContentsOffset++] = (byte) (attributeLength >> 24);
		this.contents[localContentsOffset++] = (byte) (attributeLength >> 16);
		this.contents[localContentsOffset++] = (byte) (attributeLength >> 8);
		this.contents[localContentsOffset++] = (byte) attributeLength;
		this.contents[localContentsOffset++] = (byte) (length >> 8);
		this.contents[localContentsOffset++] = (byte) length;
		for (int i = 0; i < length; i++) {
			int exceptionIndex = this.constantPool.literalIndexForType(thrownsExceptions[i]);
			this.contents[localContentsOffset++] = (byte) (exceptionIndex >> 8);
			this.contents[localContentsOffset++] = (byte) exceptionIndex;
		}
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private int generateHierarchyInconsistentAttribute() {
		int localContentsOffset = this.contentsOffset;
		// add an attribute for inconsistent hierarchy
		if (localContentsOffset + 6 >= this.contents.length) {
			resizeContents(6);
		}
		int inconsistentHierarchyNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy);
		this.contents[localContentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) inconsistentHierarchyNameIndex;
		// the length of an inconsistent hierarchy attribute is equals to 0
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private int generateInnerClassAttribute(int numberOfInnerClasses, ReferenceBinding[] innerClasses) {
		int localContentsOffset = this.contentsOffset;
		// Generate the inner class attribute
		int exSize = 8 * numberOfInnerClasses + 8;
		if (exSize + localContentsOffset >= this.contents.length) {
			resizeContents(exSize);
		}
		// Now we now the size of the attribute and the number of entries
		// attribute name
		int attributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.InnerClassName);
		this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) attributeNameIndex;
		int value = (numberOfInnerClasses << 3) + 2;
		this.contents[localContentsOffset++] = (byte) (value >> 24);
		this.contents[localContentsOffset++] = (byte) (value >> 16);
		this.contents[localContentsOffset++] = (byte) (value >> 8);
		this.contents[localContentsOffset++] = (byte) value;
		this.contents[localContentsOffset++] = (byte) (numberOfInnerClasses >> 8);
		this.contents[localContentsOffset++] = (byte) numberOfInnerClasses;
		for (int i = 0; i < numberOfInnerClasses; i++) {
			ReferenceBinding innerClass = innerClasses[i];
			int accessFlags = innerClass.getAccessFlags();
//{ObjectTeams: synthetic interfaces are illegal in class files (why???):
			if (  (accessFlags & (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
		              == (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
			{
				accessFlags ^= ClassFileConstants.AccSynthetic;
			}
//SH}
			int innerClassIndex = this.constantPool.literalIndexForType(innerClass.constantPoolName());
			// inner class index
			this.contents[localContentsOffset++] = (byte) (innerClassIndex >> 8);
			this.contents[localContentsOffset++] = (byte) innerClassIndex;
			// outer class index: anonymous and local have no outer class index
			if (innerClass.isMemberType()) {
				// member or member of local
				int outerClassIndex = this.constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName());
				this.contents[localContentsOffset++] = (byte) (outerClassIndex >> 8);
				this.contents[localContentsOffset++] = (byte) outerClassIndex;
			} else {
				// equals to 0 if the innerClass is not a member type
				this.contents[localContentsOffset++] = 0;
				this.contents[localContentsOffset++] = 0;
			}
			// name index
			if (!innerClass.isAnonymousType()) {
//{ObjectTeams: use real name not beautified version (was sourceName()).
/* orig:
				int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
  :giro */
				int nameIndex = this.constantPool.literalIndex(innerClass.internalName());
// SH}

				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
				this.contents[localContentsOffset++] = (byte) nameIndex;
			} else {
				// equals to 0 if the innerClass is an anonymous type
				this.contents[localContentsOffset++] = 0;
				this.contents[localContentsOffset++] = 0;
			}
			// access flag
			if (innerClass.isAnonymousType()) {
				accessFlags &= ~ClassFileConstants.AccFinal;
			} else if (innerClass.isMemberType() && innerClass.isInterface()) {
				accessFlags |= ClassFileConstants.AccStatic; // implicitely static
			}
			this.contents[localContentsOffset++] = (byte) (accessFlags >> 8);
			this.contents[localContentsOffset++] = (byte) accessFlags;
		}
		this.contentsOffset = localContentsOffset;
		return 1;
	}

	private int generateBootstrapMethods(List functionalExpressionList) {
		/* See JVM spec 4.7.21
		   The BootstrapMethods attribute has the following format:
		   BootstrapMethods_attribute {
		      u2 attribute_name_index;
		      u4 attribute_length;
		      u2 num_bootstrap_methods;
		      {   u2 bootstrap_method_ref;
		          u2 num_bootstrap_arguments;
		          u2 bootstrap_arguments[num_bootstrap_arguments];
		      } bootstrap_methods[num_bootstrap_methods];
		 }
		*/
		// Record inner classes for MethodHandles$Lookup
		ReferenceBinding methodHandlesLookup = this.referenceBinding.scope.getJavaLangInvokeMethodHandlesLookup();
		if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE.
		recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also
		ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory(); 
		
		// Depending on the complexity of the expression it may be necessary to use the altMetafactory() rather than the metafactory()
		int indexForMetaFactory = 0;
		int indexForAltMetaFactory = 0;

		int numberOfBootstraps = functionalExpressionList.size();
		int localContentsOffset = this.contentsOffset;
		// Generate the boot strap attribute - since we are only making lambdas and
		// functional expressions, we know the size ahead of time - this less general
		// than the full invokedynamic scope, but fine for Java 8
		
		int exSize = 10 * numberOfBootstraps + 8;
		if (exSize + localContentsOffset >= this.contents.length) {
			resizeContents(exSize);
		}
		
		int attributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.BootstrapMethodsName);
		this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) attributeNameIndex;
		// leave space for attribute_length and remember where to insert it
		int attributeLengthPosition = localContentsOffset;
		localContentsOffset += 4;
		this.contents[localContentsOffset++] = (byte) (numberOfBootstraps >> 8);
		this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
		for (int i = 0; i < numberOfBootstraps; i++) {
			FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i);
			
			TypeBinding[] markerInterfaces = null;
			if (functional instanceof LambdaExpression && 
				   (((markerInterfaces=((LambdaExpression)functional).getMarkerInterfaces()) != null) ||
				   	((LambdaExpression)functional).isSerializable)) {
				
				LambdaExpression lambdaEx = (LambdaExpression)functional;
				// may need even more space
				int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
				if (markerInterfaces != null) {
					// 2 for the marker interface list size then 2 per marker interface index
					extraSpace += (2 + 2 * markerInterfaces.length);
				}
				if (extraSpace + localContentsOffset >= this.contents.length) {
					resizeContents(extraSpace);
				} 
				
				if (indexForAltMetaFactory == 0) {
					indexForAltMetaFactory = 
						this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory, 
						ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
				}
				this.contents[localContentsOffset++] = (byte) (indexForAltMetaFactory >> 8);
				this.contents[localContentsOffset++] = (byte) indexForAltMetaFactory;
				
				// u2 num_bootstrap_arguments
				this.contents[localContentsOffset++] = 0;
				this.contents[localContentsOffset++] = (byte) (4+(markerInterfaces==null?0:1+markerInterfaces.length));
				
				int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
				this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
				this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
	
				int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
				this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
				this.contents[localContentsOffset++] = (byte) methodHandleIndex;
	
				char [] instantiatedSignature = functional.descriptor.signature();
				int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
				this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
				this.contents[localContentsOffset++] = (byte) methodTypeIndex;

				// Does this block have to deal with FLAG_BRIDGE? When is it needed?
				int bitflags = 0;
				if (lambdaEx.isSerializable) {
					bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
				}
				if (markerInterfaces!=null) {
					bitflags |= ClassFileConstants.FLAG_MARKERS;
				}
				int indexForBitflags = this.constantPool.literalIndex(bitflags);
				
				this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
				this.contents[localContentsOffset++] = (byte)(indexForBitflags);
				
				if (markerInterfaces != null) {
					int markerInterfaceCountIndex =  this.constantPool.literalIndex(markerInterfaces.length);
					this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
					this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
					for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
						int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
						this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
						this.contents[localContentsOffset++] = (byte)(classTypeIndex);
					}					
				}
			} else {
				if (indexForMetaFactory == 0) {
					indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory, 
							ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
				}
				this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8);
				this.contents[localContentsOffset++] = (byte) indexForMetaFactory;
				
				// u2 num_bootstrap_arguments
				this.contents[localContentsOffset++] = 0;
				this.contents[localContentsOffset++] = (byte) 3;
				
				int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
				this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
				this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
	
				int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
				this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
				this.contents[localContentsOffset++] = (byte) methodHandleIndex;
	
				char [] instantiatedSignature = functional.descriptor.signature();
				int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
				this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
				this.contents[localContentsOffset++] = (byte) methodTypeIndex;				
			}
		}

		int attributeLength = localContentsOffset - attributeLengthPosition - 4;
		this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 24);
		this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 16);
		this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 8);
		this.contents[attributeLengthPosition++] = (byte) attributeLength;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private int generateLineNumberAttribute() {
		int localContentsOffset = this.contentsOffset;
		int attributesNumber = 0;
		/* Create and add the line number attribute (used for debugging)
		 * Build the pairs of:
		 * 	(bytecodePC lineNumber)
		 * according to the table of start line indexes and the pcToSourceMap table
		 * contained into the codestream
		 */
		int[] pcToSourceMapTable;
		if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null)
			&& (this.codeStream.pcToSourceMapSize != 0)) {
			int lineNumberNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
			if (localContentsOffset + 8 >= this.contents.length) {
				resizeContents(8);
			}
			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
			int lineNumberTableOffset = localContentsOffset;
			localContentsOffset += 6;
			// leave space for attribute_length and line_number_table_length
			int numberOfEntries = 0;
			int length = this.codeStream.pcToSourceMapSize;
			for (int i = 0; i < length;) {
				// write the entry
				if (localContentsOffset + 4 >= this.contents.length) {
					resizeContents(4);
				}
				int pc = pcToSourceMapTable[i++];
				this.contents[localContentsOffset++] = (byte) (pc >> 8);
				this.contents[localContentsOffset++] = (byte) pc;
				int lineNumber = pcToSourceMapTable[i++];
				this.contents[localContentsOffset++] = (byte) (lineNumber >> 8);
				this.contents[localContentsOffset++] = (byte) lineNumber;
				numberOfEntries++;
			}
			// now we change the size of the line number attribute
			int lineNumberAttr_length = numberOfEntries * 4 + 2;
			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
			this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
			this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
			this.contents[lineNumberTableOffset++] = (byte) numberOfEntries;
			attributesNumber = 1;
		}
		this.contentsOffset = localContentsOffset;
		return attributesNumber;
	}
	// this is used for problem and synthetic methods
	private int generateLineNumberAttribute(int problemLine) {
		int localContentsOffset = this.contentsOffset;
		if (localContentsOffset + 12 >= this.contents.length) {
			resizeContents(12);
		}
		/* Create and add the line number attribute (used for debugging)
		 * Build the pairs of:
		 * (bytecodePC lineNumber)
		 * according to the table of start line indexes and the pcToSourceMap table
		 * contained into the codestream
		 */
		int lineNumberNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
		this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 6;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 1;
		// first entry at pc = 0
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
		this.contents[localContentsOffset++] = (byte) problemLine;
		// now we change the size of the line number attribute
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	
	private int generateLocalVariableTableAttribute(int code_length, boolean methodDeclarationIsStatic, boolean isSynthetic) {
		int attributesNumber = 0;
		int localContentsOffset = this.contentsOffset;
		int numberOfEntries = 0;
		int localVariableNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
		int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1);
		for (int i = 0; i < this.codeStream.allLocalsCounter; i++) {
			LocalVariableBinding localVariableBinding = this.codeStream.locals[i];
			maxOfEntries += 10 * localVariableBinding.initializationCount;
		}
		// reserve enough space
		if (localContentsOffset + maxOfEntries >= this.contents.length) {
			resizeContents(maxOfEntries);
		}
		this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
		int localVariableTableOffset = localContentsOffset;
		// leave space for attribute_length and local_variable_table_length
		localContentsOffset += 6;
		int nameIndex;
		int descriptorIndex;
		SourceTypeBinding declaringClassBinding = null;
		if (!methodDeclarationIsStatic && !isSynthetic) {
			numberOfEntries++;
			this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
			this.contents[localContentsOffset++] = 0;
			this.contents[localContentsOffset++] = (byte) (code_length >> 8);
			this.contents[localContentsOffset++] = (byte) code_length;
			nameIndex = this.constantPool.literalIndex(ConstantPool.This);
			this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
			this.contents[localContentsOffset++] = (byte) nameIndex;
			declaringClassBinding = (SourceTypeBinding) 
					(this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding.declaringClass : this.codeStream.lambdaExpression.binding.declaringClass);
			descriptorIndex =
				this.constantPool.literalIndex(
					declaringClassBinding.signature());
			this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
			this.contents[localContentsOffset++] = (byte) descriptorIndex;
			this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
			this.contents[localContentsOffset++] = 0;
		}
		// used to remember the local variable with a generic type
		int genericLocalVariablesCounter = 0;
		LocalVariableBinding[] genericLocalVariables = null;
		int numberOfGenericEntries = 0;

		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
			LocalVariableBinding localVariable = this.codeStream.locals[i];
			int initializationCount = localVariable.initializationCount;
			if (initializationCount == 0) continue;
			if (localVariable.declaration == null) continue;
			final TypeBinding localVariableTypeBinding = localVariable.type;
			boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
			if (isParameterizedType) {
				if (genericLocalVariables == null) {
					// we cannot have more than max locals
					genericLocalVariables = new LocalVariableBinding[max];
				}
				genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
			}
			for (int j = 0; j < initializationCount; j++) {
				int startPC = localVariable.initializationPCs[j << 1];
				int endPC = localVariable.initializationPCs[(j << 1) + 1];
				if (startPC != endPC) { // only entries for non zero length
					if (endPC == -1) {
						localVariable.declaringScope.problemReporter().abortDueToInternalError(
								Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
								(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
					}
					if (isParameterizedType) {
						numberOfGenericEntries++;
					}
					// now we can safely add the local entry
					numberOfEntries++;
					this.contents[localContentsOffset++] = (byte) (startPC >> 8);
					this.contents[localContentsOffset++] = (byte) startPC;
					int length = endPC - startPC;
					this.contents[localContentsOffset++] = (byte) (length >> 8);
					this.contents[localContentsOffset++] = (byte) length;
					nameIndex = this.constantPool.literalIndex(localVariable.name);
					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
					this.contents[localContentsOffset++] = (byte) nameIndex;
					descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
					this.contents[localContentsOffset++] = (byte) descriptorIndex;
					int resolvedPosition = localVariable.resolvedPosition;
					this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
					this.contents[localContentsOffset++] = (byte) resolvedPosition;
				}
			}
		}
		int value = numberOfEntries * 10 + 2;
		this.contents[localVariableTableOffset++] = (byte) (value >> 24);
		this.contents[localVariableTableOffset++] = (byte) (value >> 16);
		this.contents[localVariableTableOffset++] = (byte) (value >> 8);
		this.contents[localVariableTableOffset++] = (byte) value;
		this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
		this.contents[localVariableTableOffset] = (byte) numberOfEntries;
		attributesNumber++;

		final boolean currentInstanceIsGeneric =
			!methodDeclarationIsStatic
			&& declaringClassBinding != null
			&& declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
		if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) {
			// add the local variable type table attribute
			numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0);
			maxOfEntries = 8 + numberOfGenericEntries * 10;
			// reserve enough space
			if (localContentsOffset + maxOfEntries >= this.contents.length) {
				resizeContents(maxOfEntries);
			}
			int localVariableTypeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
			this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
			this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
			value = numberOfGenericEntries * 10 + 2;
			this.contents[localContentsOffset++] = (byte) (value >> 24);
			this.contents[localContentsOffset++] = (byte) (value >> 16);
			this.contents[localContentsOffset++] = (byte) (value >> 8);
			this.contents[localContentsOffset++] = (byte) value;
			this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
			this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
			if (currentInstanceIsGeneric) {
				this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
				this.contents[localContentsOffset++] = 0;
				this.contents[localContentsOffset++] = (byte) (code_length >> 8);
				this.contents[localContentsOffset++] = (byte) code_length;
				nameIndex = this.constantPool.literalIndex(ConstantPool.This);
				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
				this.contents[localContentsOffset++] = (byte) nameIndex;
				descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature());
				this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
				this.contents[localContentsOffset++] = (byte) descriptorIndex;
				this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
				this.contents[localContentsOffset++] = 0;
			}

			for (int i = 0; i < genericLocalVariablesCounter; i++) {
				LocalVariableBinding localVariable = genericLocalVariables[i];
				for (int j = 0; j < localVariable.initializationCount; j++) {
					int startPC = localVariable.initializationPCs[j << 1];
					int endPC = localVariable.initializationPCs[(j << 1) + 1];
					if (startPC != endPC) {
						// only entries for non zero length
						// now we can safely add the local entry
						this.contents[localContentsOffset++] = (byte) (startPC >> 8);
						this.contents[localContentsOffset++] = (byte) startPC;
						int length = endPC - startPC;
						this.contents[localContentsOffset++] = (byte) (length >> 8);
						this.contents[localContentsOffset++] = (byte) length;
						nameIndex = this.constantPool.literalIndex(localVariable.name);
						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
						this.contents[localContentsOffset++] = (byte) nameIndex;
						descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
						this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
						this.contents[localContentsOffset++] = (byte) descriptorIndex;
						int resolvedPosition = localVariable.resolvedPosition;
						this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
						this.contents[localContentsOffset++] = (byte) resolvedPosition;
					}
				}
			}
			attributesNumber++;
		}
		this.contentsOffset = localContentsOffset;
		return attributesNumber;
	}
	/**
	 * INTERNAL USE-ONLY
	 * That method generates the attributes of a code attribute.
	 * They could be:
	 * - an exception attribute for each try/catch found inside the method
	 * - a deprecated attribute
	 * - a synthetic attribute for synthetic access methods
	 *
	 * It returns the number of attributes created for the code attribute.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
	 * @return <CODE>int</CODE>
	 */
	public int generateMethodInfoAttributes(MethodBinding methodBinding) {
		// leave two bytes for the attribute_number
		this.contentsOffset += 2;
		if (this.contentsOffset + 2 >= this.contents.length) {
			resizeContents(2);
		}
		// now we can handle all the attribute for that method info:
		// it could be:
		// - a CodeAttribute
		// - a ExceptionAttribute
		// - a DeprecatedAttribute
		// - a SyntheticAttribute

		// Exception attribute
		ReferenceBinding[] thrownsExceptions;
		int attributesNumber = 0;
		if ((thrownsExceptions = methodBinding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
			// The method has a throw clause. So we need to add an exception attribute
			// check that there is enough space to write all the bytes for the exception attribute
			attributesNumber += generateExceptionsAttribute(thrownsExceptions);
		}
		if (methodBinding.isDeprecated()) {
			// Deprecated attribute
			attributesNumber += generateDeprecatedAttribute();
		}
		if (this.targetJDK < ClassFileConstants.JDK1_5) {
			if (methodBinding.isSynthetic()) {
				attributesNumber += generateSyntheticAttribute();
			}
			if (methodBinding.isVarargs()) {
				attributesNumber += generateVarargsAttribute();
			}
		}
		// add signature attribute
		char[] genericSignature = methodBinding.genericSignature();
		if (genericSignature != null) {
			attributesNumber += generateSignatureAttribute(genericSignature);
		}
		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
			AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
			if (methodDeclaration != null) {
				Annotation[] annotations = methodDeclaration.annotations;
				if (annotations != null) {
					attributesNumber += generateRuntimeAnnotations(annotations, methodBinding.isConstructor() ? TagBits.AnnotationForConstructor : TagBits.AnnotationForMethod);
				}
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
					Argument[] arguments = methodDeclaration.arguments;
					if (arguments != null) {
						attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
					}
				}
			} else {
				LambdaExpression lambda = methodBinding.sourceLambda();
				if (lambda != null) {
					if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
						Argument[] arguments = lambda.arguments();
						if (arguments != null) {
							int parameterCount = methodBinding.parameters.length;
							int argumentCount = arguments.length;
							if (parameterCount > argumentCount) { // synthetics prefixed 
								int redShift = parameterCount - argumentCount;
								System.arraycopy(arguments, 0, arguments = new Argument[parameterCount], redShift, argumentCount);
								for (int i = 0; i < redShift; i++)
									arguments[i] = new Argument(CharOperation.NO_CHAR, 0, null, 0);
							}
							attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
						}
					}	
				}
			}
		}
		if ((methodBinding.tagBits & TagBits.HasMissingType) != 0) {
			this.missingTypes = methodBinding.collectMissingTypes(this.missingTypes);
		}
		return attributesNumber;
	}
	public int generateMethodInfoAttributes(MethodBinding methodBinding, AnnotationMethodDeclaration declaration) {
		int attributesNumber = generateMethodInfoAttributes(methodBinding);
		int attributeOffset = this.contentsOffset;
		if ((declaration.modifiers & ClassFileConstants.AccAnnotationDefault) != 0) {
			// add an annotation default attribute
			attributesNumber += generateAnnotationDefaultAttribute(declaration, attributeOffset);
		}
		return attributesNumber;
	}
	/**
	 * INTERNAL USE-ONLY
	 * That method generates the header of a method info:
	 * The header consists in:
	 * - the access flags
	 * - the name index of the method name inside the constant pool
	 * - the descriptor index of the signature of the method inside the constant pool.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
	 */
	public void generateMethodInfoHeader(MethodBinding methodBinding) {
		generateMethodInfoHeader(methodBinding, methodBinding.modifiers);
	}

	/**
	 * INTERNAL USE-ONLY
	 * That method generates the header of a method info:
	 * The header consists in:
	 * - the access flags
	 * - the name index of the method name inside the constant pool
	 * - the descriptor index of the signature of the method inside the constant pool.
	 *
	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
	 * @param accessFlags the access flags
	 */
	public void generateMethodInfoHeader(MethodBinding methodBinding, int accessFlags) {
		// check that there is enough space to write all the bytes for the method info corresponding
		// to the @methodBinding
		this.methodCount++; // add one more method
		if (this.contentsOffset + 10 >= this.contents.length) {
			resizeContents(10);
		}
		if (this.targetJDK < ClassFileConstants.JDK1_5) {
			// pre 1.5, synthetic is an attribute, not a modifier
			// pre 1.5, varargs is an attribute, not a modifier (-target jsr14 mode)
			accessFlags &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccVarargs);
		}
		if ((methodBinding.tagBits & TagBits.ClearPrivateModifier) != 0) {
//{ObjectTeams: role methods may need to be rewritten to yield valid bytecode:
		  int rewrittenFlags = MethodModel.rewriteModifiersForBytecode(methodBinding);
		  if (rewrittenFlags != -1)
			accessFlags = rewrittenFlags;
		  else
// SH}
			accessFlags &= ~ClassFileConstants.AccPrivate;
		}
		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
		this.contents[this.contentsOffset++] = (byte) accessFlags;
		int nameIndex = this.constantPool.literalIndex(methodBinding.selector);
		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) nameIndex;
		int descriptorIndex = this.constantPool.literalIndex(methodBinding.signature(this));
		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
	}
	
	public void addSyntheticDeserializeLambda(SyntheticMethodBinding methodBinding, SyntheticMethodBinding[] syntheticMethodBindings ) {
		generateMethodInfoHeader(methodBinding);
		int methodAttributeOffset = this.contentsOffset;
		// this will add exception attribute, synthetic attribute, deprecated attribute,...
		int attributeNumber = generateMethodInfoAttributes(methodBinding);
		// Code attribute
		int codeAttributeOffset = this.contentsOffset;
		attributeNumber++; // add code attribute
		generateCodeAttributeHeader();
		this.codeStream.init(this);
		this.codeStream.generateSyntheticBodyForDeserializeLambda(methodBinding, syntheticMethodBindings);
		completeCodeAttributeForSyntheticMethod(
			methodBinding,
			codeAttributeOffset,
			((SourceTypeBinding) methodBinding.declaringClass)
				.scope
				.referenceCompilationUnit()
				.compilationResult
				.getLineSeparatorPositions());
		// update the number of attributes
		if ((this.produceAttributes & ClassFileConstants.ATTR_METHOD_PARAMETERS) != 0) {
			attributeNumber += generateMethodParameters(methodBinding);
		}
		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributeNumber;
	}	

	/**
	 * INTERNAL USE-ONLY
	 * That method generates the method info header of a clinit:
	 * The header consists in:
	 * - the access flags (always default access + static)
	 * - the name index of the method name (always <clinit>) inside the constant pool
	 * - the descriptor index of the signature (always ()V) of the method inside the constant pool.
	 */
	public void generateMethodInfoHeaderForClinit() {
		// check that there is enough space to write all the bytes for the method info corresponding
		// to the @methodBinding
		this.methodCount++; // add one more method
		if (this.contentsOffset + 10 >= this.contents.length) {
			resizeContents(10);
		}
		this.contents[this.contentsOffset++] = (byte) ((ClassFileConstants.AccDefault | ClassFileConstants.AccStatic) >> 8);
		this.contents[this.contentsOffset++] = (byte) (ClassFileConstants.AccDefault | ClassFileConstants.AccStatic);
		int nameIndex = this.constantPool.literalIndex(ConstantPool.Clinit);
		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) nameIndex;
		int descriptorIndex =
			this.constantPool.literalIndex(ConstantPool.ClinitSignature);
		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
		// We know that we won't get more than 1 attribute: the code attribute
		this.contents[this.contentsOffset++] = 0;
		this.contents[this.contentsOffset++] = 1;
	}

	/**
	 * INTERNAL USE-ONLY
	 * Generate the byte for problem method infos that correspond to missing abstract methods.
	 * http://dev.eclipse.org/bugs/show_bug.cgi?id=3179
	 *
	 * @param methodDeclarations Array of all missing abstract methods
	 */
	public void generateMissingAbstractMethods(MethodDeclaration[] methodDeclarations, CompilationResult compilationResult) {
		if (methodDeclarations != null) {
			TypeDeclaration currentDeclaration = this.referenceBinding.scope.referenceContext;
			int typeDeclarationSourceStart = currentDeclaration.sourceStart();
			int typeDeclarationSourceEnd = currentDeclaration.sourceEnd();
			for (int i = 0, max = methodDeclarations.length; i < max; i++) {
				MethodDeclaration methodDeclaration = methodDeclarations[i];
				MethodBinding methodBinding = methodDeclaration.binding;
				 String readableName = new String(methodBinding.readableName());
				 CategorizedProblem[] problems = compilationResult.problems;
				 int problemsCount = compilationResult.problemCount;
				for (int j = 0; j < problemsCount; j++) {
					CategorizedProblem problem = problems[j];
					if (problem != null
							&& problem.getID() == IProblem.AbstractMethodMustBeImplemented
							&& problem.getMessage().indexOf(readableName) != -1
							&& problem.getSourceStart() >= typeDeclarationSourceStart
							&& problem.getSourceEnd() <= typeDeclarationSourceEnd) {
						// we found a match
						addMissingAbstractProblemMethod(methodDeclaration, methodBinding, problem, compilationResult);
					}
				}
			}
		}
	}

	private void generateMissingTypesAttribute() {
		int initialSize = this.missingTypes.size();
		int[] missingTypesIndexes = new int[initialSize];
		int numberOfMissingTypes = 0;
		if (initialSize > 1) {
			Collections.sort(this.missingTypes, new Comparator() {
				public int compare(Object o1, Object o2) {
					TypeBinding typeBinding1 = (TypeBinding) o1;
					TypeBinding typeBinding2 = (TypeBinding) o2;
					return CharOperation.compareTo(typeBinding1.constantPoolName(), typeBinding2.constantPoolName());
				}
			});
		}
		int previousIndex = 0;
		next: for (int i = 0; i < initialSize; i++) {
			int missingTypeIndex = this.constantPool.literalIndexForType((TypeBinding) this.missingTypes.get(i));
			if (previousIndex == missingTypeIndex) {
				continue next;
			}
			previousIndex = missingTypeIndex;
			missingTypesIndexes[numberOfMissingTypes++] = missingTypeIndex;
		}
		// we don't need to resize as we interate from 0 to numberOfMissingTypes when recording the indexes in the .class file
		int attributeLength = numberOfMissingTypes * 2 + 2;
		if (this.contentsOffset + attributeLength + 6 >= this.contents.length) {
			resizeContents(attributeLength + 6);
		}
		int missingTypesNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MissingTypesName);
		this.contents[this.contentsOffset++] = (byte) (missingTypesNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) missingTypesNameIndex;

		// generate attribute length
		this.contents[this.contentsOffset++] = (byte) (attributeLength >> 24);
		this.contents[this.contentsOffset++] = (byte) (attributeLength >> 16);
		this.contents[this.contentsOffset++] = (byte) (attributeLength >> 8);
		this.contents[this.contentsOffset++] = (byte) attributeLength;

		// generate number of missing types
		this.contents[this.contentsOffset++] = (byte) (numberOfMissingTypes >> 8);
		this.contents[this.contentsOffset++] = (byte) numberOfMissingTypes;
		// generate entry for each missing type
		for (int i = 0; i < numberOfMissingTypes; i++) {
			int missingTypeIndex = missingTypesIndexes[i];
			this.contents[this.contentsOffset++] = (byte) (missingTypeIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) missingTypeIndex;
		}
	}

	/**
	 * @param annotations
	 * @param targetMask allowed targets
	 * @return the number of attributes created while dumping the annotations in the .class file
	 */
	private int generateRuntimeAnnotations(final Annotation[] annotations, final long targetMask) {
		int attributesNumber = 0;
		final int length = annotations.length;
		int visibleAnnotationsCounter = 0;
		int invisibleAnnotationsCounter = 0;
		for (int i = 0; i < length; i++) {
			Annotation annotation;
			if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
			long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
			if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
			if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
				invisibleAnnotationsCounter++;
			} else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
				visibleAnnotationsCounter++;
			}
		}

		int annotationAttributeOffset = this.contentsOffset;
		int constantPOffset = this.constantPool.currentOffset;
		int constantPoolIndex = this.constantPool.currentIndex;
		if (invisibleAnnotationsCounter != 0) {
			if (this.contentsOffset + 10 >= this.contents.length) {
				resizeContents(10);
			}
			int runtimeInvisibleAnnotationsAttributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			int annotationsLengthOffset = this.contentsOffset;
			this.contentsOffset += 2; // leave space for the annotations length

			int counter = 0;
			loop: for (int i = 0; i < length; i++) {
				if (invisibleAnnotationsCounter == 0) break loop;
				Annotation annotation;
				if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
				long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
				if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
				if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
					int currentAnnotationOffset = this.contentsOffset;
					generateAnnotation(annotation, currentAnnotationOffset);
					invisibleAnnotationsCounter--;
					if (this.contentsOffset != currentAnnotationOffset) {
						counter++;
					}
				}
			}
			if (counter != 0) {
				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
				this.contents[annotationsLengthOffset++] = (byte) counter;

				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				this.contentsOffset = annotationAttributeOffset;
				// reset the constant pool to its state before the clinit
				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleAnnotationsName, constantPoolIndex, constantPOffset);
			}
		}

		annotationAttributeOffset = this.contentsOffset;
		constantPOffset = this.constantPool.currentOffset;
		constantPoolIndex = this.constantPool.currentIndex;
		if (visibleAnnotationsCounter != 0) {
			if (this.contentsOffset + 10 >= this.contents.length) {
				resizeContents(10);
			}
			int runtimeVisibleAnnotationsAttributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			int annotationsLengthOffset = this.contentsOffset;
			this.contentsOffset += 2; // leave space for the annotations length

			int counter = 0;
			loop: for (int i = 0; i < length; i++) {
				if (visibleAnnotationsCounter == 0) break loop;
				Annotation annotation;
				if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
				long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
				if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
				if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
					visibleAnnotationsCounter--;
					int currentAnnotationOffset = this.contentsOffset;
					generateAnnotation(annotation, currentAnnotationOffset);
					if (this.contentsOffset != currentAnnotationOffset) {
						counter++;
					}
				}
			}
			if (counter != 0) {
				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
				this.contents[annotationsLengthOffset++] = (byte) counter;

				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				this.contentsOffset = annotationAttributeOffset;
				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleAnnotationsName, constantPoolIndex, constantPOffset);
			}
		}
		return attributesNumber;
	}
	
	private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
		final int argumentsLength = arguments.length;
		final int VISIBLE_INDEX = 0;
		final int INVISIBLE_INDEX = 1;
		int invisibleParametersAnnotationsCounter = 0;
		int visibleParametersAnnotationsCounter = 0;
		int[][] annotationsCounters = new int[argumentsLength][2];
		for (int i = 0; i < argumentsLength; i++) {
			Argument argument = arguments[i];
			Annotation[] annotations = argument.annotations;
			if (annotations != null) {
				for (int j = 0, max2 = annotations.length; j < max2; j++) {
					Annotation annotation;
					if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
					long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
					if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
					if (annotation.isRuntimeInvisible()) {
						annotationsCounters[i][INVISIBLE_INDEX]++;
						invisibleParametersAnnotationsCounter++;
					} else if (annotation.isRuntimeVisible()) {
						annotationsCounters[i][VISIBLE_INDEX]++;
						visibleParametersAnnotationsCounter++;
					}
				}
			}
		}
		int attributesNumber = 0;
		int annotationAttributeOffset = this.contentsOffset;
		if (invisibleParametersAnnotationsCounter != 0) {
			int globalCounter = 0;
			if (this.contentsOffset + 7 >= this.contents.length) {
				resizeContents(7);
			}
			int attributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			this.contents[this.contentsOffset++] = (byte) argumentsLength;
			for (int i = 0; i < argumentsLength; i++) {
				if (this.contentsOffset + 2 >= this.contents.length) {
					resizeContents(2);
				}
				if (invisibleParametersAnnotationsCounter == 0) {
					this.contents[this.contentsOffset++] = (byte) 0;
					this.contents[this.contentsOffset++] = (byte) 0;
				} else {
					final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
					int invisibleAnnotationsOffset = this.contentsOffset;
					// leave space for number of annotations
					this.contentsOffset += 2;
					int counter = 0;
					if (numberOfInvisibleAnnotations != 0) {
						Argument argument = arguments[i];
						Annotation[] annotations = argument.annotations;
						for (int j = 0, max = annotations.length; j < max; j++) {
							Annotation annotation;
							if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
							long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
							if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
							if (annotation.isRuntimeInvisible()) {
								int currentAnnotationOffset = this.contentsOffset;
								generateAnnotation(annotation, currentAnnotationOffset);
								if (this.contentsOffset != currentAnnotationOffset) {
									counter++;
									globalCounter++;
								}
								invisibleParametersAnnotationsCounter--;
							}
						}
					}
					this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8);
					this.contents[invisibleAnnotationsOffset] = (byte) counter;
				}
			}
			if (globalCounter != 0) {
				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				// if globalCounter is 0, this means that the code generation for all visible annotations failed
				this.contentsOffset = annotationAttributeOffset;
			}
		}
		if (visibleParametersAnnotationsCounter != 0) {
			int globalCounter = 0;
			if (this.contentsOffset + 7 >= this.contents.length) {
				resizeContents(7);
			}
			int attributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			this.contents[this.contentsOffset++] = (byte) argumentsLength;
			for (int i = 0; i < argumentsLength; i++) {
				if (this.contentsOffset + 2 >= this.contents.length) {
					resizeContents(2);
				}
				if (visibleParametersAnnotationsCounter == 0) {
					this.contents[this.contentsOffset++] = (byte) 0;
					this.contents[this.contentsOffset++] = (byte) 0;
				} else {
					final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
					int visibleAnnotationsOffset = this.contentsOffset;
					// leave space for number of annotations
					this.contentsOffset += 2;
					int counter = 0;
					if (numberOfVisibleAnnotations != 0) {
						Argument argument = arguments[i];
						Annotation[] annotations = argument.annotations;
						for (int j = 0, max = annotations.length; j < max; j++) {
							Annotation annotation;
							if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
							long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
							if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
							if (annotation.isRuntimeVisible()) {
								int currentAnnotationOffset = this.contentsOffset;
								generateAnnotation(annotation, currentAnnotationOffset);
								if (this.contentsOffset != currentAnnotationOffset) {
									counter++;
									globalCounter++;
								}
								visibleParametersAnnotationsCounter--;
							}
						}
					}
					this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8);
					this.contents[visibleAnnotationsOffset] = (byte) counter;
				}
			}
			if (globalCounter != 0) {
				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				// if globalCounter is 0, this means that the code generation for all visible annotations failed
				this.contentsOffset = annotationAttributeOffset;
			}
		}
		return attributesNumber;
	}
	
	/**
	 * @param annotationContexts the given annotation contexts
	 * @param visibleTypeAnnotationsNumber the given number of visible type annotations
	 * @param invisibleTypeAnnotationsNumber the given number of invisible type annotations
	 * @return the number of attributes created while dumping the annotations in the .class file
	 */
	private int generateRuntimeTypeAnnotations(
			final AnnotationContext[] annotationContexts, 
			int visibleTypeAnnotationsNumber, 
			int invisibleTypeAnnotationsNumber) {
		int attributesNumber = 0;
		final int length = annotationContexts.length;

		int visibleTypeAnnotationsCounter = visibleTypeAnnotationsNumber;
		int invisibleTypeAnnotationsCounter = invisibleTypeAnnotationsNumber;
		int annotationAttributeOffset = this.contentsOffset;
		int constantPOffset = this.constantPool.currentOffset;
		int constantPoolIndex = this.constantPool.currentIndex;
		if (invisibleTypeAnnotationsCounter != 0) {
			if (this.contentsOffset + 10 >= this.contents.length) {
				resizeContents(10);
			}
			int runtimeInvisibleAnnotationsAttributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			int annotationsLengthOffset = this.contentsOffset;
			this.contentsOffset += 2; // leave space for the annotations length

			int counter = 0;
			loop: for (int i = 0; i < length; i++) {
				if (invisibleTypeAnnotationsCounter == 0) break loop;
				AnnotationContext annotationContext = annotationContexts[i];
				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
					int currentAnnotationOffset = this.contentsOffset;
					generateTypeAnnotation(annotationContext, currentAnnotationOffset);
					invisibleTypeAnnotationsCounter--;
					if (this.contentsOffset != currentAnnotationOffset) {
						counter++;
					}
				}
			}
			if (counter != 0) {
				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
				this.contents[annotationsLengthOffset++] = (byte) counter;

				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				this.contentsOffset = annotationAttributeOffset;
				// reset the constant pool to its state before the clinit
				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName, constantPoolIndex, constantPOffset);
			}
		}

		annotationAttributeOffset = this.contentsOffset;
		constantPOffset = this.constantPool.currentOffset;
		constantPoolIndex = this.constantPool.currentIndex;
		if (visibleTypeAnnotationsCounter != 0) {
			if (this.contentsOffset + 10 >= this.contents.length) {
				resizeContents(10);
			}
			int runtimeVisibleAnnotationsAttributeNameIndex =
				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName);
			this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
			int attributeLengthOffset = this.contentsOffset;
			this.contentsOffset += 4; // leave space for the attribute length

			int annotationsLengthOffset = this.contentsOffset;
			this.contentsOffset += 2; // leave space for the annotations length

			int counter = 0;
			loop: for (int i = 0; i < length; i++) {
				if (visibleTypeAnnotationsCounter == 0) break loop;
				AnnotationContext annotationContext = annotationContexts[i];
				if ((annotationContext.visibility & AnnotationContext.VISIBLE) != 0) {
					visibleTypeAnnotationsCounter--;
					int currentAnnotationOffset = this.contentsOffset;
					generateTypeAnnotation(annotationContext, currentAnnotationOffset);
					if (this.contentsOffset != currentAnnotationOffset) {
						counter++;
					}
				}
			}
			if (counter != 0) {
				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
				this.contents[annotationsLengthOffset++] = (byte) counter;

				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
				this.contents[attributeLengthOffset++] = (byte) attributeLength;
				attributesNumber++;
			} else {
				this.contentsOffset = annotationAttributeOffset;
				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName, constantPoolIndex, constantPOffset);
			}
		}
		return attributesNumber;
	}

	/**
	 * @param binding the given method binding
	 * @return the number of attributes created while dumping he method's parameters in the .class file (0 or 1)
	 */
	private int generateMethodParameters(final MethodBinding binding) {
		
		int initialContentsOffset = this.contentsOffset;
		int length = 0; // count of actual parameters
		
		AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
		
		boolean isConstructor = binding.isConstructor();
		TypeBinding[] targetParameters = binding.parameters;
		ReferenceBinding declaringClass = binding.declaringClass;

		if (declaringClass.isEnum()) {
			if (isConstructor) { // insert String name,int ordinal
				length = writeArgumentName(ConstantPool.EnumName, ClassFileConstants.AccSynthetic, length);
				length = writeArgumentName(ConstantPool.EnumOrdinal, ClassFileConstants.AccSynthetic, length);
			} else if (CharOperation.equals(ConstantPool.ValueOf, binding.selector)) { // insert String name
				length = writeArgumentName(ConstantPool.Name, ClassFileConstants.AccMandated, length);
				targetParameters =  Binding.NO_PARAMETERS; // Override "unknown" synthetics below
			}
		}

		boolean needSynthetics = isConstructor && declaringClass.isNestedType();
		if (needSynthetics) {
			// Take into account the synthetic argument names
			// This tracks JLS8, paragraph 8.8.9
			boolean anonymousWithLocalSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isLocalType();
			boolean anonymousWithNestedSuper = declaringClass.isAnonymousType() && declaringClass.superclass().isNestedType();
			boolean isImplicitlyDeclared = ((! declaringClass.isPrivate()) || declaringClass.isAnonymousType()) && !anonymousWithLocalSuper;
			ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes();
			if (syntheticArgumentTypes != null) {
				for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
					// This behaviour tracks JLS 15.9.5.1
					// This covers that the parameter ending up in a nested class must be mandated "on the way in", even if it
					// isn't the first. The practical relevance of this is questionable, since the constructor call will be
					// generated by the same constructor.
					boolean couldForwardToMandated = anonymousWithNestedSuper ? declaringClass.superclass().enclosingType().equals(syntheticArgumentTypes[i]) : true;
					int modifier = couldForwardToMandated && isImplicitlyDeclared ? ClassFileConstants.AccMandated : ClassFileConstants.AccSynthetic;
					char[] name = CharOperation.concat(
							TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
							String.valueOf(i).toCharArray()); // cannot use depth, can be identical
					length = writeArgumentName(name, modifier | ClassFileConstants.AccFinal, length);
				}
			}
			if (binding instanceof SyntheticMethodBinding) {
				targetParameters = ((SyntheticMethodBinding)binding).targetMethod.parameters;
				methodDeclaration = ((SyntheticMethodBinding)binding).targetMethod.sourceMethod();
			}
		}
		if (targetParameters != Binding.NO_PARAMETERS) {
			for (int i = 0, max = targetParameters.length; i < max; i++) {
				if (methodDeclaration != null && methodDeclaration.arguments != null && methodDeclaration.arguments.length > i && methodDeclaration.arguments[i] != null) {
					Argument argument = methodDeclaration.arguments[i];
					length = writeArgumentName(argument.name, argument.binding.modifiers, length);
				} else {
					length = writeArgumentName(null, ClassFileConstants.AccSynthetic, length);
				}
			}
		}
		if (needSynthetics) {
			SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables();
			int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length;
			for (int i = 0; i < count; i++) {
				length = writeArgumentName(syntheticOuterArguments[i].name, syntheticOuterArguments[i].modifiers  | ClassFileConstants.AccSynthetic, length);
			}
			// move the extra padding arguments of the synthetic constructor invocation to the end
			for (int i = targetParameters.length, extraLength = binding.parameters.length; i < extraLength; i++) {
				TypeBinding parameter = binding.parameters[i];
				length = writeArgumentName(parameter.constantPoolName(), ClassFileConstants.AccSynthetic, length);
			}
		}

		if (length > 0) {
			// so we actually output the parameter
	 		int attributeLength = 1 + 4 * length; // u1 for count, u2+u2 per parameter
			if (this.contentsOffset + 6 + attributeLength >= this.contents.length) {
				resizeContents(6 + attributeLength);
			}
			int methodParametersNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MethodParametersName);
			this.contents[initialContentsOffset++] = (byte) (methodParametersNameIndex >> 8);
			this.contents[initialContentsOffset++] = (byte) methodParametersNameIndex;
			this.contents[initialContentsOffset++] = (byte) (attributeLength >> 24);
			this.contents[initialContentsOffset++] = (byte) (attributeLength >> 16);
			this.contents[initialContentsOffset++] = (byte) (attributeLength >> 8);
			this.contents[initialContentsOffset++] = (byte) attributeLength;
			this.contents[initialContentsOffset++] = (byte) length;
			return 1;
		}
		else {
			return 0;
		}
	}
	private int writeArgumentName(char[] name, int modifiers, int oldLength) {
		int ensureRoomForBytes = 4;
		if (oldLength == 0) {
			// Make room for 
			ensureRoomForBytes += 7;
			this.contentsOffset += 7; // Make room for attribute header + count byte
		}
		if (this.contentsOffset + ensureRoomForBytes > this.contents.length) {
				resizeContents(ensureRoomForBytes);
		}
		int parameterNameIndex = name == null ? 0 : this.constantPool.literalIndex(name);
		this.contents[this.contentsOffset++] = (byte) (parameterNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) parameterNameIndex;
		int flags = modifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic | ClassFileConstants.AccMandated);
		this.contents[this.contentsOffset++] = (byte) (flags >> 8);
		this.contents[this.contentsOffset++] = (byte) flags;
		return oldLength + 1;
	}

	private int generateSignatureAttribute(char[] genericSignature) {
		int localContentsOffset = this.contentsOffset;
		if (localContentsOffset + 8 >= this.contents.length) {
			resizeContents(8);
		}
		int signatureAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
		this.contents[localContentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) signatureAttributeNameIndex;
		// the length of a signature attribute is equals to 2
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 2;
		int signatureIndex =
			this.constantPool.literalIndex(genericSignature);
		this.contents[localContentsOffset++] = (byte) (signatureIndex >> 8);
		this.contents[localContentsOffset++] = (byte) signatureIndex;
		this.contentsOffset = localContentsOffset;
		return 1;
	}

	private int generateSourceAttribute(String fullFileName) {
		int localContentsOffset = this.contentsOffset;
		// check that there is enough space to write all the bytes for the field info corresponding
		// to the @fieldBinding
		if (localContentsOffset + 8 >= this.contents.length) {
			resizeContents(8);
		}
		int sourceAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.SourceName);
		this.contents[localContentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) sourceAttributeNameIndex;
		// The length of a source file attribute is 2. This is a fixed-length
		// attribute
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 2;
		// write the source file name
		int fileNameIndex = this.constantPool.literalIndex(fullFileName.toCharArray());
		this.contents[localContentsOffset++] = (byte) (fileNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) fileNameIndex;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	private int generateStackMapAttribute(
			MethodBinding methodBinding,
			int code_length,
			int codeAttributeOffset,
			int max_locals,
			boolean isClinit) {
		int attributesNumber = 0;
		int localContentsOffset = this.contentsOffset;
		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
		stackMapFrameCodeStream.removeFramePosition(code_length);
		if (stackMapFrameCodeStream.hasFramePositions()) {
			Map frames = new HashMap();
			List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
			int numberOfFrames = realFrames.size();
			if (numberOfFrames > 1) {
				int stackMapTableAttributeOffset = localContentsOffset;
				// add the stack map table attribute
				if (localContentsOffset + 8 >= this.contents.length) {
					resizeContents(8);
				}
				int stackMapAttributeNameIndex =
					this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
				this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
				this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;

				int stackMapAttributeLengthOffset = localContentsOffset;
				// generate the attribute
				localContentsOffset += 4;
				if (localContentsOffset + 4 >= this.contents.length) {
					resizeContents(4);
				}
				int numberOfFramesOffset = localContentsOffset;
				localContentsOffset += 2;
				if (localContentsOffset + 2 >= this.contents.length) {
					resizeContents(2);
				}
				StackMapFrame currentFrame = (StackMapFrame) realFrames.get(0);
				for (int j = 1; j < numberOfFrames; j++) {
					// select next frame
					currentFrame = (StackMapFrame) realFrames.get(j);
					// generate current frame
					// need to find differences between the current frame and the previous frame
					int frameOffset = currentFrame.pc;
					// FULL_FRAME
					if (localContentsOffset + 5 >= this.contents.length) {
						resizeContents(5);
					}
					this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
					this.contents[localContentsOffset++] = (byte) frameOffset;
					int numberOfLocalOffset = localContentsOffset;
					localContentsOffset += 2; // leave two spots for number of locals
					int numberOfLocalEntries = 0;
					int numberOfLocals = currentFrame.getNumberOfLocals();
					int numberOfEntries = 0;
					int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
					for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
						if (localContentsOffset + 3 >= this.contents.length) {
							resizeContents(3);
						}
						VerificationTypeInfo info = currentFrame.locals[i];
						if (info == null) {
							this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
						} else {
							switch(info.id()) {
								case T_boolean :
								case T_byte :
								case T_char :
								case T_int :
								case T_short :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
									break;
								case T_float :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
									break;
								case T_long :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
									i++;
									break;
								case T_double :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
									i++;
									break;
								case T_null :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
									break;
								default:
									this.contents[localContentsOffset++] = (byte) info.tag;
								switch (info.tag) {
									case VerificationTypeInfo.ITEM_UNINITIALIZED :
										int offset = info.offset;
										this.contents[localContentsOffset++] = (byte) (offset >> 8);
										this.contents[localContentsOffset++] = (byte) offset;
										break;
									case VerificationTypeInfo.ITEM_OBJECT :
										int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
										this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
										this.contents[localContentsOffset++] = (byte) indexForType;
								}
							}
							numberOfLocalEntries++;
						}
						numberOfEntries++;
					}
					if (localContentsOffset + 4 >= this.contents.length) {
						resizeContents(4);
					}
					this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
					this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
					int numberOfStackItems = currentFrame.numberOfStackItems;
					this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
					this.contents[localContentsOffset++] = (byte) numberOfStackItems;
					for (int i = 0; i < numberOfStackItems; i++) {
						if (localContentsOffset + 3 >= this.contents.length) {
							resizeContents(3);
						}
						VerificationTypeInfo info = currentFrame.stackItems[i];
						if (info == null) {
							this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
						} else {
							switch(info.id()) {
								case T_boolean :
								case T_byte :
								case T_char :
								case T_int :
								case T_short :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
									break;
								case T_float :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
									break;
								case T_long :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
									break;
								case T_double :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
									break;
								case T_null :
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
									break;
								default:
									this.contents[localContentsOffset++] = (byte) info.tag;
								switch (info.tag) {
									case VerificationTypeInfo.ITEM_UNINITIALIZED :
										int offset = info.offset;
										this.contents[localContentsOffset++] = (byte) (offset >> 8);
										this.contents[localContentsOffset++] = (byte) offset;
										break;
									case VerificationTypeInfo.ITEM_OBJECT :
										int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
										this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
										this.contents[localContentsOffset++] = (byte) indexForType;
								}
							}
						}
					}
				}

				numberOfFrames--;
				if (numberOfFrames != 0) {
					this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
					this.contents[numberOfFramesOffset] = (byte) numberOfFrames;

					int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
					this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
					attributesNumber++;
				} else {
					localContentsOffset = stackMapTableAttributeOffset;
				}
			}
		}
		this.contentsOffset = localContentsOffset;
		return attributesNumber;
	}

	private int generateStackMapTableAttribute(
			MethodBinding methodBinding,
			int code_length,
			int codeAttributeOffset,
			int max_locals,
			boolean isClinit) {
		int attributesNumber = 0;
		int localContentsOffset = this.contentsOffset;
		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
		stackMapFrameCodeStream.removeFramePosition(code_length);
		if (stackMapFrameCodeStream.hasFramePositions()) {
			Map frames = new HashMap();
			List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
			int numberOfFrames = realFrames.size();
			if (numberOfFrames > 1) {
				int stackMapTableAttributeOffset = localContentsOffset;
				// add the stack map table attribute
				if (localContentsOffset + 8 >= this.contents.length) {
					resizeContents(8);
				}
				int stackMapTableAttributeNameIndex =
					this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
				this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
				this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;

				int stackMapTableAttributeLengthOffset = localContentsOffset;
				// generate the attribute
				localContentsOffset += 4;
				if (localContentsOffset + 4 >= this.contents.length) {
					resizeContents(4);
				}
				int numberOfFramesOffset = localContentsOffset;
				localContentsOffset += 2;
				if (localContentsOffset + 2 >= this.contents.length) {
					resizeContents(2);
				}
				StackMapFrame currentFrame = (StackMapFrame) realFrames.get(0);
				StackMapFrame prevFrame = null;
				for (int j = 1; j < numberOfFrames; j++) {
					// select next frame
					prevFrame = currentFrame;
					currentFrame = (StackMapFrame) realFrames.get(j);
					// generate current frame
					// need to find differences between the current frame and the previous frame
					int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
					switch (currentFrame.getFrameType(prevFrame)) {
						case StackMapFrame.APPEND_FRAME :
							if (localContentsOffset + 3 >= this.contents.length) {
								resizeContents(3);
							}
							int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
							this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
							int numberOfLocals = currentFrame.getNumberOfLocals();
							for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
								if (localContentsOffset + 6 >= this.contents.length) {
									resizeContents(6);
								}
								VerificationTypeInfo info = currentFrame.locals[i];
								if (info == null) {
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
								} else {
									switch(info.id()) {
										case T_boolean :
										case T_byte :
										case T_char :
										case T_int :
										case T_short :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
											break;
										case T_float :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
											break;
										case T_long :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
											i++;
											break;
										case T_double :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
											i++;
											break;
										case T_null :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
											break;
										default:
											this.contents[localContentsOffset++] = (byte) info.tag;
											switch (info.tag) {
												case VerificationTypeInfo.ITEM_UNINITIALIZED :
													int offset = info.offset;
													this.contents[localContentsOffset++] = (byte) (offset >> 8);
													this.contents[localContentsOffset++] = (byte) offset;
													break;
												case VerificationTypeInfo.ITEM_OBJECT :
													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
													this.contents[localContentsOffset++] = (byte) indexForType;
											}
									}
									numberOfDifferentLocals--;
								}
							}
							break;
						case StackMapFrame.SAME_FRAME :
							if (localContentsOffset + 1 >= this.contents.length) {
								resizeContents(1);
							}
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							break;
						case StackMapFrame.SAME_FRAME_EXTENDED :
							if (localContentsOffset + 3 >= this.contents.length) {
								resizeContents(3);
							}
							this.contents[localContentsOffset++] = (byte) 251;
							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							break;
						case StackMapFrame.CHOP_FRAME :
							if (localContentsOffset + 3 >= this.contents.length) {
								resizeContents(3);
							}
							numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
							this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							break;
						case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
							if (localContentsOffset + 4 >= this.contents.length) {
								resizeContents(4);
							}
							this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
							if (currentFrame.stackItems[0] == null) {
								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
							} else {
								switch(currentFrame.stackItems[0].id()) {
									case T_boolean :
									case T_byte :
									case T_char :
									case T_int :
									case T_short :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
										break;
									case T_float :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
										break;
									case T_long :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
										break;
									case T_double :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
										break;
									case T_null :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
										break;
									default:
										VerificationTypeInfo info = currentFrame.stackItems[0];
										byte tag = (byte) info.tag;
										this.contents[localContentsOffset++] = tag;
										switch (tag) {
											case VerificationTypeInfo.ITEM_UNINITIALIZED :
												int offset = info.offset;
												this.contents[localContentsOffset++] = (byte) (offset >> 8);
												this.contents[localContentsOffset++] = (byte) offset;
												break;
											case VerificationTypeInfo.ITEM_OBJECT :
												int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
												this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
												this.contents[localContentsOffset++] = (byte) indexForType;
										}
								}
							}
							break;
						case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
							if (localContentsOffset + 6 >= this.contents.length) {
								resizeContents(6);
							}
							this.contents[localContentsOffset++] = (byte) 247;
							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							if (currentFrame.stackItems[0] == null) {
								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
							} else {
								switch(currentFrame.stackItems[0].id()) {
									case T_boolean :
									case T_byte :
									case T_char :
									case T_int :
									case T_short :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
										break;
									case T_float :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
										break;
									case T_long :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
										break;
									case T_double :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
										break;
									case T_null :
										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
										break;
									default:
										VerificationTypeInfo info = currentFrame.stackItems[0];
										byte tag = (byte) info.tag;
										this.contents[localContentsOffset++] = tag;
										switch (tag) {
											case VerificationTypeInfo.ITEM_UNINITIALIZED :
												int offset = info.offset;
												this.contents[localContentsOffset++] = (byte) (offset >> 8);
												this.contents[localContentsOffset++] = (byte) offset;
												break;
											case VerificationTypeInfo.ITEM_OBJECT :
												int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
												this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
												this.contents[localContentsOffset++] = (byte) indexForType;
										}
								}
							}
							break;
						default :
							// FULL_FRAME
							if (localContentsOffset + 5 >= this.contents.length) {
								resizeContents(5);
							}
							this.contents[localContentsOffset++] = (byte) 255;
							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
							this.contents[localContentsOffset++] = (byte) offsetDelta;
							int numberOfLocalOffset = localContentsOffset;
							localContentsOffset += 2; // leave two spots for number of locals
							int numberOfLocalEntries = 0;
							numberOfLocals = currentFrame.getNumberOfLocals();
							int numberOfEntries = 0;
							int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
							for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
								if (localContentsOffset + 3 >= this.contents.length) {
									resizeContents(3);
								}
								VerificationTypeInfo info = currentFrame.locals[i];
								if (info == null) {
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
								} else {
									switch(info.id()) {
										case T_boolean :
										case T_byte :
										case T_char :
										case T_int :
										case T_short :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
											break;
										case T_float :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
											break;
										case T_long :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
											i++;
											break;
										case T_double :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
											i++;
											break;
										case T_null :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
											break;
										default:
											this.contents[localContentsOffset++] = (byte) info.tag;
											switch (info.tag) {
												case VerificationTypeInfo.ITEM_UNINITIALIZED :
													int offset = info.offset;
													this.contents[localContentsOffset++] = (byte) (offset >> 8);
													this.contents[localContentsOffset++] = (byte) offset;
													break;
												case VerificationTypeInfo.ITEM_OBJECT :
													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
													this.contents[localContentsOffset++] = (byte) indexForType;
											}
									}
									numberOfLocalEntries++;
								}
								numberOfEntries++;
							}
							if (localContentsOffset + 4 >= this.contents.length) {
								resizeContents(4);
							}
							this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
							this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
							int numberOfStackItems = currentFrame.numberOfStackItems;
							this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
							this.contents[localContentsOffset++] = (byte) numberOfStackItems;
							for (int i = 0; i < numberOfStackItems; i++) {
								if (localContentsOffset + 3 >= this.contents.length) {
									resizeContents(3);
								}
								VerificationTypeInfo info = currentFrame.stackItems[i];
								if (info == null) {
									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
								} else {
									switch(info.id()) {
										case T_boolean :
										case T_byte :
										case T_char :
										case T_int :
										case T_short :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
											break;
										case T_float :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
											break;
										case T_long :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
											break;
										case T_double :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
											break;
										case T_null :
											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
											break;
										default:
											this.contents[localContentsOffset++] = (byte) info.tag;
											switch (info.tag) {
												case VerificationTypeInfo.ITEM_UNINITIALIZED :
													int offset = info.offset;
													this.contents[localContentsOffset++] = (byte) (offset >> 8);
													this.contents[localContentsOffset++] = (byte) offset;
													break;
												case VerificationTypeInfo.ITEM_OBJECT :
													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
													this.contents[localContentsOffset++] = (byte) indexForType;
											}
									}
								}
							}
					}
				}

				numberOfFrames--;
				if (numberOfFrames != 0) {
					this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
					this.contents[numberOfFramesOffset] = (byte) numberOfFrames;

					int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
					this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
					attributesNumber++;
				} else {
					localContentsOffset = stackMapTableAttributeOffset;
				}
			}
		}
		this.contentsOffset = localContentsOffset;
		return attributesNumber;
	}

	private int generateSyntheticAttribute() {
		int localContentsOffset = this.contentsOffset;
		if (localContentsOffset + 6 >= this.contents.length) {
			resizeContents(6);
		}
		int syntheticAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
		this.contents[localContentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) syntheticAttributeNameIndex;
		// the length of a synthetic attribute is equals to 0
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contentsOffset = localContentsOffset;
		return 1;
	}
	
	private void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
		Annotation annotation = annotationContext.annotation.getPersistibleAnnotation();
		if (annotation == null || annotation.resolvedType == null)
			return;
		
		int targetType = annotationContext.targetType;

		int[] locations = Annotation.getLocations(
			annotationContext.typeReference,
			annotationContext.annotation);

		if (this.contentsOffset + 5 >= this.contents.length) {
			resizeContents(5);
		}
		this.contents[this.contentsOffset++] = (byte) targetType;
		dumpTargetTypeContents(targetType, annotationContext);
		dumpLocations(locations);
		generateAnnotation(annotation, currentOffset);
	}

	private int generateTypeAnnotationAttributeForTypeDeclaration() {
		TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
		if ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) == 0) {
			return 0;
		}
		int attributesNumber = 0;
		int visibleTypeAnnotationsCounter = 0;
		int invisibleTypeAnnotationsCounter = 0;
		TypeReference superclass = typeDeclaration.superclass;
		List allTypeAnnotationContexts = new ArrayList();
		if (superclass != null && (superclass.bits & ASTNode.HasTypeAnnotations) != 0) {
			superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, -1, allTypeAnnotationContexts);
		}
		TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
		if (superInterfaces != null) {
			for (int i = 0; i < superInterfaces.length; i++) {
				TypeReference superInterface = superInterfaces[i];
				if ((superInterface.bits & ASTNode.HasTypeAnnotations) == 0) {
					continue;
				}
				superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts);
			}
		}
		TypeParameter[] typeParameters = typeDeclaration.typeParameters;
		if (typeParameters != null) {
			for (int i = 0, max = typeParameters.length; i < max; i++) {
				TypeParameter typeParameter = typeParameters[i];
				if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
					typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER, i, allTypeAnnotationContexts);
				}
			}
		}
		int size = allTypeAnnotationContexts.size();
		if (size != 0) {
			AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
			allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
			for (int j = 0, max = allTypeAnnotationContextsArray.length; j < max; j++) {
				AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
					invisibleTypeAnnotationsCounter++;
					allTypeAnnotationContexts.add(annotationContext);
				} else {
					visibleTypeAnnotationsCounter++;
					allTypeAnnotationContexts.add(annotationContext);
				}
			}
			attributesNumber += generateRuntimeTypeAnnotations(
					allTypeAnnotationContextsArray,
					visibleTypeAnnotationsCounter,
					invisibleTypeAnnotationsCounter);
		}
		return attributesNumber;
	}
	
	
	

	private int generateVarargsAttribute() {
		int localContentsOffset = this.contentsOffset;
		/*
		 * handle of the target jsr14 for varargs in the source
		 * Varargs attribute
		 * Check that there is enough space to write the attribute
		 */
		if (localContentsOffset + 6 >= this.contents.length) {
			resizeContents(6);
		}
		int varargsAttributeNameIndex =
			this.constantPool.literalIndex(AttributeNamesConstants.VarargsName);
		this.contents[localContentsOffset++] = (byte) (varargsAttributeNameIndex >> 8);
		this.contents[localContentsOffset++] = (byte) varargsAttributeNameIndex;
		// the length of a varargs attribute is equals to 0
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;
		this.contents[localContentsOffset++] = 0;

		this.contentsOffset = localContentsOffset;
		return 1;
	}

	/**
	 * EXTERNAL API
	 * Answer the actual bytes of the class file
	 *
	 * This method encodes the receiver structure into a byte array which is the content of the classfile.
	 * Returns the byte array that represents the encoded structure of the receiver.
	 *
	 * @return byte[]
	 */
	public byte[] getBytes() {
		if (this.bytes == null) {
			this.bytes = new byte[this.headerOffset + this.contentsOffset];
			System.arraycopy(this.header, 0, this.bytes, 0, this.headerOffset);
			System.arraycopy(this.contents, 0, this.bytes, this.headerOffset, this.contentsOffset);
		}
		return this.bytes;
	}
	/**
	 * EXTERNAL API
	 * Answer the compound name of the class file.
	 * @return char[][]
	 * e.g. {{java}, {util}, {Hashtable}}.
	 */
	public char[][] getCompoundName() {
		return CharOperation.splitOn('/', fileName());
	}

	private int getParametersCount(char[] methodSignature) {
		int i = CharOperation.indexOf('(', methodSignature);
		i++;
		char currentCharacter = methodSignature[i];
		if (currentCharacter == ')') {
			return 0;
		}
		int result = 0;
		while (true) {
			currentCharacter = methodSignature[i];
			if (currentCharacter == ')') {
				return result;
			}
			switch (currentCharacter) {
				case '[':
					// array type
					int scanType = scanType(methodSignature, i + 1);
					result++;
					i = scanType + 1;
					break;
				case 'L':
					scanType = CharOperation.indexOf(';', methodSignature,
							i + 1);
					result++;
					i = scanType + 1;
					break;
				case 'Z':
				case 'B':
				case 'C':
				case 'D':
				case 'F':
				case 'I':
				case 'J':
				case 'S':
					result++;
					i++;
					break;
				default:
					throw new IllegalArgumentException("Invalid starting type character : " + currentCharacter); //$NON-NLS-1$
			}
		}
	}

	private char[] getReturnType(char[] methodSignature) {
		// skip type parameters
		int paren = CharOperation.lastIndexOf(')', methodSignature);
		// there could be thrown exceptions behind, thus scan one type exactly
		return CharOperation.subarray(methodSignature, paren + 1,
				methodSignature.length);
	}

	private final int i4At(byte[] reference, int relativeOffset,
			int structOffset) {
		int position = relativeOffset + structOffset;
		return ((reference[position++] & 0xFF) << 24)
				+ ((reference[position++] & 0xFF) << 16)
				+ ((reference[position++] & 0xFF) << 8)
				+ (reference[position] & 0xFF);
	}

	protected void initByteArrays() {
		int members = this.referenceBinding.methods().length + this.referenceBinding.fields().length;
		this.header = new byte[INITIAL_HEADER_SIZE];
		this.contents = new byte[members < 15 ? INITIAL_CONTENTS_SIZE : INITIAL_HEADER_SIZE];
	}

	public void initialize(SourceTypeBinding aType, ClassFile parentClassFile, boolean createProblemType) {
		// generate the magic numbers inside the header
		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);

		long targetVersion = this.targetJDK;
		this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high
		this.header[this.headerOffset++] = (byte) (targetVersion>> 0); // minor low
		this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high
		this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low

		this.constantPoolOffset = this.headerOffset;
		this.headerOffset += 2;
		this.constantPool.initialize(this);

		// Modifier manipulations for classfile
		int accessFlags = aType.getAccessFlags();
		if (aType.isPrivate()) { // rewrite private to non-public
			accessFlags &= ~ClassFileConstants.AccPublic;
		}
		if (aType.isProtected()) { // rewrite protected into public
			accessFlags |= ClassFileConstants.AccPublic;
		}
		// clear all bits that are illegal for a class or an interface
		accessFlags
			&= ~(
				ClassFileConstants.AccStrictfp
					| ClassFileConstants.AccProtected
					| ClassFileConstants.AccPrivate
					| ClassFileConstants.AccStatic
					| ClassFileConstants.AccSynchronized
					| ClassFileConstants.AccNative);

//{ObjectTeams: synthetic interfaces are illegal in class files (why???):
		if (  (accessFlags & (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
			              == (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
		{
			accessFlags ^= ClassFileConstants.AccSynthetic;
		}
// SH}

		// set the AccSuper flag (has to be done after clearing AccSynchronized - since same value)
		if (!aType.isInterface()) { // class or enum
			accessFlags |= ClassFileConstants.AccSuper;
		}
		if (aType.isAnonymousType()) {
			accessFlags &= ~ClassFileConstants.AccFinal;
		}
		int finalAbstract = ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract;
		if ((accessFlags & finalAbstract) == finalAbstract) {
			accessFlags &= ~finalAbstract;
		}
		this.enclosingClassFile = parentClassFile;
		// innerclasses get their names computed at code gen time

		// now we continue to generate the bytes inside the contents array
		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
		this.contents[this.contentsOffset++] = (byte) accessFlags;
		int classNameIndex = this.constantPool.literalIndexForType(aType);
		this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) classNameIndex;
		int superclassNameIndex;
		if (aType.isInterface()) {
			superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
		} else {
			if (aType.superclass != null) {
				 if ((aType.superclass.tagBits & TagBits.HasMissingType) != 0) {
						superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
				 } else {
						superclassNameIndex = this.constantPool.literalIndexForType(aType.superclass);
				 }
			} else {
				superclassNameIndex = 0;
//{ObjectTeams: when compiler o.o.Team.__OT__Confined re-insert Object as superclass:
				if (CharOperation.equals(aType.compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED))
					superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
// SH}
			}
		}
		this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
		ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
		int interfacesCount = superInterfacesBinding.length;
		int interfacesCountPosition = this.contentsOffset;
		this.contentsOffset += 2;
		int interfaceCounter = 0;
		for (int i = 0; i < interfacesCount; i++) {
			ReferenceBinding binding = superInterfacesBinding[i];
			if ((binding.tagBits & TagBits.HasMissingType) != 0) {
				continue;
			}
			interfaceCounter++;
			int interfaceIndex = this.constantPool.literalIndexForType(binding);
			this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) interfaceIndex;
		}
		this.contents[interfacesCountPosition++] = (byte) (interfaceCounter >> 8);
		this.contents[interfacesCountPosition] = (byte) interfaceCounter;
		this.creatingProblemType = createProblemType;

		// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
		// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
		this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
	}

	private void initializeDefaultLocals(StackMapFrame frame,
			MethodBinding methodBinding,
			int maxLocals,
			int codeLength) {
		if (maxLocals != 0) {
			int resolvedPosition = 0;
			// take into account enum constructor synthetic name+ordinal
			final boolean isConstructor = methodBinding.isConstructor();
			if (isConstructor || !methodBinding.isStatic()) {
				LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false);
				localVariableBinding.resolvedPosition = 0;
				this.codeStream.record(localVariableBinding);
				localVariableBinding.recordInitializationStartPC(0);
				localVariableBinding.recordInitializationEndPC(codeLength);
				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
						isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT,
						methodBinding.declaringClass));
				resolvedPosition++;
			}
//{ObjectTeams: synthetic enclosing team + dummy arg?
	        if (methodBinding.needsSyntheticEnclosingTeamInstance()) {
	        	frame.putLocal(resolvedPosition, new VerificationTypeInfo(VerificationTypeInfo.ITEM_OBJECT, methodBinding.declaringClass.enclosingType()));
	        	resolvedPosition++;
	            frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeBinding.INT));
	            resolvedPosition++;
	        }
// SH}

			if (isConstructor) {
				if (methodBinding.declaringClass.isEnum()) {
					LocalVariableBinding localVariableBinding = new LocalVariableBinding(" name".toCharArray(), this.referenceBinding.scope.getJavaLangString(), 0, false); //$NON-NLS-1$
					localVariableBinding.resolvedPosition = resolvedPosition;
					this.codeStream.record(localVariableBinding);
					localVariableBinding.recordInitializationStartPC(0);
					localVariableBinding.recordInitializationEndPC(codeLength);

					frame.putLocal(resolvedPosition, new VerificationTypeInfo(
							TypeIds.T_JavaLangString,
							ConstantPool.JavaLangStringConstantPoolName));
					resolvedPosition++;

					localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$
					localVariableBinding.resolvedPosition = resolvedPosition;
					this.codeStream.record(localVariableBinding);
					localVariableBinding.recordInitializationStartPC(0);
					localVariableBinding.recordInitializationEndPC(codeLength);
					frame.putLocal(resolvedPosition, new VerificationTypeInfo(
							TypeBinding.INT));
					resolvedPosition++;
				}

				// take into account the synthetic parameters
				if (methodBinding.declaringClass.isNestedType()) {
					ReferenceBinding enclosingInstanceTypes[];
					if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
						for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
							// an enclosingInstanceType can only be a reference
							// binding. It cannot be
							// LongBinding or DoubleBinding
							LocalVariableBinding localVariableBinding = new LocalVariableBinding((" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false); //$NON-NLS-1$
							localVariableBinding.resolvedPosition = resolvedPosition;
							this.codeStream.record(localVariableBinding);
							localVariableBinding.recordInitializationStartPC(0);
							localVariableBinding.recordInitializationEndPC(codeLength);

							frame.putLocal(resolvedPosition,
									new VerificationTypeInfo(enclosingInstanceTypes[i]));
							resolvedPosition++;
						}
					}

					TypeBinding[] arguments;
					if ((arguments = methodBinding.parameters) != null) {
						for (int i = 0, max = arguments.length; i < max; i++) {
							final TypeBinding typeBinding = arguments[i];
							frame.putLocal(resolvedPosition,
									new VerificationTypeInfo(typeBinding));
							switch (typeBinding.id) {
								case TypeIds.T_double:
								case TypeIds.T_long:
									resolvedPosition += 2;
									break;
								default:
									resolvedPosition++;
							}
						}
					}

					SyntheticArgumentBinding syntheticArguments[];
					if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
						for (int i = 0, max = syntheticArguments.length; i < max; i++) {
							final TypeBinding typeBinding = syntheticArguments[i].type;
							LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, false); //$NON-NLS-1$
							localVariableBinding.resolvedPosition = resolvedPosition;
							this.codeStream.record(localVariableBinding);
							localVariableBinding.recordInitializationStartPC(0);
							localVariableBinding.recordInitializationEndPC(codeLength);

							frame.putLocal(resolvedPosition,
									new VerificationTypeInfo(typeBinding));
							switch (typeBinding.id) {
								case TypeIds.T_double:
								case TypeIds.T_long:
									resolvedPosition += 2;
									break;
								default:
									resolvedPosition++;
							}
						}
					}
				} else {
					TypeBinding[] arguments;
					if ((arguments = methodBinding.parameters) != null) {
						for (int i = 0, max = arguments.length; i < max; i++) {
							final TypeBinding typeBinding = arguments[i];
							frame.putLocal(resolvedPosition,
									new VerificationTypeInfo(typeBinding));
							switch (typeBinding.id) {
								case TypeIds.T_double:
								case TypeIds.T_long:
									resolvedPosition += 2;
									break;
								default:
									resolvedPosition++;
							}
						}
					}
				}
			} else {
				TypeBinding[] arguments;
				if ((arguments = methodBinding.parameters) != null) {
					for (int i = 0, max = arguments.length; i < max; i++) {
						final TypeBinding typeBinding = arguments[i];
//{ObjectTeams: bugfix (?) re Bug 416781 - reconcile compiler changes from BETA_JAVA8 with OT/J
						if (CharOperation.equals(TypeConstants.DESERIALIZE_LAMBDA, methodBinding.selector)) {
// orig:
							// For the branching complexities in the generated $deserializeLambda$ we need the local variable
							LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic"+i).toCharArray(), typeBinding, 0, true); //$NON-NLS-1$
							localVariableBinding.resolvedPosition = i;
							this.codeStream.record(localVariableBinding);
							localVariableBinding.recordInitializationStartPC(0);
							localVariableBinding.recordInitializationEndPC(codeLength);
// :giro
						}
// SH}
						frame.putLocal(resolvedPosition,
								new VerificationTypeInfo(typeBinding));
						switch (typeBinding.id) {
							case TypeIds.T_double:
							case TypeIds.T_long:
								resolvedPosition += 2;
								break;
							default:
								resolvedPosition++;
						}
					}
				}
			}
		}
	}

	private void initializeLocals(boolean isStatic, int currentPC, StackMapFrame currentFrame) {
		VerificationTypeInfo[] locals = currentFrame.locals;
		int localsLength = locals.length;
		int i = 0;
		if (!isStatic) {
			// we don't want to reset the first local if the method is not static
			i = 1;
		}
		for (; i < localsLength; i++) {
			locals[i] = null;
		}
		i = 0;
		locals: for (int max = this.codeStream.allLocalsCounter; i < max; i++) {
			LocalVariableBinding localVariable = this.codeStream.locals[i];
			if (localVariable == null) continue;
			int resolvedPosition = localVariable.resolvedPosition;
			final TypeBinding localVariableTypeBinding = localVariable.type;
			inits: for (int j = 0; j < localVariable.initializationCount; j++) {
				int startPC = localVariable.initializationPCs[j << 1];
				int endPC = localVariable.initializationPCs[(j << 1) + 1];
				if (currentPC < startPC) {
					continue inits;
				} else if (currentPC < endPC) {
					// the current local is an active local
					if (currentFrame.locals[resolvedPosition] == null) {
						currentFrame.locals[resolvedPosition] =
								new VerificationTypeInfo(
										localVariableTypeBinding);
					}
					continue locals;
				}
			}
		}
	}
	/**
	 * INTERNAL USE-ONLY
	 * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name
	 * for all inner types of the receiver.
	 * @return org.eclipse.jdt.internal.compiler.codegen.ClassFile
	 */
	public ClassFile outerMostEnclosingClassFile() {
		ClassFile current = this;
		while (current.enclosingClassFile != null)
			current = current.enclosingClassFile;
		return current;
	}

	public void recordInnerClasses(TypeBinding binding) {
		if (this.innerClassesBindings == null) {
			this.innerClassesBindings = new HashSet(INNER_CLASSES_SIZE);
		}
		ReferenceBinding innerClass = (ReferenceBinding) binding;
		this.innerClassesBindings.add(innerClass.erasure().unannotated());  // should not emit yet another inner class for Outer.@Inner Inner.
		ReferenceBinding enclosingType = innerClass.enclosingType();
		while (enclosingType != null
				&& enclosingType.isNestedType()) {
			this.innerClassesBindings.add(enclosingType.erasure().unannotated());
			enclosingType = enclosingType.enclosingType();
		}
	}

//{ObjectTeams: byte code attributes need contents resizing:
	public final byte[] getResizedContents(int minimalSize) {
		resizeContents(minimalSize);
		return this.contents;
	}
//MW}

	public int recordBootstrapMethod(FunctionalExpression expression) {
		if (this.bootstrapMethods == null) {
			this.bootstrapMethods = new ArrayList();
		}
		this.bootstrapMethods.add(expression);
		// Record which bootstrap method was assigned to the expression
		expression.bootstrapMethodNumber = this.bootstrapMethods.size() - 1;
		return this.bootstrapMethods.size() - 1;
	}

	public void reset(SourceTypeBinding typeBinding) {
		// the code stream is reinitialized for each method
		final CompilerOptions options = typeBinding.scope.compilerOptions();
		this.referenceBinding = typeBinding;
		this.isNestedType = typeBinding.isNestedType();
		this.targetJDK = options.targetJDK;
		this.produceAttributes = options.produceDebugAttributes;
		if (this.targetJDK >= ClassFileConstants.JDK1_6) {
			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
			if (this.targetJDK >= ClassFileConstants.JDK1_8) {
				this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
			}
		} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
			this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
		}
		this.bytes = null;
		this.constantPool.reset();
		this.codeStream.reset(this);
		this.constantPoolOffset = 0;
		this.contentsOffset = 0;
		this.creatingProblemType = false;
		this.enclosingClassFile = null;
		this.headerOffset = 0;
		this.methodCount = 0;
		this.methodCountOffset = 0;
		if (this.innerClassesBindings != null) {
			this.innerClassesBindings.clear();
		}
		if (this.bootstrapMethods != null) {
			this.bootstrapMethods.clear();
		}
		this.missingTypes = null;
		this.visitedTypes = null;
	}

	/**
	 * Resize the pool contents
	 */
	private final void resizeContents(int minimalSize) {
		int length = this.contents.length;
		int toAdd = length;
		if (toAdd < minimalSize)
			toAdd = minimalSize;
		System.arraycopy(this.contents, 0, this.contents = new byte[length + toAdd], 0, length);
	}

	private VerificationTypeInfo retrieveLocal(int currentPC, int resolvedPosition) {
		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
			LocalVariableBinding localVariable = this.codeStream.locals[i];
			if (localVariable == null) continue;
			if (resolvedPosition == localVariable.resolvedPosition) {
				inits: for (int j = 0; j < localVariable.initializationCount; j++) {
					int startPC = localVariable.initializationPCs[j << 1];
					int endPC = localVariable.initializationPCs[(j << 1) + 1];
					if (currentPC < startPC) {
						continue inits;
					} else if (currentPC < endPC) {
						// the current local is an active local
						return new VerificationTypeInfo(localVariable.type);
					}
				}
			}
		}
		return null;
	}

	private int scanType(char[] methodSignature, int index) {
		switch (methodSignature[index]) {
			case '[':
				// array type
				return scanType(methodSignature, index + 1);
			case 'L':
				return CharOperation.indexOf(';', methodSignature, index + 1);
			case 'Z':
			case 'B':
			case 'C':
			case 'D':
			case 'F':
			case 'I':
			case 'J':
			case 'S':
				return index;
			default:
				throw new IllegalArgumentException();
		}
	}

	/**
	 * INTERNAL USE-ONLY
	 * This methods leaves the space for method counts recording.
	 */
	public void setForMethodInfos() {
		// leave some space for the methodCount
		this.methodCountOffset = this.contentsOffset;
		this.contentsOffset += 2;
	}
	
	private List filterFakeFrames(Set realJumpTargets, Map frames, int codeLength) {
		// no more frame to generate
		// filter out "fake" frames
		realJumpTargets.remove(new Integer(codeLength));
		List result = new ArrayList();
		for (Iterator iterator = realJumpTargets.iterator(); iterator.hasNext(); ) {
			Integer jumpTarget = (Integer) iterator.next();
			StackMapFrame frame = (StackMapFrame) frames.get(jumpTarget);
			if (frame != null) {
				result.add(frame);
			}
		}
		Collections.sort(result, new Comparator() {
			public int compare(Object o1, Object o2) {
				StackMapFrame frame = (StackMapFrame) o1;
				StackMapFrame frame2 = (StackMapFrame) o2;
				return frame.pc - frame2.pc;
			}
		});
		return result;
	}

	public List traverse(MethodBinding methodBinding, int maxLocals, byte[] bytecodes, int codeOffset, int codeLength, Map frames, boolean isClinit) {
		Set realJumpTarget = new HashSet(); 

		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
		int[] framePositions = stackMapFrameCodeStream.getFramePositions();
		int pc = codeOffset;
		int index;
		int[] constantPoolOffsets = this.constantPool.offsets;
		byte[] poolContents = this.constantPool.poolContent;

		// set initial values for frame positions
		int indexInFramePositions = 0;
		int framePositionsLength = framePositions.length;
		int currentFramePosition = framePositions[0];

		// set initial values for stack depth markers
		int indexInStackDepthMarkers = 0;
		StackDepthMarker[] stackDepthMarkers = stackMapFrameCodeStream.getStackDepthMarkers();
		int stackDepthMarkersLength = stackDepthMarkers == null ? 0 : stackDepthMarkers.length;
		boolean hasStackDepthMarkers = stackDepthMarkersLength != 0;
		StackDepthMarker stackDepthMarker = null;
		if (hasStackDepthMarkers) {
			stackDepthMarker = stackDepthMarkers[0];
		}

		// set initial values for stack markers (used only in cldc mode)
		int indexInStackMarkers = 0;
		StackMarker[] stackMarkers = stackMapFrameCodeStream.getStackMarkers();
		int stackMarkersLength = stackMarkers == null ? 0 : stackMarkers.length;
		boolean hasStackMarkers = stackMarkersLength != 0;
		StackMarker stackMarker = null;
		if (hasStackMarkers) {
			stackMarker = stackMarkers[0];
		}

		// set initial values for exception markers
		int indexInExceptionMarkers = 0;
		ExceptionMarker[] exceptionMarkers= stackMapFrameCodeStream.getExceptionMarkers();
		int exceptionsMarkersLength = exceptionMarkers == null ? 0 : exceptionMarkers.length;
		boolean hasExceptionMarkers = exceptionsMarkersLength != 0;
		ExceptionMarker exceptionMarker = null;
		if (hasExceptionMarkers) {
			exceptionMarker = exceptionMarkers[0];
		}

		StackMapFrame frame = new StackMapFrame(maxLocals);
		if (!isClinit) {
			initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength);
		}
		frame.pc = -1;
		add(frames, frame.duplicate());
		addRealJumpTarget(realJumpTarget, -1);
		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
			ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i];
			if (exceptionLabel != null) {
				addRealJumpTarget(realJumpTarget, exceptionLabel.position);
			}
		}
		while (true) {
			int currentPC = pc - codeOffset;
			if (hasStackMarkers && stackMarker.pc == currentPC) {
				VerificationTypeInfo[] infos = frame.stackItems;
				VerificationTypeInfo[] tempInfos = new VerificationTypeInfo[frame.numberOfStackItems];
				System.arraycopy(infos, 0, tempInfos, 0, frame.numberOfStackItems);
				stackMarker.setInfos(tempInfos);
			} else if (hasStackMarkers && stackMarker.destinationPC == currentPC) {
				VerificationTypeInfo[] infos = stackMarker.infos;
				frame.stackItems = infos;
				frame.numberOfStackItems = infos.length;
				indexInStackMarkers++;
				if (indexInStackMarkers < stackMarkersLength) {
					stackMarker = stackMarkers[indexInStackMarkers];
				} else {
					hasStackMarkers = false;
				}
			}
			if (hasStackDepthMarkers && stackDepthMarker.pc == currentPC) {
				TypeBinding typeBinding = stackDepthMarker.typeBinding;
				if (typeBinding != null) {
					if (stackDepthMarker.delta > 0) {
						frame.addStackItem(new VerificationTypeInfo(typeBinding));
					} else {
						frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
					}
				} else {
					frame.numberOfStackItems--;
				}
				indexInStackDepthMarkers++;
				if (indexInStackDepthMarkers < stackDepthMarkersLength) {
					stackDepthMarker = stackDepthMarkers[indexInStackDepthMarkers];
				} else {
					hasStackDepthMarkers = false;
				}
			}
			if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
				frame.numberOfStackItems = 0;
				frame.addStackItem(new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_OBJECT, exceptionMarker.constantPoolName));
				indexInExceptionMarkers++;
				if (indexInExceptionMarkers < exceptionsMarkersLength) {
					exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
				} else {
					hasExceptionMarkers = false;
				}
			}
			if (currentFramePosition < currentPC) {
				do {
					indexInFramePositions++;
					if (indexInFramePositions < framePositionsLength) {
						currentFramePosition = framePositions[indexInFramePositions];
					} else {
						currentFramePosition = Integer.MAX_VALUE;
					}
				} while (currentFramePosition < currentPC);
			}
			if (currentFramePosition == currentPC) {
				// need to build a new frame and create a stack map attribute entry
				StackMapFrame currentFrame = frame.duplicate();
				currentFrame.pc = currentPC;
				// initialize locals
				initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, currentFrame);
				// insert a new frame
				add(frames, currentFrame);
				indexInFramePositions++;
				if (indexInFramePositions < framePositionsLength) {
					currentFramePosition = framePositions[indexInFramePositions];
				} else {
					currentFramePosition = Integer.MAX_VALUE;
				}
			}
			byte opcode = (byte) u1At(bytecodes, 0, pc);
			switch (opcode) {
				case Opcodes.OPC_nop:
					pc++;
					break;
				case Opcodes.OPC_aconst_null:
					frame.addStackItem(TypeBinding.NULL);
					pc++;
					break;
				case Opcodes.OPC_iconst_m1:
				case Opcodes.OPC_iconst_0:
				case Opcodes.OPC_iconst_1:
				case Opcodes.OPC_iconst_2:
				case Opcodes.OPC_iconst_3:
				case Opcodes.OPC_iconst_4:
				case Opcodes.OPC_iconst_5:
					frame.addStackItem(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_lconst_0:
				case Opcodes.OPC_lconst_1:
					frame.addStackItem(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_fconst_0:
				case Opcodes.OPC_fconst_1:
				case Opcodes.OPC_fconst_2:
					frame.addStackItem(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_dconst_0:
				case Opcodes.OPC_dconst_1:
					frame.addStackItem(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_bipush:
					frame.addStackItem(TypeBinding.BYTE);
					pc += 2;
					break;
				case Opcodes.OPC_sipush:
					frame.addStackItem(TypeBinding.SHORT);
					pc += 3;
					break;
				case Opcodes.OPC_ldc:
					index = u1At(bytecodes, 1, pc);
					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
						case ClassFileConstants.StringTag:
							frame
									.addStackItem(new VerificationTypeInfo(
											TypeIds.T_JavaLangString,
											ConstantPool.JavaLangStringConstantPoolName));
							break;
						case ClassFileConstants.IntegerTag:
							frame.addStackItem(TypeBinding.INT);
							break;
						case ClassFileConstants.FloatTag:
							frame.addStackItem(TypeBinding.FLOAT);
							break;
						case ClassFileConstants.ClassTag:
							frame.addStackItem(new VerificationTypeInfo(
									TypeIds.T_JavaLangClass,
									ConstantPool.JavaLangClassConstantPoolName));
					}
					pc += 2;
					break;
				case Opcodes.OPC_ldc_w:
					index = u2At(bytecodes, 1, pc);
					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
						case ClassFileConstants.StringTag:
							frame
									.addStackItem(new VerificationTypeInfo(
											TypeIds.T_JavaLangString,
											ConstantPool.JavaLangStringConstantPoolName));
							break;
						case ClassFileConstants.IntegerTag:
							frame.addStackItem(TypeBinding.INT);
							break;
						case ClassFileConstants.FloatTag:
							frame.addStackItem(TypeBinding.FLOAT);
							break;
						case ClassFileConstants.ClassTag:
							frame.addStackItem(new VerificationTypeInfo(
									TypeIds.T_JavaLangClass,
									ConstantPool.JavaLangClassConstantPoolName));
					}
					pc += 3;
					break;
				case Opcodes.OPC_ldc2_w:
					index = u2At(bytecodes, 1, pc);
					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
						case ClassFileConstants.DoubleTag:
							frame.addStackItem(TypeBinding.DOUBLE);
							break;
						case ClassFileConstants.LongTag:
							frame.addStackItem(TypeBinding.LONG);
							break;
					}
					pc += 3;
					break;
				case Opcodes.OPC_iload:
					frame.addStackItem(TypeBinding.INT);
					pc += 2;
					break;
				case Opcodes.OPC_lload:
					frame.addStackItem(TypeBinding.LONG);
					pc += 2;
					break;
				case Opcodes.OPC_fload:
					frame.addStackItem(TypeBinding.FLOAT);
					pc += 2;
					break;
				case Opcodes.OPC_dload:
					frame.addStackItem(TypeBinding.DOUBLE);
					pc += 2;
					break;
				case Opcodes.OPC_aload:
					index = u1At(bytecodes, 1, pc);
					VerificationTypeInfo localsN = retrieveLocal(currentPC, index);
					frame.addStackItem(localsN);
					pc += 2;
					break;
				case Opcodes.OPC_iload_0:
				case Opcodes.OPC_iload_1:
				case Opcodes.OPC_iload_2:
				case Opcodes.OPC_iload_3:
					frame.addStackItem(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_lload_0:
				case Opcodes.OPC_lload_1:
				case Opcodes.OPC_lload_2:
				case Opcodes.OPC_lload_3:
					frame.addStackItem(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_fload_0:
				case Opcodes.OPC_fload_1:
				case Opcodes.OPC_fload_2:
				case Opcodes.OPC_fload_3:
					frame.addStackItem(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_dload_0:
				case Opcodes.OPC_dload_1:
				case Opcodes.OPC_dload_2:
				case Opcodes.OPC_dload_3:
					frame.addStackItem(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_aload_0:
					VerificationTypeInfo locals0 = frame.locals[0];
					if (locals0 == null || locals0.tag != VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
						// special case to handle uninitialized object
						locals0 = retrieveLocal(currentPC, 0);
					}
					frame.addStackItem(locals0);
					pc++;
					break;
				case Opcodes.OPC_aload_1:
					VerificationTypeInfo locals1 = retrieveLocal(currentPC, 1);
					frame.addStackItem(locals1);
					pc++;
					break;
				case Opcodes.OPC_aload_2:
					VerificationTypeInfo locals2 = retrieveLocal(currentPC, 2);
					frame.addStackItem(locals2);
					pc++;
					break;
				case Opcodes.OPC_aload_3:
					VerificationTypeInfo locals3 = retrieveLocal(currentPC, 3);
					frame.addStackItem(locals3);
					pc++;
					break;
				case Opcodes.OPC_iaload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_laload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_faload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_daload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_aaload:
					frame.numberOfStackItems--;
					frame.replaceWithElementType();
					pc++;
					break;
				case Opcodes.OPC_baload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.BYTE);
					pc++;
					break;
				case Opcodes.OPC_caload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.CHAR);
					pc++;
					break;
				case Opcodes.OPC_saload:
					frame.numberOfStackItems -=2;
					frame.addStackItem(TypeBinding.SHORT);
					pc++;
					break;
				case Opcodes.OPC_istore:
				case Opcodes.OPC_lstore:
				case Opcodes.OPC_fstore:
				case Opcodes.OPC_dstore:
					frame.numberOfStackItems--;
					pc += 2;
					break;
				case Opcodes.OPC_astore:
					index = u1At(bytecodes, 1, pc);
					frame.numberOfStackItems--;
					pc += 2;
					break;
				case Opcodes.OPC_astore_0:
					frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					pc++;
					break;
				case Opcodes.OPC_astore_1:
				case Opcodes.OPC_astore_2:
				case Opcodes.OPC_astore_3:
				case Opcodes.OPC_istore_0:
				case Opcodes.OPC_istore_1:
				case Opcodes.OPC_istore_2:
				case Opcodes.OPC_istore_3:
				case Opcodes.OPC_lstore_0:
				case Opcodes.OPC_lstore_1:
				case Opcodes.OPC_lstore_2:
				case Opcodes.OPC_lstore_3:
				case Opcodes.OPC_fstore_0:
				case Opcodes.OPC_fstore_1:
				case Opcodes.OPC_fstore_2:
				case Opcodes.OPC_fstore_3:
				case Opcodes.OPC_dstore_0:
				case Opcodes.OPC_dstore_1:
				case Opcodes.OPC_dstore_2:
				case Opcodes.OPC_dstore_3:
					frame.numberOfStackItems--;
					pc++;
					break;
				case Opcodes.OPC_iastore:
				case Opcodes.OPC_lastore:
				case Opcodes.OPC_fastore:
				case Opcodes.OPC_dastore:
				case Opcodes.OPC_aastore:
				case Opcodes.OPC_bastore:
				case Opcodes.OPC_castore:
				case Opcodes.OPC_sastore:
					frame.numberOfStackItems-=3;
					pc++;
					break;
				case Opcodes.OPC_pop:
					frame.numberOfStackItems--;
					pc++;
					break;
				case Opcodes.OPC_pop2:
					int numberOfStackItems = frame.numberOfStackItems;
					switch(frame.stackItems[numberOfStackItems - 1].id()) {
						case TypeIds.T_long :
						case TypeIds.T_double :
							frame.numberOfStackItems--;
							break;
						default:
							frame.numberOfStackItems -= 2;
					}
					pc++;
					break;
				case Opcodes.OPC_dup:
					frame.addStackItem(frame.stackItems[frame.numberOfStackItems - 1]);
					pc++;
					break;
				case Opcodes.OPC_dup_x1:
					VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					frame.addStackItem(info);
					frame.addStackItem(info2);
					frame.addStackItem(info);
					pc++;
					break;
				case Opcodes.OPC_dup_x2:
					info = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					info2 = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					switch(info2.id()) {
						case TypeIds.T_long :
						case TypeIds.T_double :
							frame.addStackItem(info);
							frame.addStackItem(info2);
							frame.addStackItem(info);
							break;
						default:
							numberOfStackItems = frame.numberOfStackItems;
							VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
							frame.numberOfStackItems--;
							frame.addStackItem(info);
							frame.addStackItem(info3);
							frame.addStackItem(info2);
							frame.addStackItem(info);
					}
					pc++;
					break;
				case Opcodes.OPC_dup2:
					info = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					switch(info.id()) {
						case TypeIds.T_double :
						case TypeIds.T_long :
							frame.addStackItem(info);
							frame.addStackItem(info);
							break;
						default:
							info2 = frame.stackItems[frame.numberOfStackItems - 1];
							frame.numberOfStackItems--;
							frame.addStackItem(info2);
							frame.addStackItem(info);
							frame.addStackItem(info2);
							frame.addStackItem(info);
					}
					pc++;
					break;
				case Opcodes.OPC_dup2_x1:
					info = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					info2 = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					switch(info.id()) {
						case TypeIds.T_double :
						case TypeIds.T_long :
							frame.addStackItem(info);
							frame.addStackItem(info2);
							frame.addStackItem(info);
							break;
						default:
							VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1];
							frame.numberOfStackItems--;
							frame.addStackItem(info2);
							frame.addStackItem(info);
							frame.addStackItem(info3);
							frame.addStackItem(info2);
							frame.addStackItem(info);
					}
					pc++;
					break;
				case Opcodes.OPC_dup2_x2:
					numberOfStackItems = frame.numberOfStackItems;
					info = frame.stackItems[numberOfStackItems - 1];
					frame.numberOfStackItems--;
					info2 = frame.stackItems[frame.numberOfStackItems - 1];
					frame.numberOfStackItems--;
					switch(info.id()) {
						case TypeIds.T_long :
						case TypeIds.T_double :
							switch(info2.id()) {
								case TypeIds.T_long :
								case TypeIds.T_double :
									// form 4
									frame.addStackItem(info);
									frame.addStackItem(info2);
									frame.addStackItem(info);
									break;
								default:
									// form 2
									numberOfStackItems = frame.numberOfStackItems;
									VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
									frame.numberOfStackItems--;
									frame.addStackItem(info);
									frame.addStackItem(info3);
									frame.addStackItem(info2);
									frame.addStackItem(info);
							}
							break;
						default:
							numberOfStackItems = frame.numberOfStackItems;
							VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
							frame.numberOfStackItems--;
							switch(info3.id()) {
								case TypeIds.T_long :
								case TypeIds.T_double :
									// form 3
									frame.addStackItem(info2);
									frame.addStackItem(info);
									frame.addStackItem(info3);
									frame.addStackItem(info2);
									frame.addStackItem(info);
									break;
								default:
									// form 1
									numberOfStackItems = frame.numberOfStackItems;
									VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1];
									frame.numberOfStackItems--;
									frame.addStackItem(info2);
									frame.addStackItem(info);
									frame.addStackItem(info4);
									frame.addStackItem(info3);
									frame.addStackItem(info2);
									frame.addStackItem(info);
							}
					}
					pc++;
					break;
				case Opcodes.OPC_swap:
					numberOfStackItems = frame.numberOfStackItems;
					info = frame.stackItems[numberOfStackItems - 1];
					info2 = frame.stackItems[numberOfStackItems - 2];
					frame.stackItems[numberOfStackItems - 1] = info2;
					frame.stackItems[numberOfStackItems - 2] = info;
					pc++;
					break;
				case Opcodes.OPC_iadd:
				case Opcodes.OPC_ladd:
				case Opcodes.OPC_fadd:
				case Opcodes.OPC_dadd:
				case Opcodes.OPC_isub:
				case Opcodes.OPC_lsub:
				case Opcodes.OPC_fsub:
				case Opcodes.OPC_dsub:
				case Opcodes.OPC_imul:
				case Opcodes.OPC_lmul:
				case Opcodes.OPC_fmul:
				case Opcodes.OPC_dmul:
				case Opcodes.OPC_idiv:
				case Opcodes.OPC_ldiv:
				case Opcodes.OPC_fdiv:
				case Opcodes.OPC_ddiv:
				case Opcodes.OPC_irem:
				case Opcodes.OPC_lrem:
				case Opcodes.OPC_frem:
				case Opcodes.OPC_drem:
				case Opcodes.OPC_ishl:
				case Opcodes.OPC_lshl:
				case Opcodes.OPC_ishr:
				case Opcodes.OPC_lshr:
				case Opcodes.OPC_iushr:
				case Opcodes.OPC_lushr:
				case Opcodes.OPC_iand:
				case Opcodes.OPC_land:
				case Opcodes.OPC_ior:
				case Opcodes.OPC_lor:
				case Opcodes.OPC_ixor:
				case Opcodes.OPC_lxor:
					frame.numberOfStackItems--;
					pc++;
					break;
				case Opcodes.OPC_ineg:
				case Opcodes.OPC_lneg:
				case Opcodes.OPC_fneg:
				case Opcodes.OPC_dneg:
					pc++;
					break;
				case Opcodes.OPC_iinc:
					pc += 3;
					break;
				case Opcodes.OPC_i2l:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_i2f:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_i2d:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_l2i:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_l2f:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_l2d:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_f2i:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_f2l:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_f2d:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
					pc++;
					break;
				case Opcodes.OPC_d2i:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_d2l:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
					pc++;
					break;
				case Opcodes.OPC_d2f:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
					pc++;
					break;
				case Opcodes.OPC_i2b:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE);
					pc++;
					break;
				case Opcodes.OPC_i2c:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR);
					pc++;
					break;
				case Opcodes.OPC_i2s:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT);
					pc++;
					break;
				case Opcodes.OPC_lcmp:
				case Opcodes.OPC_fcmpl:
				case Opcodes.OPC_fcmpg:
				case Opcodes.OPC_dcmpl:
				case Opcodes.OPC_dcmpg:
					frame.numberOfStackItems-=2;
					frame.addStackItem(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_ifeq:
				case Opcodes.OPC_ifne:
				case Opcodes.OPC_iflt:
				case Opcodes.OPC_ifge:
				case Opcodes.OPC_ifgt:
				case Opcodes.OPC_ifle:
					frame.numberOfStackItems--;
					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
					pc += 3;
					break;
				case Opcodes.OPC_if_icmpeq:
				case Opcodes.OPC_if_icmpne:
				case Opcodes.OPC_if_icmplt:
				case Opcodes.OPC_if_icmpge:
				case Opcodes.OPC_if_icmpgt:
				case Opcodes.OPC_if_icmple:
				case Opcodes.OPC_if_acmpeq:
				case Opcodes.OPC_if_acmpne:
					frame.numberOfStackItems -= 2;
					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
					pc += 3;
					break;
				case Opcodes.OPC_goto:
					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
					pc += 3;
					addRealJumpTarget(realJumpTarget, pc - codeOffset);
					break;
				case Opcodes.OPC_tableswitch:
					pc++;
					while (((pc - codeOffset) & 0x03) != 0) {
						pc++;
					}
					// default offset
					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
					pc += 4; // default
					int low = i4At(bytecodes, 0, pc);
					pc += 4;
					int high = i4At(bytecodes, 0, pc);
					pc += 4;
					int length = high - low + 1;
					for (int i = 0; i < length; i++) {
						// pair offset
						addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
						pc += 4;
					}
					frame.numberOfStackItems--;
					break;
				case Opcodes.OPC_lookupswitch:
					pc++;
					while (((pc - codeOffset) & 0x03) != 0) {
						pc++;
					}
					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
					pc += 4; // default offset
					int npairs = (int) u4At(bytecodes, 0, pc);
					pc += 4; // npair value
					for (int i = 0; i < npairs; i++) {
						pc += 4; // case value
						// pair offset
						addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
						pc += 4;
					}
					frame.numberOfStackItems--;
					break;
				case Opcodes.OPC_ireturn:
				case Opcodes.OPC_lreturn:
				case Opcodes.OPC_freturn:
				case Opcodes.OPC_dreturn:
				case Opcodes.OPC_areturn:
					frame.numberOfStackItems--;
					pc++;
					addRealJumpTarget(realJumpTarget, pc - codeOffset);
					break;
				case Opcodes.OPC_return:
					pc++;
					addRealJumpTarget(realJumpTarget, pc - codeOffset);
					break;
				case Opcodes.OPC_getstatic:
					index = u2At(bytecodes, 1, pc);
					int nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					int utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					char[] descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					if (descriptor.length == 1) {
						// base type
						switch(descriptor[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else if (descriptor[0] == '[') {
						frame.addStackItem(new VerificationTypeInfo(0, descriptor));
					} else {
						frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
					}
					pc += 3;
					break;
				case Opcodes.OPC_putstatic:
					frame.numberOfStackItems--;
					pc += 3;
					break;
				case Opcodes.OPC_getfield:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.numberOfStackItems--;
					if (descriptor.length == 1) {
						// base type
						switch(descriptor[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else if (descriptor[0] == '[') {
						frame.addStackItem(new VerificationTypeInfo(0, descriptor));
					} else {
						frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
					}
					pc += 3;
					break;
				case Opcodes.OPC_putfield:
					frame.numberOfStackItems -= 2;
					pc += 3;
					break;
				case Opcodes.OPC_invokevirtual:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[nameAndTypeIndex]);
					char[] name = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
					char[] returnType = getReturnType(descriptor);
					if (returnType.length == 1) {
						// base type
						switch(returnType[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else {
						if (returnType[0] == '[') {
							frame.addStackItem(new VerificationTypeInfo(0, returnType));
						} else {
							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
						}
					}
					pc += 3;
					break;
				case Opcodes.OPC_invokedynamic:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.numberOfStackItems -= getParametersCount(descriptor);
					returnType = getReturnType(descriptor);
					if (returnType.length == 1) {
						// base type
						switch(returnType[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else {
						if (returnType[0] == '[') {
							frame.addStackItem(new VerificationTypeInfo(0, returnType));
						} else {
							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
						}
					}
					pc += 5;
					break;
				case Opcodes.OPC_invokespecial:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[nameAndTypeIndex]);
					name = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.numberOfStackItems -= getParametersCount(descriptor);
					if (CharOperation.equals(ConstantPool.Init, name)) {
						// constructor
						frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT;
					}
					frame.numberOfStackItems--;
					returnType = getReturnType(descriptor);
					if (returnType.length == 1) {
						// base type
						switch(returnType[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else {
						if (returnType[0] == '[') {
							frame.addStackItem(new VerificationTypeInfo(0, returnType));
						} else {
							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
						}
					}
					pc += 3;
					break;
				case Opcodes.OPC_invokestatic:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[nameAndTypeIndex]);
					name = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.numberOfStackItems -= getParametersCount(descriptor);
					returnType = getReturnType(descriptor);
					if (returnType.length == 1) {
						// base type
						switch(returnType[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else {
						if (returnType[0] == '[') {
							frame.addStackItem(new VerificationTypeInfo(0, returnType));
						} else {
							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
						}
					}
					pc += 3;
					break;
				case Opcodes.OPC_invokeinterface:
					index = u2At(bytecodes, 1, pc);
					nameAndTypeIndex = u2At(poolContents, 3,
							constantPoolOffsets[index]);
					utf8index = u2At(poolContents, 3,
							constantPoolOffsets[nameAndTypeIndex]);
					descriptor = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[nameAndTypeIndex]);
					name = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					// we don't need count and args
					// u1At(bytecodes, 3, pc); // count
					// u1At(bytecodes, 4, pc); // extra args
					frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
					returnType = getReturnType(descriptor);
					if (returnType.length == 1) {
						// base type
						switch(returnType[0]) {
							case 'Z':
								frame.addStackItem(TypeBinding.BOOLEAN);
								break;
							case 'B':
								frame.addStackItem(TypeBinding.BYTE);
								break;
							case 'C':
								frame.addStackItem(TypeBinding.CHAR);
								break;
							case 'D':
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case 'F':
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case 'I':
								frame.addStackItem(TypeBinding.INT);
								break;
							case 'J':
								frame.addStackItem(TypeBinding.LONG);
								break;
							case 'S':
								frame.addStackItem(TypeBinding.SHORT);
								break;
						}
					} else {
						if (returnType[0] == '[') {
							frame.addStackItem(new VerificationTypeInfo(0, returnType));
						} else {
							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
						}
					}
					pc += 5;
					break;
				case Opcodes.OPC_new:
					index = u2At(bytecodes, 1, pc);
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[index]);
					char[] className = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_UNINITIALIZED, className);
					verificationTypeInfo.offset = currentPC;
					frame.addStackItem(verificationTypeInfo);
					pc += 3;
					break;
				case Opcodes.OPC_newarray:
					char[] constantPoolName = null;
					switch (u1At(bytecodes, 1, pc)) {
						case ClassFileConstants.INT_ARRAY :
							constantPoolName = new char[] { '[', 'I' };
							break;
						case ClassFileConstants.BYTE_ARRAY :
							constantPoolName = new char[] { '[', 'B' };
							break;
						case ClassFileConstants.BOOLEAN_ARRAY :
							constantPoolName = new char[] { '[', 'Z' };
							break;
						case ClassFileConstants.SHORT_ARRAY :
							constantPoolName = new char[] { '[', 'S' };
							break;
						case ClassFileConstants.CHAR_ARRAY :
							constantPoolName = new char[] { '[', 'C' };
							break;
						case ClassFileConstants.LONG_ARRAY :
							constantPoolName = new char[] { '[', 'J' };
							break;
						case ClassFileConstants.FLOAT_ARRAY :
							constantPoolName = new char[] { '[', 'F' };
							break;
						case ClassFileConstants.DOUBLE_ARRAY :
							constantPoolName = new char[] { '[', 'D' };
							break;
					}
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName);
					pc += 2;
					break;
				case Opcodes.OPC_anewarray:
					index = u2At(bytecodes, 1, pc);
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[index]);
					className = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					int classNameLength = className.length;
					if (className[0] != '[') {
						// this is a type name (class or interface). So we add appropriate '[', 'L' and ';'.
						System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength);
						constantPoolName[0] = '[';
						constantPoolName[1] = 'L';
						constantPoolName[classNameLength + 2] = ';';
					} else {
						// if class name is already an array, we just need to add one dimension
						System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 1]), 1, classNameLength);
						constantPoolName[0] = '[';
					}
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, constantPoolName);
					pc += 3;
					break;
				case Opcodes.OPC_arraylength:
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
					pc++;
					break;
				case Opcodes.OPC_athrow:
					frame.numberOfStackItems--;
					pc++;
					addRealJumpTarget(realJumpTarget, pc - codeOffset);
					break;
				case Opcodes.OPC_checkcast:
					index = u2At(bytecodes, 1, pc);
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[index]);
					className = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, className);
					pc += 3;
					break;
				case Opcodes.OPC_instanceof:
					// no need to know the class index = u2At(bytecodes, 1, pc);
					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
					pc += 3;
					break;
				case Opcodes.OPC_monitorenter:
				case Opcodes.OPC_monitorexit:
					frame.numberOfStackItems--;
					pc++;
					break;
				case Opcodes.OPC_wide:
					opcode = (byte) u1At(bytecodes, 1, pc);
					if (opcode == Opcodes.OPC_iinc) {
						// index = u2At(bytecodes, 2, pc);
						// i2At(bytecodes, 4, pc); // const
						// we don't need the index and the const value
						pc += 6;
					} else {
						index = u2At(bytecodes, 2, pc);
						// need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
						switch(opcode) {
							case Opcodes.OPC_iload :
								frame.addStackItem(TypeBinding.INT);
								break;
							case Opcodes.OPC_fload :
								frame.addStackItem(TypeBinding.FLOAT);
								break;
							case Opcodes.OPC_aload :
								localsN = frame.locals[index];
								if (localsN == null) {
									localsN = retrieveLocal(currentPC, index);
								}
								frame.addStackItem(localsN);
								break;
							case Opcodes.OPC_lload :
								frame.addStackItem(TypeBinding.LONG);
								break;
							case Opcodes.OPC_dload :
								frame.addStackItem(TypeBinding.DOUBLE);
								break;
							case Opcodes.OPC_istore :
								frame.numberOfStackItems--;
								break;
							case Opcodes.OPC_fstore :
								frame.numberOfStackItems--;
								break;
							case Opcodes.OPC_astore :
								frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1];
								frame.numberOfStackItems--;
								break;
							case Opcodes.OPC_lstore :
								frame.numberOfStackItems--;
								break;
							case Opcodes.OPC_dstore :
								frame.numberOfStackItems--;
								break;
						}
						pc += 4;
					}
					break;
				case Opcodes.OPC_multianewarray:
					index = u2At(bytecodes, 1, pc);
					utf8index = u2At(poolContents, 1,
							constantPoolOffsets[index]);
					className = utf8At(poolContents,
							constantPoolOffsets[utf8index] + 3, u2At(
									poolContents, 1,
									constantPoolOffsets[utf8index]));
					int dimensions = u1At(bytecodes, 3, pc); // dimensions
					frame.numberOfStackItems -= dimensions;
					classNameLength = className.length;
					constantPoolName = new char[classNameLength + dimensions];
					for (int i = 0; i < dimensions; i++) {
						constantPoolName[i] = '[';
					}
					System.arraycopy(className, 0, constantPoolName, dimensions, classNameLength);
					frame.addStackItem(new VerificationTypeInfo(0, constantPoolName));
					pc += 4;
					break;
				case Opcodes.OPC_ifnull:
				case Opcodes.OPC_ifnonnull:
					frame.numberOfStackItems--;
					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
					pc += 3;
					break;
				case Opcodes.OPC_goto_w:
					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 1, pc));
					pc += 5;
					addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop
					break;
				default: // should not occur
					if (this.codeStream.methodDeclaration != null) {
						this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
								Messages.bind(
										Messages.abort_invalidOpcode,
										new Object[] {
												new Byte(opcode),
												new Integer(pc),
												new String(methodBinding.shortReadableName()),
										}),
										this.codeStream.methodDeclaration);
					} else {
						this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
								Messages.bind(
										Messages.abort_invalidOpcode,
										new Object[] {
												new Byte(opcode),
												new Integer(pc),
												new String(methodBinding.shortReadableName()),
										}),
										this.codeStream.lambdaExpression);
					}
				break;
			}
			if (pc >= (codeLength + codeOffset)) {
				break;
			}
		}
		return filterFakeFrames(realJumpTarget, frames, codeLength);
	}

	private void addRealJumpTarget(Set realJumpTarget, int pc) {
		realJumpTarget.add(new Integer(pc));
	}
	private void add(Map frames, StackMapFrame frame) {
		frames.put(new Integer(frame.pc), frame);
	}
	private final int u1At(byte[] reference, int relativeOffset,
			int structOffset) {
		return (reference[relativeOffset + structOffset] & 0xFF);
	}

	private final int u2At(byte[] reference, int relativeOffset,
			int structOffset) {
		int position = relativeOffset + structOffset;
		return ((reference[position++] & 0xFF) << 8)
				+ (reference[position] & 0xFF);
	}

	private final long u4At(byte[] reference, int relativeOffset,
			int structOffset) {
		int position = relativeOffset + structOffset;
		return (((reference[position++] & 0xFFL) << 24)
				+ ((reference[position++] & 0xFF) << 16)
				+ ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
	}

	private final int i2At(byte[] reference, int relativeOffset, int structOffset) {
		int position = relativeOffset + structOffset;
		return (reference[position++] << 8) + (reference[position] & 0xFF);
	}

	public char[] utf8At(byte[] reference, int absoluteOffset,
			int bytesAvailable) {
		int length = bytesAvailable;
		char outputBuf[] = new char[bytesAvailable];
		int outputPos = 0;
		int readOffset = absoluteOffset;

		while (length != 0) {
			int x = reference[readOffset++] & 0xFF;
			length--;
			if ((0x80 & x) != 0) {
				if ((x & 0x20) != 0) {
					length -= 2;
					x = ((x & 0xF) << 12)
							| ((reference[readOffset++] & 0x3F) << 6)
							| (reference[readOffset++] & 0x3F);
				} else {
					length--;
					x = ((x & 0x1F) << 6) | (reference[readOffset++] & 0x3F);
				}
			}
			outputBuf[outputPos++] = (char) x;
		}

		if (outputPos != bytesAvailable) {
			System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]),
					0, outputPos);
		}
		return outputBuf;
	}
//{ObjectTeams: helpers for storing the path where a classfile is written to
	// This is the flow of information:
	// 1. CompilationUnitDeclaration.cleanUp() gives us a chance to store the type model
	//    (by calling maybeRememberModel())
	// 2. AbstractImageBuilder.writeClassFile() tells us about the file path
	//    (by calling maybeSetClassFilePath())
	//    The same for Util.getFileOutputStream().
	// 3. MethodModel.setupByteCode() may use this path to read the byte code from disc.
	//    The same for RoleModel.getByteCode().
	// After releaseModel() this data flow is no longer possible.
	private TypeModel generatingModel = null;

	/** Make a best effort at determining whether this is the ClassFile for type. */
	public boolean isForType(ReferenceBinding type) {
		if (this.generatingModel == null)
			return TypeBinding.equalsEquals(this.referenceBinding, type);
		if (this.generatingModel == type.roleModel)
			return true;
		if (this.generatingModel == type._teamModel)
			return true;
		return false;
	}
	/**
	 * Teams need a class file path for copying constructors and callin wrappers calling private role methods.
	 * Roles need a class file path for copying everything.
	 */
	public void maybeRememberModel() {
		if (this.referenceBinding != null) {
			if (this.referenceBinding.isRole())
				this.generatingModel = this.referenceBinding.roleModel;
				// role model's setClassFilePath() will transfer the path to a team model, too, if present.
			else if (this.referenceBinding.isTeam())
				this.generatingModel = this.referenceBinding.getTeamModel();
		}
	}
	public void maybeSetClassFilePath(String path) {
		if (this.generatingModel != null) {
			this.generatingModel.setClassFilePath(path);
			this.generatingModel = null; // cleanup, reference is no longer needed.
		}
	}
	/**
     * Releasing the role model means, that this class file can no longer be used
     * to retrieve that role's bytes.
     */
	void releaseModel() {
		if (this.generatingModel instanceof RoleModel)
			((RoleModel)this.generatingModel).releaseClassFile();
		this.generatingModel= null;
	}
// SH}
}
