package org.eclipse.jdt.internal.compiler;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
/**
 * 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
 */ 

import java.io.*;
import java.util.*;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.problem.*;
import org.eclipse.jdt.internal.compiler.util.*;


public class ClassFile implements AttributeNamesConstants, CompilerModifiers, TypeConstants, TypeIds {
	public SourceTypeBinding referenceBinding;
	public ConstantPool constantPool;
	public ClassFile enclosingClassFile; // used to generate private access methods
	public int produceDebugAttributes;
	public ReferenceBinding[] innerClassesBindings;
	public int numberOfInnerClasses;
	public byte[] header; // the header contains all the bytes till the end of the constant pool
	public byte[] contents; // that collection contains all the remaining bytes of the .class file
	public int headerOffset;
	public int contentsOffset;
	public int constantPoolOffset;
	public int methodCountOffset;
	public int methodCount;
	protected boolean creatingProblemType;
	public static final int INITIAL_CONTENTS_SIZE = 1000;
	public static final int INITIAL_HEADER_SIZE = 1000;
	public static final int INCREMENT_SIZE = 1000;
	public static final int INNER_CLASSES_SIZE = 5;
	protected CharArrayCache nameUsage;
	public CodeStream codeStream;
	protected int problemLine; // used to create line number attributes for problem methods
/**
 * INTERNAL USE-ONLY
 * This methods creates a new instance of the receiver.
 */
public ClassFile() {}
/**
 * INTERNAL USE-ONLY
 * This methods creates a new instance of the receiver.
 *
 * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
 * @param enclosingClassFile org.eclipse.jdt.internal.compiler.ClassFile
 * @param creatingProblemType <CODE>boolean</CODE>
 */
public ClassFile(SourceTypeBinding aType, ClassFile enclosingClassFile, boolean creatingProblemType) {
	referenceBinding = aType;
	header = new byte[INITIAL_HEADER_SIZE];
	// generate the magic numbers inside the header
	header[headerOffset++] = (byte) (0xCAFEBABEL >> 24);
	header[headerOffset++] = (byte) (0xCAFEBABEL >> 16);
	header[headerOffset++] = (byte) (0xCAFEBABEL >> 8);
	header[headerOffset++] = (byte) (0xCAFEBABEL >> 0);
	if (((SourceTypeBinding) referenceBinding).scope.environment().options.targetJDK == CompilerOptions.JDK1_2) {
		// Compatible with JDK 1.2
		header[headerOffset++] = 0; // minorVersion = 0 means we just need to offset the current offset by 2
		header[headerOffset++] = 0;
		header[headerOffset++] = 0;
		header[headerOffset++] = 46;
	} else {
		// Compatible with JDK 1.1
		header[headerOffset++] = 0;
		header[headerOffset++] = 3;
		header[headerOffset++] = 0;
		header[headerOffset++] = 45;
	}
	constantPoolOffset = headerOffset;
	headerOffset += 2;
	constantPool = new ConstantPool(this);
	int accessFlags = aType.getAccessFlags() | AccSuper;
	if (aType.isNestedType()) {
		if (aType.isStatic()) {
			// clear Acc_Static
			accessFlags &= ~AccStatic;
		}
		if (aType.isPrivate()) {
			// clear Acc_Private and Acc_Public
			accessFlags &= ~ (AccPrivate | AccPublic);
		}
		if (aType.isProtected()) {
			// clear Acc_Protected and set Acc_Public
			accessFlags &= ~AccProtected;
			accessFlags |= AccPublic;
		}
	}
	// clear all bits that are illegal for a class or an interface
	accessFlags &= ~(AccStrictfp | AccProtected | AccPrivate | AccStatic | AccSynchronized | AccNative);

	this.enclosingClassFile = enclosingClassFile;
	// innerclasses get their names computed at code gen time
	if (aType.isLocalType()) {
		((LocalTypeBinding) aType).constantPoolName(computeConstantPoolName((LocalTypeBinding) aType));
		ReferenceBinding[] memberTypes = aType.memberTypes();
		for (int i = 0, max = memberTypes.length; i < max; i++) {
			((LocalTypeBinding) memberTypes[i]).constantPoolName(computeConstantPoolName((LocalTypeBinding) memberTypes[i]));
		}
	}
	contents = new byte[INITIAL_CONTENTS_SIZE];
	// now we continue to generate the bytes inside the contents array
	contents[contentsOffset++] = (byte) (accessFlags >> 8);
	contents[contentsOffset++] = (byte) accessFlags;
	int classNameIndex = constantPool.literalIndex(aType);
	contents[contentsOffset++] = (byte) (classNameIndex >> 8);
	contents[contentsOffset++] = (byte) classNameIndex;
	int superclassNameIndex;
	if (aType.isInterface()) {
		superclassNameIndex = constantPool.literalIndexForJavaLangObject();
	} else {
		superclassNameIndex = (aType.superclass == null ? 0 : constantPool.literalIndex(aType.superclass));
	}
	contents[contentsOffset++] = (byte) (superclassNameIndex >> 8);
	contents[contentsOffset++] = (byte) superclassNameIndex;
	ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
	int interfacesCount = superInterfacesBinding.length;
	contents[contentsOffset++] = (byte) (interfacesCount >> 8);
	contents[contentsOffset++] = (byte) interfacesCount;
	if (superInterfacesBinding != null) {
		for (int i = 0; i < interfacesCount; i++) {
			int interfaceIndex = constantPool.literalIndex(superInterfacesBinding[i]);
			contents[contentsOffset++] = (byte) (interfaceIndex >> 8);
			contents[contentsOffset++] = (byte) interfaceIndex;
		}
	}
	produceDebugAttributes = ((SourceTypeBinding) referenceBinding).scope.environment().options.produceDebugAttributes;
	innerClassesBindings = new ReferenceBinding[INNER_CLASSES_SIZE];
	this.creatingProblemType = creatingProblemType;
	codeStream = new CodeStream(this);

	// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
	// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
	ClassFile outermostClassFile = this.outerMostEnclosingClassFile();
	if (this == outermostClassFile) {
		codeStream.maxFieldCount = aType.scope.referenceType().maxFieldCount;
	} else {
		codeStream.maxFieldCount = outermostClassFile.codeStream.maxFieldCount;
	}
}
/**
 * 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
 */
public void addAbstractMethod(
	AbstractMethodDeclaration method,
	MethodBinding methodBinding) {

	// force the modifiers to be public and abstract
	methodBinding.modifiers = AccPublic | AccAbstract;
	
	this.generateMethodInfoHeader(methodBinding);
	int methodAttributeOffset = this.contentsOffset;
	int attributeNumber = this.generateMethodInfoAttribute(methodBinding);
	this.completeMethodInfo(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
	contents[methodCountOffset++] = (byte) (methodCount >> 8);
	contents[methodCountOffset] = (byte) methodCount;
	
	int attributeNumber = 0;
	// leave two bytes for the number of attributes and store the current offset
	int attributeOffset = contentsOffset;
	contentsOffset += 2;

	// source attribute
	if ((produceDebugAttributes & CompilerOptions.Source) != 0) {
		String fullFileName = new String(referenceBinding.scope.referenceCompilationUnit().getFileName());
		fullFileName = fullFileName.replace('\\', '/');
		int lastIndex = fullFileName.lastIndexOf('/');
		if (lastIndex != -1) {
			fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
		}
		// check that there is enough space to write all the bytes for the field info corresponding
		// to the @fieldBinding
		int contentsLength;
		if (contentsOffset + 8 >= (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		int sourceAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SourceName);
		contents[contentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) sourceAttributeNameIndex;
		// The length of a source file attribute is 2. This is a fixed-length
		// attribute
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 2;
		// write the source file name
		int fileNameIndex = constantPool.literalIndex(fullFileName.toCharArray());
		contents[contentsOffset++] = (byte) (fileNameIndex >> 8);
		contents[contentsOffset++] = (byte) fileNameIndex;
		attributeNumber++;
	}

	// Deprecated attribute
	if (referenceBinding.isDeprecated()) {
		// check that there is enough space to write all the bytes for the field info corresponding
		// to the @fieldBinding
		int contentsLength;
		if (contentsOffset + 6 >= (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		int deprecatedAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
		contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
		// the length of a deprecated attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		attributeNumber++;
	}

	// Inner class attribute
	if (numberOfInnerClasses != 0) {
		// Generate the inner class attribute
		int contentsLength;
		int exSize;
		if (contentsOffset + (exSize = (8 * numberOfInnerClasses + 8)) >= (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + (exSize >= INCREMENT_SIZE ? exSize : INCREMENT_SIZE)]), 0, contentsLength);
		}
		// Now we now the size of the attribute and the number of entries
		// attribute name
		int attributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.InnerClassName);
		contents[contentsOffset++] = (byte) (attributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) attributeNameIndex;
		int value = (numberOfInnerClasses << 3) + 2;
		contents[contentsOffset++] = (byte) (value >> 24);
		contents[contentsOffset++] = (byte) (value >> 16);
		contents[contentsOffset++] = (byte) (value >> 8);
		contents[contentsOffset++] = (byte) value;
		contents[contentsOffset++] = (byte) (numberOfInnerClasses >> 8);
		contents[contentsOffset++] = (byte) numberOfInnerClasses;
		for (int i = 0; i < numberOfInnerClasses; i++) {
			ReferenceBinding innerClass = innerClassesBindings[i];
			int accessFlags = innerClass.getAccessFlags();
			int innerClassIndex = constantPool.literalIndex(innerClass);
			// inner class index
			contents[contentsOffset++] = (byte) (innerClassIndex >> 8);
			contents[contentsOffset++] = (byte) innerClassIndex;
			// outer class index: anonymous and local have no outer class index
			if (innerClass.isMemberType()) {
				// member or member of local
				int outerClassIndex = constantPool.literalIndex(innerClass.enclosingType());
				contents[contentsOffset++] = (byte) (outerClassIndex >> 8);
				contents[contentsOffset++] = (byte) outerClassIndex;
			} else {
				// equals to 0 if the innerClass is not a member type
				contents[contentsOffset++] = 0;
				contents[contentsOffset++] = 0;
			}
			// name index
			if (!innerClass.isAnonymousType()) {
				int nameIndex = constantPool.literalIndex(innerClass.sourceName());
				contents[contentsOffset++] = (byte) (nameIndex >> 8);
				contents[contentsOffset++] = (byte) nameIndex;
			} else {
				// equals to 0 if the innerClass is an anonymous type
				contents[contentsOffset++] = 0;
				contents[contentsOffset++] = 0;
			}				
			// access flag
			if (innerClass.isAnonymousType()) {
				accessFlags |= AccPrivate;
			} else
				if (innerClass.isLocalType() && !innerClass.isMemberType()) {
					accessFlags |= AccPrivate;
				}
			contents[contentsOffset++] = (byte) (accessFlags >> 8);
			contents[contentsOffset++] = (byte) accessFlags;
		}
		attributeNumber++;
	}
	// update the number of attributes
	contents[attributeOffset++] = (byte) (attributeNumber >> 8);
	contents[attributeOffset] = (byte) attributeNumber;

	// resynchronize all offsets of the classfile
	header = constantPool.poolContent;
	headerOffset = constantPool.currentOffset;
	int constantPoolCount = constantPool.currentIndex;
	header[constantPoolOffset++] = (byte) (constantPoolCount >> 8);
	header[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 = referenceBinding.getDefaultAbstractMethods();
	for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
		generateMethodInfoHeader(defaultAbstractMethods[i]);
		int methodAttributeOffset = contentsOffset;
		int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
		completeMethodInfo(methodAttributeOffset, attributeNumber);
	}
}
/**
 * INTERNAL USE-ONLY
 * This methods generates the bytes for the field binding passed like a parameter
 * @param fieldBinding org.eclipse.jdt.internal.compiler.lookup.FieldBinding
 */
public void addFieldInfo(FieldBinding fieldBinding) {
	int attributeNumber = 0;
	// check that there is enough space to write all the bytes for the field info corresponding
	// to the @fieldBinding
	int contentsLength;
	if (contentsOffset + 30 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	// Generate two attribute: constantValueAttribute and SyntheticAttribute
	// Now we can generate all entries into the byte array
	// First the accessFlags
	int accessFlags = fieldBinding.getAccessFlags();
	contents[contentsOffset++] = (byte) (accessFlags >> 8);
	contents[contentsOffset++] = (byte) accessFlags;
	// Then the nameIndex
	int nameIndex = constantPool.literalIndex(fieldBinding.name);
	contents[contentsOffset++] = (byte) (nameIndex >> 8);
	contents[contentsOffset++] = (byte) nameIndex;
	// Then the descriptorIndex
	int descriptorIndex = constantPool.literalIndex(fieldBinding.type.signature());
	contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
	contents[contentsOffset++] = (byte) descriptorIndex;
	// leave some space for the number of attributes
	int fieldAttributeOffset = contentsOffset;
	contentsOffset += 2;
	// 4.7.2 only static constant fields get a ConstantAttribute
	if (fieldBinding.isStatic() 
		&& fieldBinding.constant != Constant.NotAConstant 
		&& fieldBinding.constant.typeID() != T_null) {
		// Now we generate the constant attribute corresponding to the fieldBinding
		int constantValueNameIndex = constantPool.literalIndex(AttributeNamesConstants.ConstantValueName);
		contents[contentsOffset++] = (byte) (constantValueNameIndex >> 8);
		contents[contentsOffset++] = (byte) constantValueNameIndex;
		// The attribute length = 2 in case of a constantValue attribute
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 2;
		attributeNumber++;
		// Need to add the constant_value_index
		switch (fieldBinding.constant.typeID()) {
			case T_boolean :
				int booleanValueIndex = constantPool.literalIndex(fieldBinding.constant.booleanValue() ? 1 : 0);
				contents[contentsOffset++] = (byte) (booleanValueIndex >> 8);
				contents[contentsOffset++] = (byte) booleanValueIndex;
				break;
			case T_byte :
			case T_char :
			case T_int :
			case T_short :
				int integerValueIndex = constantPool.literalIndex(fieldBinding.constant.intValue());
				contents[contentsOffset++] = (byte) (integerValueIndex >> 8);
				contents[contentsOffset++] = (byte) integerValueIndex;
				break;
			case T_float :
				int floatValueIndex = constantPool.literalIndex(fieldBinding.constant.floatValue());
				contents[contentsOffset++] = (byte) (floatValueIndex >> 8);
				contents[contentsOffset++] = (byte) floatValueIndex;
				break;
			case T_double :
				int doubleValueIndex = constantPool.literalIndex(fieldBinding.constant.doubleValue());
				contents[contentsOffset++] = (byte) (doubleValueIndex >> 8);
				contents[contentsOffset++] = (byte) doubleValueIndex;
				break;
			case T_long :
				int longValueIndex = constantPool.literalIndex(fieldBinding.constant.longValue());
				contents[contentsOffset++] = (byte) (longValueIndex >> 8);
				contents[contentsOffset++] = (byte) longValueIndex;
				break;
			case T_String :
				int stringValueIndex = constantPool.literalIndex(((StringConstant) fieldBinding.constant).stringValue());
				if (stringValueIndex == -1) {
					if (!creatingProblemType) {
						// report an error and abort: will lead to a problem type classfile creation
						TypeDeclaration typeDeclaration = 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
						contentsOffset = fieldAttributeOffset + 2; // +2 is necessary to keep the two byte space for the attribute number
						attributeNumber--;
					}
				} else {
					contents[contentsOffset++] = (byte) (stringValueIndex >> 8);
					contents[contentsOffset++] = (byte) stringValueIndex;
				}
		}
	}
	if (fieldBinding.isSynthetic()) {
		int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
		contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
		// the length of a synthetic attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		attributeNumber++;
	}
	if (fieldBinding.isDeprecated()) {
		int deprecatedAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
		contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
		// the length of a deprecated attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		attributeNumber++;
	}
	contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8);
	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)
 */
public void addFieldInfos() {
	SourceTypeBinding currentBinding = referenceBinding;
	FieldBinding[] syntheticFields = currentBinding.syntheticFields();
	int fieldCount = currentBinding.fieldCount() + (syntheticFields == null ? 0 : syntheticFields.length);

	// write the number of fields
	contents[contentsOffset++] = (byte) (fieldCount >> 8);
	contents[contentsOffset++] = (byte) fieldCount;

	FieldBinding[] fieldBindings = currentBinding.fields();
	for (int i = 0, max = fieldBindings.length; i < max; i++) {
		addFieldInfo(fieldBindings[i]);
	}
	if (syntheticFields != null) {
		for (int i = 0, max = syntheticFields.length; i < max; i++) {
			addFieldInfo(syntheticFields[i]);
		}
	}
}
/**
 * INTERNAL USE-ONLY
 * This methods stores the bindings for each inner class. They will be used to know which entries
 * have to be generated for the inner classes attributes.
 * @param referenceBinding org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding 
 */
public void addInnerClasses(ReferenceBinding referenceBinding) {
	// check first if that reference binding is there
	for (int i = 0; i < numberOfInnerClasses; i++) {
		if (innerClassesBindings[i] == referenceBinding)
			return;
	}
	int length = innerClassesBindings.length;
	if (numberOfInnerClasses == length) {
		System.arraycopy(innerClassesBindings, 0, (innerClassesBindings = new ReferenceBinding[length * 2]), 0, length);
	}
	innerClassesBindings[numberOfInnerClasses++] = referenceBinding;
}
/**
 * INTERNAL USE-ONLY
 * Generate the byte for a problem clinit method info that correspond to a boggus method.
 *
 * @param problem org.eclipse.jdt.internal.compiler.problem.Problem[]
 */
public void addProblemClinit(IProblem[] problems) {
	generateMethodInfoHeaderForClinit();
	// leave two spaces for the number of attributes
	contentsOffset -= 2;
	int attributeOffset = contentsOffset;
	contentsOffset += 2;
	ReferenceBinding[] thrownsExceptions;
	int attributeNumber = 0;
	int contentsLength;

	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	codeStream.resetForProblemClinit(this);
	String problemString = ""/*nonNLS*/;
	if (problems != null) {
		int max = problems.length;
		StringBuffer buffer = new StringBuffer(25);
		int count = 0;
		for (int i = 0; i < max; i++) {
			IProblem problem = problems[i];
			if ((problem != null) && (problem.isError())) {
				buffer.append("\t"/*nonNLS*/ + problem.getMessage() + "\n"/*nonNLS*/);
				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, Util.bind("compilation.unresolvedProblems"/*nonNLS*/));
		} else {
			buffer.insert(0, Util.bind("compilation.unresolvedProblem"/*nonNLS*/));
		}
		problemString = buffer.toString();
	}

	// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
	int[] exceptionHandler = codeStream.generateCodeAttributeForProblemMethod(referenceBinding.scope.problemReporter().options.runtimeExceptionNameForCompileError, problemString);
	attributeNumber++; // code attribute
	completeCodeAttributeForClinit(
		codeAttributeOffset,
		exceptionHandler,
		referenceBinding
			.scope
			.referenceCompilationUnit()
			.compilationResult
			.lineSeparatorPositions);
	contents[attributeOffset++] = (byte) (attributeNumber >> 8);
	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 problem org.eclipse.jdt.internal.compiler.problem.Problem[]
 */
public void addProblemConstructor(
	AbstractMethodDeclaration method, 
	MethodBinding methodBinding, 
	IProblem[] problems) {

	// always clear the strictfp/native/abstract bit for a problem method
	methodBinding.modifiers &= ~(AccStrictfp | AccNative | AccAbstract);
		
	generateMethodInfoHeader(methodBinding); 
	// We know that we won't get more than 1 attribute: the code attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 1; // Code attribute
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	final ProblemReporter problemReporter = method.scope.problemReporter();
	codeStream.reset(method, this);
	String problemString = ""/*nonNLS*/;
	if (problems != null) {
		int max = problems.length;
		StringBuffer buffer = new StringBuffer(25);
		int count = 0;
		for (int i = 0; i < max; i++) {
			IProblem problem = problems[i];
			if ((problem != null) && (problem.isError())) {
				buffer.append("\t"/*nonNLS*/ + problem.getMessage() + "\n"/*nonNLS*/);
				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, Util.bind("compilation.unresolvedProblems"/*nonNLS*/));
		} else {
			buffer.insert(0, Util.bind("compilation.unresolvedProblem"/*nonNLS*/));
		}
		problemString = buffer.toString();
	}
	
	// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
	int[] exceptionHandler = 
		codeStream.generateCodeAttributeForProblemMethod(
			problemReporter.options.runtimeExceptionNameForCompileError, 
			problemString);
	completeCodeAttributeForProblemMethod(
		method,
		methodBinding, 
		codeAttributeOffset, 
		exceptionHandler, 
		((SourceTypeBinding) methodBinding.declaringClass)
			.scope
			.referenceCompilationUnit()
			.compilationResult
			.lineSeparatorPositions); 
}
/**
 * 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 problem org.eclipse.jdt.internal.compiler.problem.Problem[]
 * @param savedOffset <CODE>int</CODE>
 */
public void addProblemConstructor(AbstractMethodDeclaration method, MethodBinding methodBinding,IProblem[] problems, int savedOffset) {
	// we need to move back the contentsOffset to the value at the beginning of the method
	contentsOffset = savedOffset;
	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 problem org.eclipse.jdt.internal.compiler.problem.Problem[]
 */
public void addProblemMethod(
	AbstractMethodDeclaration method, 
	MethodBinding methodBinding, 
	IProblem[] problems) {
	if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) {
		method.abort(AbstractMethodDeclaration.AbortType);
	}	
	// always clear the strictfp/native/abstract bit for a problem method
	methodBinding.modifiers &= ~(AccStrictfp | AccNative | AccAbstract);
	
	generateMethodInfoHeader(methodBinding);
	// leave two spaces for the number of attributes
	int attributeOffset = contentsOffset;
	contentsOffset += 2;
	ReferenceBinding[] thrownsExceptions;
	int attributeNumber = 0;
	int contentsLength;
	
	if ((thrownsExceptions = methodBinding.thrownExceptions) != NoExceptions) {
		// 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
		int length = thrownsExceptions.length;
		if (contentsOffset + (8 + length * 2) >= (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + Math.max(INCREMENT_SIZE, (8 + length * 2))]), 0, contentsLength);
		}
		int exceptionNameIndex = constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
		contents[contentsOffset++] = (byte) (exceptionNameIndex >> 8);
		contents[contentsOffset++] = (byte) exceptionNameIndex;
		// The attribute length = length * 2 + 2 in case of a exception attribute
		int attributeLength = length * 2 + 2;
		contents[contentsOffset++] = (byte) (attributeLength >> 24);
		contents[contentsOffset++] = (byte) (attributeLength >> 16);
		contents[contentsOffset++] = (byte) (attributeLength >> 8);
		contents[contentsOffset++] = (byte) attributeLength;
		contents[contentsOffset++] = (byte) (length >> 8);
		contents[contentsOffset++] = (byte) length;
		for (int i = 0; i < length; i++) {
			int exceptionIndex = constantPool.literalIndex(thrownsExceptions[i]);
			contents[contentsOffset++] = (byte) (exceptionIndex >> 8);
			contents[contentsOffset++] = (byte) exceptionIndex;
		}
		attributeNumber++;
	}

	// Deprecated attribute
	// Check that there is enough space to write the deprecated attribute
	if (contentsOffset + 6 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	if (methodBinding.isDeprecated()) {
		int deprecatedAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
		contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
		// the length of a deprecated attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;

		attributeNumber++;
	}
	
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	final ProblemReporter problemReporter = method.scope.problemReporter();
	codeStream.reset(method, this);
	String problemString = ""/*nonNLS*/;
	if (problems != null) {
		int max = problems.length;
		StringBuffer buffer = new StringBuffer(25);
		int count = 0;
		for (int i = 0; i < max; i++) {
			IProblem problem = problems[i];
			if ((problem != null)
				&& (problem.isError())
				&& (problem.getSourceStart() >= method.declarationSourceStart)
				&& (problem.getSourceEnd() <= method.declarationSourceEnd)) {
				buffer.append("\t"/*nonNLS*/ + problem.getMessage() + "\n"/*nonNLS*/);
				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, Util.bind("compilation.unresolvedProblems"/*nonNLS*/));
		} else {
			buffer.insert(0, Util.bind("compilation.unresolvedProblem"/*nonNLS*/));
		}
		problemString = buffer.toString();
	}

	// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
	int[] exceptionHandler = 
		codeStream.generateCodeAttributeForProblemMethod(
			problemReporter.options.runtimeExceptionNameForCompileError, 
			problemString);
	attributeNumber++; // code attribute
	completeCodeAttributeForProblemMethod(
		method, 
		methodBinding, 
		codeAttributeOffset, 
		exceptionHandler, 
		((SourceTypeBinding) methodBinding.declaringClass)
			.scope
			.referenceCompilationUnit()
			.compilationResult
			.lineSeparatorPositions);
	contents[attributeOffset++] = (byte) (attributeNumber >> 8);
	contents[attributeOffset] = (byte) attributeNumber;	
}
/**
 * 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 problem org.eclipse.jdt.internal.compiler.problem.Problem[]
 * @param savedOffset <CODE>int</CODE>
 */
public void addProblemMethod(AbstractMethodDeclaration method, MethodBinding methodBinding,IProblem[] problems, int savedOffset) {
	// we need to move back the contentsOffset to the value at the beginning of the method
	contentsOffset = savedOffset;
	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
	SourceTypeBinding currentBinding = referenceBinding;
	MethodBinding[] defaultAbstractMethods = currentBinding.getDefaultAbstractMethods();
	for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
		generateMethodInfoHeader(defaultAbstractMethods[i]);
		int methodAttributeOffset = contentsOffset;
		int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
		completeMethodInfo(methodAttributeOffset, attributeNumber);
	}

	// add synthetic methods infos
	SyntheticAccessMethodBinding[] syntheticAccessMethods = currentBinding.syntheticAccessMethods();
	if (syntheticAccessMethods != null) {
		for (int i = 0, max = syntheticAccessMethods.length; i < max; i++) {
			SyntheticAccessMethodBinding accessMethodBinding = syntheticAccessMethods[i];
			switch (accessMethodBinding.accessType) {
				case SyntheticAccessMethodBinding.FieldReadAccess :
					// generate a method info to emulate an reading access to
					// a private field
					addSyntheticFieldReadAccessMethod(syntheticAccessMethods[i]);
					break;
				case SyntheticAccessMethodBinding.FieldWriteAccess :
					// generate a method info to emulate an writing access to
					// a private field
					addSyntheticFieldWriteAccessMethod(syntheticAccessMethods[i]);
					break;
				case SyntheticAccessMethodBinding.MethodAccess :
					// generate a method info to emulate an access to a private method
					addSyntheticMethodAccessMethod(syntheticAccessMethods[i]);
					break;
				case SyntheticAccessMethodBinding.ConstructorAccess :
					// generate a method info to emulate an access to a private method
					addSyntheticConstructorAccessMethod(syntheticAccessMethods[i]);
			}
		}
	}
}
/**
 * INTERNAL USE-ONLY
 * Generate the byte for a problem method info that correspond to a synthetic method that
 * generate an access to a private constructor.
 *
 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
 */
public void addSyntheticConstructorAccessMethod(SyntheticAccessMethodBinding methodBinding) {
	generateMethodInfoHeader(methodBinding);
	// We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 2;	
	// Code attribute
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	codeStream.init(this);
	codeStream.generateSyntheticBodyForConstructorAccess(methodBinding);
	completeCodeAttributeForSyntheticAccessMethod(methodBinding, codeAttributeOffset, ((SourceTypeBinding) methodBinding.declaringClass).scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions);
	// add the synthetic attribute
	int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
	contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
	contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
	// the length of a synthetic attribute is equals to 0
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
}
/**
 * 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(SyntheticAccessMethodBinding methodBinding) {
	generateMethodInfoHeader(methodBinding);
	// We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 2;
	// Code attribute
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	codeStream.init(this);
	codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding);
	completeCodeAttributeForSyntheticAccessMethod(methodBinding, codeAttributeOffset, ((SourceTypeBinding) methodBinding.declaringClass).scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions);
	// add the synthetic attribute
	int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
	contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
	contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
	// the length of a synthetic attribute is equals to 0
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;	
}
/**
 * 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(SyntheticAccessMethodBinding methodBinding) {
	generateMethodInfoHeader(methodBinding);
	// We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 2;	
	// Code attribute
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	codeStream.init(this);
	codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding);
	completeCodeAttributeForSyntheticAccessMethod(methodBinding, codeAttributeOffset, ((SourceTypeBinding) methodBinding.declaringClass).scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions);
	// add the synthetic attribute
	int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
	contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
	contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
	// the length of a synthetic attribute is equals to 0
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;	
}
/**
 * INTERNAL USE-ONLY
 * Generate the byte for a problem method info that correspond to a synthetic method that
 * generate an access to a private method.
 *
 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
 */
public void addSyntheticMethodAccessMethod(SyntheticAccessMethodBinding methodBinding) {
	generateMethodInfoHeader(methodBinding);
	// We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 2;	
	// Code attribute
	int codeAttributeOffset = contentsOffset;
	generateCodeAttributeHeader();
	codeStream.init(this);
	codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
	completeCodeAttributeForSyntheticAccessMethod(methodBinding, codeAttributeOffset, ((SourceTypeBinding) methodBinding.declaringClass).scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions);
	// add the synthetic attribute
	int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
	contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
	contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
	// the length of a synthetic attribute is equals to 0
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 0;	
}
/**
 * INTERNAL USE-ONLY
 * Build all the directories and subdirectories corresponding to the packages names
 * into the directory specified in parameters.
 *
 * outputPath is formed like:
 *	   c:\temp\ the last character is a file separator
 * relativeFileName is formed like:
 *     java\lang\String.class *
 * 
 * @param outputPath java.lang.String
 * @param relativeFileName java.lang.String
 * @return java.lang.String
 */
public static String buildAllDirectoriesInto(String outputPath, String relativeFileName) throws IOException {
	char fileSeparatorChar = File.separatorChar;
	String fileSeparator = File.separator;
	File f;
	// First we ensure that the outputPath exists
	outputPath = outputPath.replace('/', fileSeparatorChar);
	// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
	if (outputPath.endsWith(fileSeparator)) {
		outputPath = outputPath.substring(0, outputPath.length() - 1);
	}
	f = new File(outputPath);
	if (f.exists()) {
		if (!f.isDirectory()) {
			System.out.println(Util.bind("output.isFile"/*nonNLS*/,f.getAbsolutePath()));
			throw new IOException(Util.bind("output.isFileNotDirectory"/*nonNLS*/));
		}
	} else {
		// we have to create that directory
		if (!f.mkdirs()) {
			System.out.println(Util.bind("output.dirName"/*nonNLS*/,f.getAbsolutePath()));
			throw new IOException(Util.bind("output.notValidAll"/*nonNLS*/));
		}
	}
	StringBuffer outDir = new StringBuffer(outputPath);
	outDir.append(fileSeparator);
	StringTokenizer tokenizer = new StringTokenizer(relativeFileName, fileSeparator);
	String token = tokenizer.nextToken();
	while (tokenizer.hasMoreTokens()) {
		f = new File(outDir.append(token).append(fileSeparator).toString());
		if (f.exists()) {
			// The outDir already exists, so we proceed the next entry
			// System.out.println("outDir: " + outDir + " already exists.");
		} else {
			// Need to add the outDir
			if (!f.mkdir()) {
				System.out.println(Util.bind("output.fileName"/*nonNLS*/,f.getName()));
				throw new IOException(Util.bind("output.notValid"/*nonNLS*/));
			}
		}
		token = tokenizer.nextToken();
	}
	// token contains the last one
	return outDir.append(token).toString();
}
/**
 * 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 codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param codeAttributeOffset <CODE>int</CODE>
 */
public void completeCodeAttribute(int codeAttributeOffset) {
	// reinitialize the localContents with the byte modified by the code stream
	byte[] localContents = contents = codeStream.bCodeStream;
	int localContentsOffset = 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 contentsLength;
	int code_length = codeStream.position;
	if (code_length > 65535) {
		codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(codeStream.methodDeclaration);
	}
	if (localContentsOffset + 20 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	int max_stack = codeStream.stackMax;
	localContents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
	localContents[codeAttributeOffset + 7] = (byte) max_stack;
	int max_locals = codeStream.maxLocals;
	localContents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
	localContents[codeAttributeOffset + 9] = (byte) max_locals;
	localContents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
	localContents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
	localContents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
	localContents[codeAttributeOffset + 13] = (byte) code_length;

	// write the exception table
	int exceptionHandlersNumber = codeStream.exceptionHandlersNumber;
	ExceptionLabel[] exceptionHandlers = codeStream.exceptionHandlers;
	int exSize;
	if (localContentsOffset + (exSize = (exceptionHandlersNumber * 8 + 2)) >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + (exSize > INCREMENT_SIZE ? exSize : INCREMENT_SIZE)]), 0, contentsLength);
	}
	// there is no exception table, so we need to offset by 2 the current offset and move 
	// on the attribute generation
	localContents[localContentsOffset++] = (byte) (exceptionHandlersNumber >> 8);
	localContents[localContentsOffset++] = (byte) exceptionHandlersNumber;
	for (int i = 0; i < exceptionHandlersNumber; i++) {
		ExceptionLabel exceptionHandler = exceptionHandlers[i];
		int start = exceptionHandler.start;
		localContents[localContentsOffset++] = (byte) (start >> 8);
		localContents[localContentsOffset++] = (byte) start;
		int end = exceptionHandler.end;
		localContents[localContentsOffset++] = (byte) (end >> 8);
		localContents[localContentsOffset++] = (byte) end;
		int handlerPC = exceptionHandler.position;
		localContents[localContentsOffset++] = (byte) (handlerPC >> 8);
		localContents[localContentsOffset++] = (byte) handlerPC;
		if (exceptionHandler.exceptionType == null) {
			// any exception handler
			localContents[localContentsOffset++] = 0;
			localContents[localContentsOffset++] = 0;
		} else {
			int nameIndex;
			if (exceptionHandler.exceptionType == TypeBinding.NullBinding) {
				/* represents ClassNotFoundException, see class literal access*/
				nameIndex = constantPool.literalIndexForJavaLangClassNotFoundException();
			} else {
				nameIndex = constantPool.literalIndex(exceptionHandler.exceptionType);
			}
			localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
			localContents[localContentsOffset++] = (byte) nameIndex;
		}
	}

	// debug attributes
	int codeAttributeAttributeOffset = localContentsOffset;
	int attributeNumber = 0;
	// leave two bytes for the attribute_length
	localContentsOffset += 2;

	// first we handle the linenumber attribute
	if (codeStream.generateLineNumberAttributes) {
		/* 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
		 */
		/** OLD CODE
				int[][] pcToSourceMapTable;
		int previousLineNumber;
		int[] flatTable;
		int index;
		int startLineIndexes[] = codeStream.methodDeclaration.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
		int max = startLineIndexes.length;
		*/ 
		int[] pcToSourceMapTable;
		if (((pcToSourceMapTable = codeStream.pcToSourceMap) != null) && (codeStream.pcToSourceMapSize != 0)) {
			int lineNumberNameIndex = constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
			if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
				System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
			}
			localContents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
			localContents[localContentsOffset++] = (byte) lineNumberNameIndex;
			int lineNumberTableOffset = localContentsOffset;
			localContentsOffset += 6; // leave space for attribute_length and line_number_table_length
			/** OLD CODE
			previousLineNumber = 0;

			// Seems like do would be better, but this preserves the existing behavior.

			flatTable = new int[code_length];
			for (int i = codeStream.pcToSourceMapSize - 1; i >= 0; i--) {
				// entry contains the following structure:
				// position 1: startPC
				// position 2: endPC
				// position 3: sourceStart
				// position 4: sourceEnd
				// Compute the line number for a given source position
				index = searchLineNumber(startLineIndexes, pcToSourceMapTable[i][2]);
				for (int j = pcToSourceMapTable[i][0]; j < pcToSourceMapTable[i][1]; j++)
					flatTable[j] = index;
			}
			previousLineNumber = -1;
			
			*/
			int numberOfEntries = 0;
			int length = codeStream.pcToSourceMapSize;
			/** OLD CODE
				int length = flatTable.length;
						for (int i = 0; i < length; i++) {
				if (flatTable[i] != previousLineNumber) {
					previousLineNumber = flatTable[i];
					// write the entry
					if (localContentsOffset + 4 >= (contentsLength = localContents.length)) {
						System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
					}
					localContents[localContentsOffset++] = (byte) (i >> 8);
					localContents[localContentsOffset++] = (byte) i;
					localContents[localContentsOffset++] = (byte) (previousLineNumber >> 8);
					localContents[localContentsOffset++] = (byte) previousLineNumber;
					numberOfEntries++;
				}
			}
			*/			
			for (int i = 0; i < length;) {
				// write the entry
				if (localContentsOffset + 4 >= (contentsLength = localContents.length)) {
					System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
				}
				int pc = pcToSourceMapTable[i++];
				localContents[localContentsOffset++] = (byte) (pc >> 8);
				localContents[localContentsOffset++] = (byte) pc;
				int lineNumber = pcToSourceMapTable[i++];
				localContents[localContentsOffset++] = (byte) (lineNumber >> 8);
				localContents[localContentsOffset++] = (byte) lineNumber;
				numberOfEntries++;
			}
			// now we change the size of the line number attribute
			int lineNumberAttr_length = numberOfEntries * 4 + 2;
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
			localContents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
			localContents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
			localContents[lineNumberTableOffset++] = (byte) numberOfEntries;
			attributeNumber++;
		}
	}



	// then we do the local variable attribute
	if (codeStream.generateLocalVariableTableAttributes) {
		int localVariableTableOffset = localContentsOffset;
		int numberOfEntries = 0;
		int localVariableNameIndex = constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
		if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
			System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		localContents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
		localContents[localContentsOffset++] = (byte) localVariableNameIndex;
		localContentsOffset += 6; // leave space for attribute_length and local_variable_table_length
		int nameIndex;
		int descriptorIndex;
		if (!codeStream.methodDeclaration.isStatic()) {
			numberOfEntries++;
			if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
				System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
			}
			localContentsOffset += 2; // the startPC for this is always 0
			localContents[localContentsOffset++] = (byte) (code_length >> 8);
			localContents[localContentsOffset++] = (byte) code_length;
			nameIndex = constantPool.literalIndex(QualifiedNamesConstants.This);
			localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
			localContents[localContentsOffset++] = (byte) nameIndex;
			descriptorIndex = constantPool.literalIndex(codeStream.methodDeclaration.binding.declaringClass.signature());
			localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
			localContents[localContentsOffset++] = (byte) descriptorIndex;
			localContentsOffset += 2; // the resolved position for this is always 0
		}
		for (int i = 0; i < codeStream.allLocalsCounter; i++) {
			LocalVariableBinding localVariable = codeStream.locals[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
					int currentLength;
					if (endPC == -1) {
						localVariable.declaringScope.problemReporter().abortDueToInternalError(Util.bind("abort.invalidAttribute"/*nonNLS*/,new String(localVariable.name)), (AstNode) localVariable.declaringScope.methodScope().referenceContext);
					}
					if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
						System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
					}
					// now we can safely add the local entry
					numberOfEntries++;
					localContents[localContentsOffset++] = (byte) (startPC >> 8);
					localContents[localContentsOffset++] = (byte) startPC;
					int length = endPC - startPC;
					localContents[localContentsOffset++] = (byte) (length >> 8);
					localContents[localContentsOffset++] = (byte) length;
					nameIndex = constantPool.literalIndex(localVariable.name);
					localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
					localContents[localContentsOffset++] = (byte) nameIndex;
					descriptorIndex = constantPool.literalIndex(localVariable.type.signature());
					localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
					localContents[localContentsOffset++] = (byte) descriptorIndex;
					int resolvedPosition = localVariable.resolvedPosition;
					localContents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
					localContents[localContentsOffset++] = (byte) resolvedPosition;
				}
			}
		}
		int value = numberOfEntries * 10 + 2;
		localVariableTableOffset += 2;
		localContents[localVariableTableOffset++] = (byte) (value >> 24);
		localContents[localVariableTableOffset++] = (byte) (value >> 16);
		localContents[localVariableTableOffset++] = (byte) (value >> 8);
		localContents[localVariableTableOffset++] = (byte) value;
		localContents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
		localContents[localVariableTableOffset] = (byte) numberOfEntries;
		attributeNumber++;
	}
	// update the number of attributes
	// ensure first that there is enough space available inside the localContents array
	if (codeAttributeAttributeOffset + 2 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	localContents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
	localContents[codeAttributeAttributeOffset] = (byte) attributeNumber;

	// update the attribute length
	int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
	localContents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
	localContents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
	localContents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
	localContents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	contentsOffset = localContentsOffset;
}
/**
 * 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 codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param codeAttributeOffset <CODE>int</CODE>
 */
