/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *******************************************************************************/
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.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

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.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.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
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.ast.Wildcard;
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.VerificationTypeInfo;
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.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.BlockScope;
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;

/**
 * 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
 */
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 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) {
		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;
		if (methodDecls != null) {
			if (typeBinding.isInterface()) {
				// we cannot create problem methods for an interface. So we have to generate a clinit
				// which should contain all the problem
				classFile.addProblemClinit(problemsCopy);
				for (int i = 0, length = methodDecls.length; i < length; i++) {
					AbstractMethodDeclaration methodDecl = methodDecls[i];
					MethodBinding method = methodDecl.binding;
					if (method == null || method.isConstructor()) continue;
					method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
					classFile.addAbstractMethod(methodDecl, method);
				}
			} else {
				for (int i = 0, length = methodDecls.length; i < length; i++) {
					AbstractMethodDeclaration methodDecl = methodDecls[i];
					MethodBinding method = methodDecl.binding;
					if (method == null) continue;
					if (method.isConstructor()) {
						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);
	}

	/**
	 * Return the location for the corresponding annotation inside the type reference, <code>null</code> if none.
	 */
	private static int[] getWildcardLocations(TypeReference reference, Wildcard wildcard) {
		class LocationCollector extends ASTVisitor {
			Stack currentIndexes;
			boolean search = true;
			Wildcard currentWildcard;
			
			public LocationCollector(Wildcard currentWildcard) {
				this.currentIndexes = new Stack();
				this.currentWildcard = currentWildcard;
			}
			public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				TypeReference[] typeReferences = typeReference.typeArguments;
				this.currentIndexes.push(new Integer(0));
				for (int i = 0, max = typeReferences.length; i < max; i++) {
					typeReferences[i].traverse(this, scope);
					if (!this.search) return false;
					this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
				if (!this.search) return false;
				TypeReference[] typeReferences = typeReference.typeArguments[typeReference.typeArguments.length - 1];
				this.currentIndexes.push(new Integer(0));
				for (int i = 0, max = typeReferences.length; i < max; i++) {
					typeReferences[i].traverse(this, scope);
					if (!this.search) return false;
					this.currentIndexes.push(new Integer(((Integer) this.currentIndexes.pop()).intValue() + 1));
				}
				this.currentIndexes.pop();
				return true;
			}
			public boolean visit(Wildcard typeReference, BlockScope scope) {
				if (!this.search) return false;
				if (typeReference.equals(this.currentWildcard)) {
					this.search = false;
				}
				return true;
			}
			public String toString() {
				StringBuffer buffer = new StringBuffer();
				buffer
					.append("search location for ") //$NON-NLS-1$
					.append(this.currentWildcard)
					.append("\ncurrent indexes : ") //$NON-NLS-1$
					.append(this.currentIndexes);
				return String.valueOf(buffer);
			}
		}
		if (reference == null) return null;
		LocationCollector collector = new LocationCollector(wildcard);
		reference.traverse(collector, (BlockScope) null);
		if (collector.currentIndexes.isEmpty()) {
			return null;
		}
		int size = collector.currentIndexes.size();
		int[] result = new int[size];
		for (int i = 0; i < size; i++) {
			result[size - i - 1] = ((Integer) collector.currentIndexes.pop()).intValue();
		}
		return result;
	}

	/**
	 * 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_7) {
				this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
				this.codeStream = new TypeAnnotationCodeStream(this);
			} 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) {

		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);
		}
		// 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) {
					attributesNumber += generateRuntimeAnnotations(annotations);
				}
			}
		}

		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();
		}
		// 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;
				List allTypeAnnotationContexts = new ArrayList();
				int invisibleTypeAnnotationsCounter = 0;
				int visibleTypeAnnotationsCounter = 0;
				if (annotations != null) {
					attributesNumber += generateRuntimeAnnotations(annotations);
					if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
						if ((fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
							fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
						}
					}
				}
				TypeReference fieldType = fieldDeclaration.type;
				if (fieldType != null 
						&& ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0)
						&& ((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;
		}
		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);
		}
		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;

		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) {

		// 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);

		// 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
	 */
	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
		SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods();
		if (syntheticMethods != null) {
			for (int i = 0, max = syntheticMethods.length; 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 :
						// 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);
				}
			}
		}
	}

	/**
	 * 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
		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;
	}

	/**
	 * 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());
		// 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) {
			this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
				this.codeStream.methodDeclaration);
		}
		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].count / 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.count;
				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;
					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.isStatic();
			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
		}

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

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

		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 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].count / 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.count;
				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);
		}

		// 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);
		}

		// 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].count / 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.count;
					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) {
			int lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
			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 = ((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];
				LocalDeclaration declaration = localVariable.declaration;
				if (declaration == null
						|| (declaration.isArgument() && ((declaration.bits & ASTNode.CatchVariable) == 0))
						|| (localVariable.initializationCount == 0)
						|| ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
					continue;
				}
				declaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.LOCAL_VARIABLE, localVariable, allTypeAnnotationContexts);
			}
			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_PARAMETER, i, allTypeAnnotationContexts);
							}
						}
					}
					Annotation[] annotations = methodDeclaration.receiverAnnotations;
					if (annotations != null) {
						for (int i = 0, max = annotations.length; i < max; i++) {
							Annotation annotation = annotations[i];
							AnnotationContext annotationContext = null;
							if (annotation.isRuntimeTypeInvisible()) {
								annotationContext = new AnnotationContext(annotation, null, AnnotationTargetTypeConstants.METHOD_RECEIVER, null, AnnotationContext.INVISIBLE, null);
								invisibleTypeAnnotationsCounter++;
							} else if (annotation.isRuntimeTypeVisible()) {
								annotationContext = new AnnotationContext(annotation, null, AnnotationTargetTypeConstants.METHOD_RECEIVER, null, AnnotationContext.VISIBLE, null);
								visibleTypeAnnotationsCounter++;
							}
							if (annotationContext != null) {
								allTypeAnnotationContexts.add(annotationContext);
							}
						}
					}
				}
				Annotation[] annotations = methodDeclaration.annotations;
				if (annotations != null && binding.returnType.id != T_void) {
					methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN_TYPE, 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_TYPE, 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);
			}
		}

		// update the number of attributes
		this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
		this.contents[methodAttributeOffset] = (byte) attributesNumber;
	}

	private void dumpLocations(int[] locations) {
		if (locations != null) {
			int length = locations.length;
			int actualSize = 2 + length;
			if (this.contentsOffset + actualSize >= this.contents.length) {
				resizeContents(actualSize);
			}
			this.contents[this.contentsOffset++] = (byte) (length >> 8);
			this.contents[this.contentsOffset++] = (byte) length;
			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.THROWS :
			case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
			case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.OBJECT_CREATION :
			case AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.CLASS_LITERAL :
			case AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.TYPE_INSTANCEOF :
			case AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.TYPE_CAST :
			case AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY :
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
			case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
			case AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY :
				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_PARAMETER :
			case AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY :
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
			// nothing to do
			// case AnnotationTargetTypeConstants.METHOD_RECEIVER :
			// case AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY :
			//	break;
			// case AnnotationTargetTypeConstants.FIELD :
			// case AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY :
			//	break;
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				break;
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY :
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
				break;
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY :
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY :
				// offset
				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
				// type index
				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
		}
	}

	/**
	 * 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;
		}
		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;
						for (int i = 0, max = fieldDecls.length; 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 (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();
			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()) {
				int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
				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 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.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);
				}
				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
					Argument[] arguments = methodDeclaration.arguments;
					if (arguments != null) {
						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) {
			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;
	}

	/**
	 * 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
	 * @return the number of attributes created while dumping the annotations in the .class file
	 */
	private int generateRuntimeAnnotations(final Annotation[] annotations) {
		int attributesNumber = 0;
		final int length = annotations.length;
		int visibleAnnotationsCounter = 0;
		int invisibleAnnotationsCounter = 0;

		for (int i = 0; i < length; i++) {
			Annotation annotation = annotations[i];
			if (annotation.isRuntimeInvisible()) {
				invisibleAnnotationsCounter++;
			} else if (annotation.isRuntimeVisible()) {
				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 = annotations[i];
				if (annotation.isRuntimeInvisible()) {
					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 = annotations[i];
				if (annotation.isRuntimeVisible()) {
					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 = annotations[j];
					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 = annotations[j];
							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 = annotations[j];
							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;
	}

	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()) {
			ArrayList frames = new ArrayList();
			traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
			int numberOfFrames = frames.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) frames.get(0);
				for (int j = 1; j < numberOfFrames; j++) {
					// select next frame
					currentFrame = (StackMapFrame) frames.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()) {
			ArrayList frames = new ArrayList();
			traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
			int numberOfFrames = frames.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) frames.get(0);
				StackMapFrame prevFrame = null;
				for (int j = 1; j < numberOfFrames; j++) {
					// select next frame
					prevFrame = currentFrame;
					currentFrame = (StackMapFrame) frames.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) {
		int targetType = annotationContext.targetType;
		if (annotationContext.wildcard != null) {
			generateWilcardTypeAnnotation(annotationContext, currentOffset);
			return;
		}
		// common part between type annotation and annotation
		generateAnnotation(annotationContext.annotation, currentOffset);
		if (this.contentsOffset == currentOffset) {
			// error occurred while generating the annotation
			return;
		}
		int[] locations = Annotation.getLocations(
			annotationContext.typeReference,
			annotationContext.primaryAnnotations,
			annotationContext.annotation,
			annotationContext.annotationsOnDimensions);
		if (locations != null) {
			// convert to GENERIC_OR_ARRAY type
			switch(targetType) {
				case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
					targetType = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
					targetType = AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.METHOD_PARAMETER :
					targetType = AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.FIELD :
					targetType = AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY;
					break;
//					case AnnotationTargetTypeConstants.METHOD_RECEIVER :
//					// should not happen - possible extension
//					targetType = AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY;
//					break;
//				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
//					// should not happen - possible extension
//					targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY;
//					break;
				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
					// should not happen - possible extension
					targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
					break;
//				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
//					// should not happen - possible extension
//					targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY;
//					break;
				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
					// should not happen - possible extension
					targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
					break;
//				case AnnotationTargetTypeConstants.THROWS :
//					targetType = AnnotationTargetTypeConstants.THROWS_GENERIC_OR_ARRAY;
				case AnnotationTargetTypeConstants.TYPE_INSTANCEOF:
					targetType = AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.CLASS_LITERAL:
					targetType = AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.OBJECT_CREATION:
					targetType = AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.TYPE_CAST:
					targetType = AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
					targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
					targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY;
					break;
				case AnnotationTargetTypeConstants.METHOD_RETURN_TYPE :
					targetType = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY;
			}
		}
		// reserve enough space
		if (this.contentsOffset + 5 >= this.contents.length) {
			resizeContents(5);
		}
		this.contents[this.contentsOffset++] = (byte) targetType;
		dumpTargetTypeContents(targetType, annotationContext);
		dumpLocations(locations);
	}

	private void generateWilcardTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
		// common part between type annotation and annotation
		generateAnnotation(annotationContext.annotation, currentOffset);
		if (this.contentsOffset == currentOffset) {
			// error occurred while generating the annotation
			return;
		}
		int[] wildcardLocations = getWildcardLocations(annotationContext.typeReference, annotationContext.wildcard);
		int targetType = annotationContext.targetType;
		switch(targetType) {
			case AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS :
				targetType = AnnotationTargetTypeConstants.CLASS_EXTENDS_IMPLEMENTS_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
				targetType = AnnotationTargetTypeConstants.LOCAL_VARIABLE_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.METHOD_PARAMETER :
				targetType = AnnotationTargetTypeConstants.METHOD_PARAMETER_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.FIELD :
				targetType = AnnotationTargetTypeConstants.FIELD_GENERIC_OR_ARRAY;
				break;
//				case AnnotationTargetTypeConstants.METHOD_RECEIVER :
//				// should not happen - possible extension
//				targetType = AnnotationTargetTypeConstants.METHOD_RECEIVER_GENERIC_OR_ARRAY;
//				break;
//			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
//				// should not happen - possible extension
//				targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY;
//				break;
//			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
//				// should not happen - possible extension
//				targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
//				break;
//			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
//				// should not happen - possible extension
//				targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY;
//				break;
//			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
//				// should not happen - possible extension
//				targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY;
//				break;
//			case AnnotationTargetTypeConstants.THROWS :
//				targetType = AnnotationTargetTypeConstants.THROWS_GENERIC_OR_ARRAY;
			case AnnotationTargetTypeConstants.TYPE_INSTANCEOF:
				targetType = AnnotationTargetTypeConstants.TYPE_INSTANCEOF_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.CLASS_LITERAL:
				targetType = AnnotationTargetTypeConstants.CLASS_LITERAL_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.OBJECT_CREATION:
				targetType = AnnotationTargetTypeConstants.OBJECT_CREATION_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.TYPE_CAST:
				targetType = AnnotationTargetTypeConstants.TYPE_CAST_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL :
				targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_METHOD_CALL_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL :
				targetType = AnnotationTargetTypeConstants.TYPE_ARGUMENT_CONSTRUCTOR_CALL_GENERIC_OR_ARRAY;
				break;
			case AnnotationTargetTypeConstants.METHOD_RETURN_TYPE :
				targetType = AnnotationTargetTypeConstants.METHOD_RETURN_TYPE_GENERIC_OR_ARRAY;
		}
		int[] locations = Annotation.getLocations(
				annotationContext.wildcard.bound,
				null,
				annotationContext.annotation,
				null);
		// reserve enough space
		if (this.contentsOffset + 5 >= this.contents.length) {
			resizeContents(5);
		}
		this.contents[this.contentsOffset++] =
			(byte) (locations != null ?
					AnnotationTargetTypeConstants.WILDCARD_BOUND_GENERIC_OR_ARRAY :
					AnnotationTargetTypeConstants.WILDCARD_BOUND);
		this.contents[this.contentsOffset++] = (byte) targetType;
		dumpTargetTypeContents(targetType, annotationContext);
		dumpLocations(wildcardLocations);
		dumpLocations(locations);
	}
	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_IMPLEMENTS, -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_IMPLEMENTS, 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();
			}
		}
	}

	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);

		// 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;
		}
		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 {
			superclassNameIndex =
				(aType.superclass == null ? 0 : this.constantPool.literalIndexForType(aType.superclass));
		}
		this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
		ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
		int interfacesCount = superInterfacesBinding.length;
		this.contents[this.contentsOffset++] = (byte) (interfacesCount >> 8);
		this.contents[this.contentsOffset++] = (byte) interfacesCount;
		for (int i = 0; i < interfacesCount; i++) {
			int interfaceIndex = this.constantPool.literalIndexForType(superInterfacesBinding[i]);
			this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
			this.contents[this.contentsOffset++] = (byte) interfaceIndex;
		}
		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) {
				LocalVariableBinding localVariableBinding = new LocalVariableBinding("this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
				localVariableBinding.resolvedPosition = 0;
				this.codeStream.record(localVariableBinding);
				localVariableBinding.recordInitializationStartPC(0);
				localVariableBinding.recordInitializationEndPC(codeLength);
				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
						VerificationTypeInfo.ITEM_UNINITIALIZED_THIS,
						methodBinding.declaringClass));
				resolvedPosition++;
			} else if (!methodBinding.isStatic()) {
				LocalVariableBinding localVariableBinding = new LocalVariableBinding("this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
				localVariableBinding.resolvedPosition = 0;
				this.codeStream.record(localVariableBinding);
				localVariableBinding.recordInitializationStartPC(0);
				localVariableBinding.recordInitializationEndPC(codeLength);
				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
						VerificationTypeInfo.ITEM_OBJECT,
						methodBinding.declaringClass));
				resolvedPosition++;
			}

			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];
						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());
		ReferenceBinding enclosingType = innerClass.enclosingType();
		while (enclosingType != null
				&& enclosingType.isNestedType()) {
			this.innerClassesBindings.add(enclosingType.erasure());
			enclosingType = enclosingType.enclosingType();
		}
	}

	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_7) {
				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();
		}
		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;
	}

	public void traverse(MethodBinding methodBinding, int maxLocals, byte[] bytecodes, int codeOffset, int codeLength, ArrayList frames, boolean isClinit) {
		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;
		frames.add(frame.duplicate());
		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 {
						// no more frame to generate
						return;
					}
				} 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
				frames.add(currentFrame);
				indexInFramePositions++;
				if (indexInFramePositions < framePositionsLength) {
					currentFramePosition = framePositions[indexInFramePositions];
				} else {
					// no more frame to generate
					return;
				}
			}
			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];
					// special case to handle uninitialized object
					if (locals0 == null) {
						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--;
					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;
					pc += 3;
					break;
				case Opcodes.OPC_goto:
					pc += 3;
					break;
				case Opcodes.OPC_tableswitch:
					pc++;
					while (((pc - codeOffset) & 0x03) != 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;
					pc += (length * 4);
					frame.numberOfStackItems--;
					break;
				case Opcodes.OPC_lookupswitch:
					pc++;
					while (((pc - codeOffset) & 0x03) != 0) {
						pc++;
					}
					pc += 4; // default
					int npairs = (int) u4At(bytecodes, 0, pc);
					pc += (4 + npairs * 8);
					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++;
					break;
				case Opcodes.OPC_return:
					pc++;
					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_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++;
					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--;
					pc += 3;
					break;
				case Opcodes.OPC_goto_w:
					pc += 5;
					break;
				default: // should not occur
					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);
				break;
			}
			if (pc >= (codeLength + codeOffset)) {
				break;
			}
		}
	}

	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));
	}

	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;
	}
}