public void completeCodeAttributeForClinit(int codeAttributeOffset) {
	// reinitialize the contents with the byte modified by the code stream
	byte[] localContents = contents = codeStream.bCodeStream;
	int localContentsOffset = 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 contentsLength;
	int code_length = codeStream.position;
	if (code_length > 65535) {
		codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(codeStream.methodDeclaration.scope.referenceType());
	}
	if (localContentsOffset + 20 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	int max_stack = codeStream.stackMax;
	localContents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
	localContents[codeAttributeOffset + 7] = (byte) max_stack;
	int max_locals = codeStream.maxLocals;
	localContents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
	localContents[codeAttributeOffset + 9] = (byte) max_locals;
	localContents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
	localContents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
	localContents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
	localContents[codeAttributeOffset + 13] = (byte) code_length;

	// write the exception table
	int exceptionHandlersNumber = codeStream.exceptionHandlersNumber;
	ExceptionLabel[] exceptionHandlers = codeStream.exceptionHandlers;
	int exSize;
	if (localContentsOffset + (exSize = (exceptionHandlersNumber * 8 + 2)) >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + (exSize > INCREMENT_SIZE ? exSize : INCREMENT_SIZE)]), 0, contentsLength);
	}
	// there is no exception table, so we need to offset by 2 the current offset and move 
	// on the attribute generation
	localContents[localContentsOffset++] = (byte) (exceptionHandlersNumber >> 8);
	localContents[localContentsOffset++] = (byte) exceptionHandlersNumber;
	for (int i = 0; i < exceptionHandlersNumber; i++) {
		ExceptionLabel exceptionHandler = exceptionHandlers[i];
		int start = exceptionHandler.start;
		localContents[localContentsOffset++] = (byte) (start >> 8);
		localContents[localContentsOffset++] = (byte) start;
		int end = exceptionHandler.end;
		localContents[localContentsOffset++] = (byte) (end >> 8);
		localContents[localContentsOffset++] = (byte) end;
		int handlerPC = exceptionHandler.position;
		localContents[localContentsOffset++] = (byte) (handlerPC >> 8);
		localContents[localContentsOffset++] = (byte) handlerPC;
		if (exceptionHandler.exceptionType == null) {
			// any exception handler
			localContentsOffset += 2;
		} else {
			int nameIndex;
			if (exceptionHandler.exceptionType == TypeBinding.NullBinding) {
				/* represents denote ClassNotFoundException, see class literal access*/
				nameIndex = constantPool.literalIndexForJavaLangClassNotFoundException();
			} else {
				nameIndex = constantPool.literalIndex(exceptionHandler.exceptionType);
			}
			localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
			localContents[localContentsOffset++] = (byte) nameIndex;
		}
	}

	// debug attributes
	int codeAttributeAttributeOffset = localContentsOffset;
	int attributeNumber = 0;
	// leave two bytes for the attribute_length
	localContentsOffset += 2;

	// first we handle the linenumber attribute
	if (codeStream.generateLineNumberAttributes) {
		/* 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 = codeStream.pcToSourceMap) != null) && (codeStream.pcToSourceMapSize != 0)) {
			int lineNumberNameIndex = constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
			if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
				System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
			}
			localContents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
			localContents[localContentsOffset++] = (byte) lineNumberNameIndex;
			int lineNumberTableOffset = localContentsOffset;
			localContentsOffset += 6; // leave space for attribute_length and line_number_table_length
			int numberOfEntries = 0;
			int length = codeStream.pcToSourceMapSize;
			for (int i = 0; i < length;) {
				// write the entry
				if (localContentsOffset + 4 >= (contentsLength = localContents.length)) {
					System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
				}
				int pc = pcToSourceMapTable[i++];
				localContents[localContentsOffset++] = (byte) (pc >> 8);
				localContents[localContentsOffset++] = (byte) pc;
				int lineNumber = pcToSourceMapTable[i++];
				localContents[localContentsOffset++] = (byte) (lineNumber >> 8);
				localContents[localContentsOffset++] = (byte) lineNumber;
				numberOfEntries++;
			}
			// now we change the size of the line number attribute
			int lineNumberAttr_length = numberOfEntries * 4 + 2;
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
			localContents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
			localContents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
			localContents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
			localContents[lineNumberTableOffset++] = (byte) numberOfEntries;
			attributeNumber++;
		}
	}



	// then we do the local variable attribute
	if (codeStream.generateLocalVariableTableAttributes) {
		int localVariableTableOffset = localContentsOffset;
		int numberOfEntries = 0;
		//		codeAttribute.addLocalVariableTableAttribute(this);
		if ((codeStream.pcToSourceMap != null) && (codeStream.pcToSourceMapSize != 0)) {
			int localVariableNameIndex = constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
			if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
				System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
			}
			localContents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
			localContents[localContentsOffset++] = (byte) localVariableNameIndex;
			localContentsOffset += 6; // leave space for attribute_length and local_variable_table_length
			int nameIndex;
			int descriptorIndex;
			for (int i = 0; i < codeStream.allLocalsCounter; i++) {
				LocalVariableBinding localVariable = codeStream.locals[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
						int currentLength;
						if (endPC == -1) {
							localVariable.declaringScope.problemReporter().abortDueToInternalError(Util.bind("abort.invalidAttribute"/*nonNLS*/,new String(localVariable.name)), (AstNode) localVariable.declaringScope.methodScope().referenceContext);
						}
						if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
							System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
						}
						// now we can safely add the local entry
						numberOfEntries++;
						localContents[localContentsOffset++] = (byte) (startPC >> 8);
						localContents[localContentsOffset++] = (byte) startPC;
						int length = endPC - startPC;
						localContents[localContentsOffset++] = (byte) (length >> 8);
						localContents[localContentsOffset++] = (byte) length;
						nameIndex = constantPool.literalIndex(localVariable.name);
						localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
						localContents[localContentsOffset++] = (byte) nameIndex;
						descriptorIndex = constantPool.literalIndex(localVariable.type.signature());
						localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
						localContents[localContentsOffset++] = (byte) descriptorIndex;
						int resolvedPosition = localVariable.resolvedPosition;
						localContents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
						localContents[localContentsOffset++] = (byte) resolvedPosition;
					}
				}
			}
			int value = numberOfEntries * 10 + 2;
			localVariableTableOffset += 2;
			localContents[localVariableTableOffset++] = (byte) (value >> 24);
			localContents[localVariableTableOffset++] = (byte) (value >> 16);
			localContents[localVariableTableOffset++] = (byte) (value >> 8);
			localContents[localVariableTableOffset++] = (byte) value;
			localContents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
			localContents[localVariableTableOffset] = (byte) numberOfEntries;
			attributeNumber++;
		}
	}
	// update the number of attributes
	// ensure first that there is enough space available inside the contents array
	if (codeAttributeAttributeOffset + 2 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	localContents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
	localContents[codeAttributeAttributeOffset] = (byte) attributeNumber;
	// update the attribute length
	int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
	localContents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
	localContents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
	localContents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
	localContents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	contentsOffset = localContentsOffset;
}
/**
 * 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 codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param codeAttributeOffset <CODE>int</CODE>
 * @param exceptionHandler int[]
 * @param startIndexes int[]
 */
public void completeCodeAttributeForClinit(int codeAttributeOffset, int[] exceptionHandler, int[] startLineIndexes) {
	// reinitialize the contents with the byte modified by the code stream
	byte[] localContents = contents = codeStream.bCodeStream;
	int localContentsOffset = 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 contentsLength;
	int code_length = codeStream.position;
	if (code_length > 65535) {
		codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(codeStream.methodDeclaration.scope.referenceType());
	}
	if (localContentsOffset + 20 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	int max_stack = codeStream.stackMax;
	localContents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
	localContents[codeAttributeOffset + 7] = (byte) max_stack;
	int max_locals = codeStream.maxLocals;
	localContents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
	localContents[codeAttributeOffset + 9] = (byte) max_locals;
	localContents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
	localContents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
	localContents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
	localContents[codeAttributeOffset + 13] = (byte) code_length;

	// write the exception table
	localContents[localContentsOffset++] = 0;
	localContents[localContentsOffset++] = 1;
	int start = exceptionHandler[0];
	localContents[localContentsOffset++] = (byte) (start >> 8);
	localContents[localContentsOffset++] = (byte) start;
	int end = exceptionHandler[1];
	localContents[localContentsOffset++] = (byte) (end >> 8);
	localContents[localContentsOffset++] = (byte) end;
	int handlerPC = exceptionHandler[2];
	localContents[localContentsOffset++] = (byte) (handlerPC >> 8);
	localContents[localContentsOffset++] = (byte) handlerPC;
	int nameIndex = constantPool.literalIndexForJavaLangException();
	localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
	localContents[localContentsOffset++] = (byte) nameIndex;
	
	// debug attributes
	int codeAttributeAttributeOffset = localContentsOffset;
	int attributeNumber = 0; // leave two bytes for the attribute_length
	localContentsOffset += 2; // first we handle the linenumber attribute

	// first we handle the linenumber attribute
	if (codeStream.generateLineNumberAttributes) {
		/* 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 index = 0, max = startLineIndexes.length;
		int lineNumberNameIndex = constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
		localContents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
		localContents[localContentsOffset++] = (byte) lineNumberNameIndex;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 6;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 1;
		// first entry at pc = 0
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = (byte) (problemLine >> 8);
		localContents[localContentsOffset++] = (byte) problemLine;
		// now we change the size of the line number attribute
		attributeNumber++;
	}

	// then we do the local variable attribute
	if (codeStream.generateLocalVariableTableAttributes) {
		int localVariableNameIndex = constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
		if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
			System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		localContents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
		localContents[localContentsOffset++] = (byte) localVariableNameIndex;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 2;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		attributeNumber++;
	}
	
	// update the number of attributes
	// ensure first that there is enough space available inside the contents array
	if (codeAttributeAttributeOffset + 2 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	localContents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
	localContents[codeAttributeAttributeOffset] = (byte) attributeNumber;
	// update the attribute length
	int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
	localContents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
	localContents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
	localContents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
	localContents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	contentsOffset = localContentsOffset;
}
/**
 * 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 codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param codeAttributeOffset <CODE>int</CODE>
 * @param exceptionHandler int[] 
 */
public void completeCodeAttributeForProblemMethod(AbstractMethodDeclaration method, MethodBinding binding, int codeAttributeOffset, int[] exceptionHandler, int[] startLineIndexes) {
	// reinitialize the localContents with the byte modified by the code stream
	byte[] localContents = contents = codeStream.bCodeStream;
	int localContentsOffset = 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 = codeStream.stackMax;
	localContents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
	localContents[codeAttributeOffset + 7] = (byte) max_stack;
	int max_locals = codeStream.maxLocals;
	localContents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
	localContents[codeAttributeOffset + 9] = (byte) max_locals;
	int code_length = codeStream.position;
	localContents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
	localContents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
	localContents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
	localContents[codeAttributeOffset + 13] = (byte) code_length;
	// write the exception table
	int contentsLength;
	if (localContentsOffset + 50 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	localContents[localContentsOffset++] = 0;
	localContents[localContentsOffset++] = 1;
	int start = exceptionHandler[0];
	localContents[localContentsOffset++] = (byte) (start >> 8);
	localContents[localContentsOffset++] = (byte) start;
	int end = exceptionHandler[1];
	localContents[localContentsOffset++] = (byte) (end >> 8);
	localContents[localContentsOffset++] = (byte) end;
	int handlerPC = exceptionHandler[2];
	localContents[localContentsOffset++] = (byte) (handlerPC >> 8);
	localContents[localContentsOffset++] = (byte) handlerPC;
	int nameIndex = constantPool.literalIndexForJavaLangException();
	localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
	localContents[localContentsOffset++] = (byte) nameIndex; // debug attributes
	int codeAttributeAttributeOffset = localContentsOffset;
	int attributeNumber = 0; // leave two bytes for the attribute_length
	localContentsOffset += 2; // first we handle the linenumber attribute

	if (codeStream.generateLineNumberAttributes) {
		/* 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 = constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
		localContents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
		localContents[localContentsOffset++] = (byte) lineNumberNameIndex;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 6;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 1;
		if (problemLine == 0) {
			problemLine = searchLineNumber(startLineIndexes, binding.sourceStart());
		}
		// first entry at pc = 0
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = 0;
		localContents[localContentsOffset++] = (byte) (problemLine >> 8);
		localContents[localContentsOffset++] = (byte) problemLine;
		// now we change the size of the line number attribute
		attributeNumber++;
	}

	// then we do the local variable attribute
	if (codeStream.generateLocalVariableTableAttributes) {
		// compute the resolved position for the arguments of the method
		int argSize;
		int localVariableTableOffset = localContentsOffset;
		int numberOfEntries = 0;
		//		codeAttribute.addLocalVariableTableAttribute(this);
		int localVariableNameIndex = constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
		if (localContentsOffset + 8 >= (contentsLength = localContents.length)) {
			System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		localContents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
		localContents[localContentsOffset++] = (byte) localVariableNameIndex;
		localContentsOffset += 6; // leave space for attribute_length and local_variable_table_length
		int descriptorIndex;
		if (!codeStream.methodDeclaration.isStatic()) {
			numberOfEntries++;
			if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
				System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
			}
			localContents[localContentsOffset++] = 0;
			localContents[localContentsOffset++] = 0;
			localContents[localContentsOffset++] = (byte) (code_length >> 8);
			localContents[localContentsOffset++] = (byte) code_length;
			nameIndex = constantPool.literalIndex(QualifiedNamesConstants.This);
			localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
			localContents[localContentsOffset++] = (byte) nameIndex;
			descriptorIndex = constantPool.literalIndex(codeStream.methodDeclaration.binding.declaringClass.signature());
			localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
			localContents[localContentsOffset++] = (byte) descriptorIndex;
			// the resolved position for this is always 0
			localContents[localContentsOffset++] = 0;
			localContents[localContentsOffset++] = 0;
		}
		if (binding.isConstructor()) {
			ReferenceBinding declaringClass = binding.declaringClass;
			if (declaringClass.isNestedType()) {
				NestedTypeBinding methodDeclaringClass = (NestedTypeBinding) declaringClass;
				argSize = methodDeclaringClass.syntheticArgumentsOffset;
				SyntheticArgumentBinding[] syntheticArguments;
				if ((syntheticArguments = methodDeclaringClass.syntheticEnclosingInstances()) != null) {
					for (int i = 0, max = syntheticArguments.length; i < max; i++) {
						LocalVariableBinding localVariable = syntheticArguments[i];
						int currentLength;
						if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
							System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
						}
						// now we can safely add the local entry
						numberOfEntries++;
						localContents[localContentsOffset++] = 0;
						localContents[localContentsOffset++] = 0;
						localContents[localContentsOffset++] = (byte) (code_length >> 8);
						localContents[localContentsOffset++] = (byte) code_length;
						nameIndex = constantPool.literalIndex(localVariable.name);
						localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
						localContents[localContentsOffset++] = (byte) nameIndex;
						descriptorIndex = constantPool.literalIndex(localVariable.type.signature());
						localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
						localContents[localContentsOffset++] = (byte) descriptorIndex;
						int resolvedPosition = localVariable.resolvedPosition;
						localContents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
						localContents[localContentsOffset++] = (byte) resolvedPosition;
					}
				}
			} else {
				argSize = 1;
			}
		} else {
			argSize = binding.isStatic() ? 0 : 1;
		}
		if (method.binding != null) {
			TypeBinding[] parameters = method.binding.parameters;
			Argument[] arguments = method.arguments;
			if ((parameters != null) && (arguments != null)) {
				for (int i = 0, max = parameters.length; i < max; i++) {
					TypeBinding argumentBinding = parameters[i];
					int currentLength;
					if (localContentsOffset + 10 >= (contentsLength = localContents.length)) {
						System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
					}
					// now we can safely add the local entry
					numberOfEntries++;
					localContents[localContentsOffset++] = 0;
					localContents[localContentsOffset++] = 0;
					localContents[localContentsOffset++] = (byte) (code_length >> 8);
					localContents[localContentsOffset++] = (byte) code_length;
					nameIndex = constantPool.literalIndex(arguments[i].name);
					localContents[localContentsOffset++] = (byte) (nameIndex >> 8);
					localContents[localContentsOffset++] = (byte) nameIndex;
					descriptorIndex = constantPool.literalIndex(argumentBinding.signature());
					localContents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
					localContents[localContentsOffset++] = (byte) descriptorIndex;
					int resolvedPosition = argSize;
					if ((argumentBinding == TypeBinding.LongBinding) || (argumentBinding == TypeBinding.DoubleBinding))
						argSize += 2;
					else
						argSize++;
					localContents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
					localContents[localContentsOffset++] = (byte) resolvedPosition;
				}
			}
		}
		int value = numberOfEntries * 10 + 2;
		localVariableTableOffset += 2;
		localContents[localVariableTableOffset++] = (byte) (value >> 24);
		localContents[localVariableTableOffset++] = (byte) (value >> 16);
		localContents[localVariableTableOffset++] = (byte) (value >> 8);
		localContents[localVariableTableOffset++] = (byte) value;
		localContents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
		localContents[localVariableTableOffset] = (byte) numberOfEntries;
		attributeNumber++;
	}

	// update the number of attributes// ensure first that there is enough space available inside the localContents array
	if (codeAttributeAttributeOffset + 2 >= (contentsLength = localContents.length)) {
		System.arraycopy(contents, 0, (localContents = contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	localContents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
	localContents[codeAttributeAttributeOffset] = (byte) attributeNumber;
	// update the attribute length
	int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
	localContents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
	localContents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
	localContents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
	localContents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	contentsOffset = localContentsOffset;
}
/**
 * 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 codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param codeAttributeOffset <CODE>int</CODE>
 */
public void completeCodeAttributeForSyntheticAccessMethod(SyntheticAccessMethodBinding binding, int codeAttributeOffset, int[] startLineIndexes) {
	// reinitialize the contents with the byte modified by the code stream
	contents = codeStream.bCodeStream;
	int localContentsOffset = 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 = codeStream.stackMax;
	contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
	contents[codeAttributeOffset + 7] = (byte) max_stack;
	int max_locals = codeStream.maxLocals;
	contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
	contents[codeAttributeOffset + 9] = (byte) max_locals;
	int code_length = codeStream.position;
	contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
	contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
	contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
	contents[codeAttributeOffset + 13] = (byte) code_length;
	int contentsLength;
	if ((localContentsOffset + 40) >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	// there is no exception table, so we need to offset by 2 the current offset and move 
	// on the attribute generation
	localContentsOffset += 2;
	// debug attributes
	int codeAttributeAttributeOffset = localContentsOffset;
	int attributeNumber = 0;
	// leave two bytes for the attribute_length
	localContentsOffset += 2;

	// first we handle the linenumber attribute
	if (codeStream.generateLineNumberAttributes) {
		int index = 0, max = startLineIndexes.length;
		int lineNumberNameIndex = constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
		contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
		contents[localContentsOffset++] = (byte) lineNumberNameIndex;
		int lineNumberTableOffset = localContentsOffset;
		localContentsOffset += 6; // leave space for attribute_length and line_number_table_length
		// Seems like do would be better, but this preserves the existing behavior.
		index = searchLineNumber(startLineIndexes, binding.sourceStart);
		contents[localContentsOffset++] = 0;
		contents[localContentsOffset++] = 0;
		contents[localContentsOffset++] = (byte) (index >> 8);
		contents[localContentsOffset++] = (byte) index;
		// now we change the size of the line number attribute
		contents[lineNumberTableOffset++] = 0;
		contents[lineNumberTableOffset++] = 0;
		contents[lineNumberTableOffset++] = 0;
		contents[lineNumberTableOffset++] = 6;
		contents[lineNumberTableOffset++] = 0;
		contents[lineNumberTableOffset++] = 1;
		attributeNumber++;
	}

	// then we do the local variable attribute
	if (codeStream.generateLocalVariableTableAttributes) {
		int localVariableTableOffset = localContentsOffset;
		int numberOfEntries = 0;
		int localVariableNameIndex = constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
		if (localContentsOffset + 8 > (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
		}
		contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
		contents[localContentsOffset++] = (byte) localVariableNameIndex;
		localContentsOffset += 6; // leave space for attribute_length and local_variable_table_length
		int nameIndex;
		int descriptorIndex;
		for (int i = 0; i < codeStream.allLocalsCounter; i++) {
			LocalVariableBinding localVariable = codeStream.locals[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
					int currentLength;
					if (endPC == -1) {
						localVariable.declaringScope.problemReporter().abortDueToInternalError(Util.bind("abort.invalidAttribute"/*nonNLS*/,new String(localVariable.name)), (AstNode) localVariable.declaringScope.methodScope().referenceContext);
					}
					if (localContentsOffset + 10 > (contentsLength = contents.length)) {
						System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
					}
					// now we can safely add the local entry
					numberOfEntries++;
					contents[localContentsOffset++] = (byte) (startPC >> 8);
					contents[localContentsOffset++] = (byte) startPC;
					int length = endPC - startPC;
					contents[localContentsOffset++] = (byte) (length >> 8);
					contents[localContentsOffset++] = (byte) length;
					nameIndex = constantPool.literalIndex(localVariable.name);
					contents[localContentsOffset++] = (byte) (nameIndex >> 8);
					contents[localContentsOffset++] = (byte) nameIndex;
					descriptorIndex = constantPool.literalIndex(localVariable.type.signature());
					contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
					contents[localContentsOffset++] = (byte) descriptorIndex;
					int resolvedPosition = localVariable.resolvedPosition;
					contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
					contents[localContentsOffset++] = (byte) resolvedPosition;
				}
			}
		}
		int value = numberOfEntries * 10 + 2;
		localVariableTableOffset += 2;
		contents[localVariableTableOffset++] = (byte) (value >> 24);
		contents[localVariableTableOffset++] = (byte) (value >> 16);
		contents[localVariableTableOffset++] = (byte) (value >> 8);
		contents[localVariableTableOffset++] = (byte) value;
		contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
		contents[localVariableTableOffset] = (byte) numberOfEntries;
		attributeNumber++;
	}

	// update the number of attributes
	// ensure first that there is enough space available inside the contents array
	if (codeAttributeAttributeOffset + 2 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
	contents[codeAttributeAttributeOffset] = (byte) attributeNumber;

	// update the attribute length
	int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
	contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
	contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
	contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
	contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
	contentsOffset = localContentsOffset;
}
/**
 * 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 attributeNumber <CODE>int</CODE> 
 */
public void completeMethodInfo(int methodAttributeOffset, int attributeNumber) {
	// update the number of attributes
	contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
	contents[methodAttributeOffset] = (byte) attributeNumber;
}
/*
 * INTERNAL USE-ONLY
 * Innerclasses get their name computed as they are generated, since some may not
 * be actually outputed if sitting inside unreachable code.
 *
 * @param localType org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding
 */
public char[] computeConstantPoolName(LocalTypeBinding localType) {
	if (localType.constantPoolName() != null) {
		return localType.constantPoolName();
	}

	// delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes.
	if (enclosingClassFile != null) {
		return this.outerMostEnclosingClassFile().computeConstantPoolName(localType);
	}

	if (nameUsage == null) {
		nameUsage = new CharArrayCache();
	}
	if (localType.isMemberType()) { // catches member types of local types
		return CharOperation.concat(
			localType.enclosingType().constantPoolName(),
			localType.sourceName,
			'$');
	} else {
		char[][] compoundName =  (char[][]) referenceBinding.compoundName.clone();
		int last = compoundName.length - 1;
		StringBuffer nameBuffer = new StringBuffer().append(compoundName[last]);
		// retrieve the number of use of the combination
		char[] simpleName = localType.sourceName;
		//if (simpleName == null) simpleName = new char[]{}; // for anonymous
		int nameCount = nameUsage.get(simpleName); // -1 if not found
		nameCount =  nameCount == -1 ? 1 : nameCount + 1;
		nameBuffer.append('$').append(nameCount);
		nameUsage.put(simpleName, nameCount);
		if (!localType.isAnonymousType()) { // named local type
			nameBuffer.append('$').append(simpleName);
		}
		compoundName[last] = nameBuffer.toString().toCharArray();
		return CharOperation.concatWith(compoundName, '/');
	}
}
/**
 * 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 = new ClassFile(typeBinding, null, true);

	// inner attributes
	if (typeBinding.isMemberType())
		classFile.recordEnclosingTypeAttributes(typeBinding);

	// add its fields
	FieldBinding[] fields = typeBinding.fields;
	if ((fields != null) && (fields != NoFields)) {
		for (int i = 0, max = fields.length; i < max; i++) {
			if (fields[i].constant == null) {
				FieldReference.getConstantFor(fields[i], false, null, 0);
			}
		}
		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
	MethodBinding[] methods = typeBinding.methods;
	AbstractMethodDeclaration[] methodDeclarations = typeDeclaration.methods;
	int maxMethodDecl = methodDeclarations == null ? 0 : methodDeclarations.length;
	int problemsLength;
	IProblem[] problems = unitResult.getProblems();
	if (problems == null) {
		problems = new IProblem[0];
	}
	IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
	System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
	if (methods != 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, max = methods.length; i < max; i++) {
				MethodBinding methodBinding;
				if ((methodBinding = methods[i]) != null) {
					// find the corresponding method declaration
					for (int j = 0; j < maxMethodDecl; j++) {
						if ((methodDeclarations[j] != null) && (methodDeclarations[j].binding == methods[i])) {
							if (!methodBinding.isConstructor()) {
								classFile.addAbstractMethod(methodDeclarations[j], methodBinding);
							}
							break;
						}
					}
				}
			}			
		} else {
			for (int i = 0, max = methods.length; i < max; i++) {
				MethodBinding methodBinding;
				if ((methodBinding = methods[i]) != null) {
					// find the corresponding method declaration
					for (int j = 0; j < maxMethodDecl; j++) {
						if ((methodDeclarations[j] != null) && (methodDeclarations[j].binding == methods[i])) {
							AbstractMethodDeclaration methodDecl;
							if ((methodDecl = methodDeclarations[j]).isConstructor()) {
								classFile.addProblemConstructor(methodDecl, methodBinding, problemsCopy);
							} else {
								classFile.addProblemMethod(methodDecl, methodBinding, problemsCopy);
							}
							break;
						}
					}
				}
			}
		}
		// add abstract methods
		classFile.addDefaultAbstractMethods();
	}
	// propagate generation of (problem) member types
	if (typeDeclaration.memberTypes != null) {
		CompilationResult result = typeDeclaration.scope.referenceCompilationUnit().compilationResult;
		for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
			TypeDeclaration memberType = typeDeclaration.memberTypes[i];
			if (memberType.binding != null) {
				classFile.recordNestedMemberAttribute(memberType.binding);
				ClassFile.createProblemType(memberType, unitResult);
			}
		}
	}
	classFile.addAttributes();
	unitResult.record(typeBinding.constantPoolName(), classFile);
}
/**
 * INTERNAL USE-ONLY
 * This methods returns a char[] representing the file name of the receiver
 *
 * @return char[]
 */
public char[] fileName() {
	return constantPool.UTF8Cache.returnKeyFor(1);
}
/**
 * INTERNAL USE-ONLY
 * That method generates the header of a code attribute.
 * - the index inside the constant pool for the attribute name (i.e. Code)
 * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4).
 */
public void generateCodeAttributeHeader() {
	int contentsLength;
	if (contentsOffset + 20 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	int constantValueNameIndex = constantPool.literalIndex(AttributeNamesConstants.CodeName);
	contents[contentsOffset++] = (byte) (constantValueNameIndex >> 8);
	contents[contentsOffset++] = (byte) constantValueNameIndex;
	// leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4)
	contentsOffset += 12;
}
/**
 * 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 generateMethodInfoAttribute(MethodBinding methodBinding) {
	// leave two bytes for the attribute_number
	contentsOffset += 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 contentsLength;
	int attributeNumber = 0;
	if ((thrownsExceptions = methodBinding.thrownExceptions) != NoExceptions) {
		// 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
		int length = thrownsExceptions.length;
		if (contentsOffset + (8 + length * 2) >= (contentsLength = contents.length)) {
			System.arraycopy(contents, 0, (contents = new byte[contentsLength + Math.max(INCREMENT_SIZE, (8 + length * 2))]), 0, contentsLength);
		}
		int exceptionNameIndex = constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
		contents[contentsOffset++] = (byte) (exceptionNameIndex >> 8);
		contents[contentsOffset++] = (byte) exceptionNameIndex;
		// The attribute length = length * 2 + 2 in case of a exception attribute
		int attributeLength = length * 2 + 2;
		contents[contentsOffset++] = (byte) (attributeLength >> 24);
		contents[contentsOffset++] = (byte) (attributeLength >> 16);
		contents[contentsOffset++] = (byte) (attributeLength >> 8);
		contents[contentsOffset++] = (byte) attributeLength;
		contents[contentsOffset++] = (byte) (length >> 8);
		contents[contentsOffset++] = (byte) length;
		for (int i = 0; i < length; i++) {
			int exceptionIndex = constantPool.literalIndex(thrownsExceptions[i]);
			contents[contentsOffset++] = (byte) (exceptionIndex >> 8);
			contents[contentsOffset++] = (byte) exceptionIndex;
		}
		attributeNumber++;
	}

	// Deprecated attribute
	// Check that there is enough space to write the deprecated attribute
	if (contentsOffset + 6 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	if (methodBinding.isDeprecated()) {
		int deprecatedAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
		contents[contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) deprecatedAttributeNameIndex;
		// the length of a deprecated attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;

		attributeNumber++;
	}

	// Synthetic attribute
	// Check that there is enough space to write the deprecated attribute
	if (contentsOffset + 6 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	if (methodBinding.isSynthetic()) {
		int syntheticAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
		contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
		contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
		// the length of a synthetic attribute is equals to 0
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;
		contents[contentsOffset++] = 0;

		attributeNumber++;
	}
	return attributeNumber;
}
/**
 * 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) {
	// check that there is enough space to write all the bytes for the method info corresponding
	// to the @methodBinding
	int contentsLength;
	methodCount++; // add one more method
	if (contentsOffset + 10 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	int accessFlags = methodBinding.getAccessFlags();
	if (methodBinding.isRequiredToClearPrivateModifier()) {
		accessFlags &= ~AccPrivate;
	}
	contents[contentsOffset++] = (byte) (accessFlags >> 8);
	contents[contentsOffset++] = (byte) accessFlags;
	int nameIndex = constantPool.literalIndex(methodBinding.selector);
	contents[contentsOffset++] = (byte) (nameIndex >> 8);
	contents[contentsOffset++] = (byte) nameIndex;
	int descriptorIndex = constantPool.literalIndex(methodBinding.signature());
	contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
	contents[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.
 *
 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
 */
public void generateMethodInfoHeaderForClinit() {
	// check that there is enough space to write all the bytes for the method info corresponding
	// to the @methodBinding
	int contentsLength;
	methodCount++; // add one more method
	if (contentsOffset + 10 >= (contentsLength = contents.length)) {
		System.arraycopy(contents, 0, (contents = new byte[contentsLength + INCREMENT_SIZE]), 0, contentsLength);
	}
	contents[contentsOffset++] = (byte) ((AccDefault | AccStatic) >> 8);
	contents[contentsOffset++] = (byte) (AccDefault | AccStatic);
	int nameIndex = constantPool.literalIndex(QualifiedNamesConstants.Clinit);
	contents[contentsOffset++] = (byte) (nameIndex >> 8);
	contents[contentsOffset++] = (byte) nameIndex;
	int descriptorIndex = constantPool.literalIndex(QualifiedNamesConstants.ClinitSignature);
	contents[contentsOffset++] = (byte) (descriptorIndex >> 8);
	contents[contentsOffset++] = (byte) descriptorIndex;
	// We know that we won't get more than 1 attribute: the code attribute
	contents[contentsOffset++] = 0;
	contents[contentsOffset++] = 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() {
	byte[] fullContents = new byte[headerOffset + contentsOffset];
	System.arraycopy(header, 0, fullContents, 0, headerOffset);
	System.arraycopy(contents, 0, fullContents, headerOffset, contentsOffset);
	return fullContents;
}
/**
 * EXTERNAL API
 * Answer the compound name of the class file.
 * @return char[][]
 * e.g. {{java}, {util}, {Hashtable}}.
 */
public char[][] getCompoundName() {
	return CharOperation.splitOn('/', fileName());
}
/**
 * EXTERNAL API
 * 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 byte[] getReducedBytes() {
	return getBytes(); // might be improved
}
/**
 * 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;
}
/**
 * INTERNAL USE-ONLY
 * This is used to store a new inner class. It checks that the binding @binding doesn't already exist inside the
 * collection of inner classes. Add all the necessary classes in the right order to fit to the specifications.
 *
 * @param binding org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding
 */
public void recordEnclosingTypeAttributes(ReferenceBinding binding) {
	// add all the enclosing types
	ReferenceBinding enclosingType = referenceBinding.enclosingType();
	int depth = 0;
	while (enclosingType != null) {
		depth++;
		enclosingType = enclosingType.enclosingType();
	}
	enclosingType = referenceBinding;
	ReferenceBinding enclosingTypes[];
	if (depth >= 2) {
		enclosingTypes = new ReferenceBinding[depth];
		for (int i = depth - 1; i >= 0; i--) {
			enclosingTypes[i] = enclosingType;
			enclosingType = enclosingType.enclosingType();
		}
		for (int i = 0; i < depth; i++) {
			addInnerClasses(enclosingTypes[i]);
		}
	} else {
		addInnerClasses(referenceBinding);
	}
}
/**
 * INTERNAL USE-ONLY
 * This is used to store a new inner class. It checks that the binding @binding doesn't already exist inside the
 * collection of inner classes. Add all the necessary classes in the right order to fit to the specifications.
 *
 * @param binding org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding
 */
public void recordNestedLocalAttribute(ReferenceBinding binding) {
	// add all the enclosing types
	ReferenceBinding enclosingType = referenceBinding.enclosingType();
	int depth = 0;
	while (enclosingType != null) {
		depth++;
		enclosingType = enclosingType.enclosingType();
	}
	enclosingType = referenceBinding;
	ReferenceBinding enclosingTypes[];
	if (depth >= 2) {
		enclosingTypes = new ReferenceBinding[depth];
		for (int i = depth - 1; i >= 0; i--) {
			enclosingTypes[i] = enclosingType;
			enclosingType = enclosingType.enclosingType();
		}
		for (int i = 0; i < depth; i++)
			addInnerClasses(enclosingTypes[i]);
	} else {
		addInnerClasses(binding);
	}
}
/**
 * INTERNAL USE-ONLY
 * This is used to store a new inner class. It checks that the binding @binding doesn't already exist inside the
 * collection of inner classes. Add all the necessary classes in the right order to fit to the specifications.
 *
 * @param binding org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding
 */
public void recordNestedMemberAttribute(ReferenceBinding binding) {
	addInnerClasses(binding);
}
/**
 * INTERNAL USE-ONLY
 * Search the line number corresponding to a specific position
 *
 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
 */
public static final int searchLineNumber(int[] startLineIndexes, int position) {
	// this code is completely useless, but it is the same implementation than
	// org.eclipse.jdt.internal.compiler.problem.ProblemHandler.searchLineNumber(int[], int)
	// if (startLineIndexes == null)
	//	return 1;
	int length = startLineIndexes.length;
	if (length == 0)
		return 1;
	int g = 0, d = length - 1;
	int m = 0;
	while (g <= d) {
		m = (g + d) /2;
		if (position < startLineIndexes[m]) {
			d = m-1;
		} else if (position > startLineIndexes[m]) {
			g = m+1;
		} else {
			return m + 1;
		}
	}
	if (position < startLineIndexes[m]) {
		return m+1;
	}
	return m+2;
}
/**
 * INTERNAL USE-ONLY
 * This methods leaves the space for method counts recording.
 */
public void setForMethodInfos() {
	// leave some space for the methodCount
	methodCountOffset = contentsOffset;
	contentsOffset += 2;
}
/**
 * INTERNAL USE-ONLY
 * outputPath is formed like:
 *	   c:\temp\ the last character is a file separator
 * relativeFileName is formed like:
 *     java\lang\String.class
 * @param fileName java.lang.String
 * @param content byte[]
 */
public static void writeToDisk(String outputPath, String relativeFileName, byte[] contents) throws IOException {
	String fileName;
	File file;
	FileOutputStream output = new FileOutputStream(file = new File((fileName = buildAllDirectoriesInto(outputPath, relativeFileName))));
	output.write(contents);
	output.flush();
	output.close();
}
}
