package org.eclipse.jdt.internal.compiler.codegen;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
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.classfmt.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;

public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
	// It will be responsible for the following items.

	// -> Tracking Max Stack.

	public int stackMax; // Use Ints to keep from using extra bc when adding
	public int stackDepth; // Use Ints to keep from using extra bc when adding
	public int maxLocals;
	public static final int max = 100; // Maximum size of the code array
	public static final int growFactor = 400;
	public static final int LABELS_INCREMENT = 5;
	public byte[] bCodeStream;
	public int pcToSourceMapSize;
	public int[] pcToSourceMap = new int[24];
	public int lastEntryPC; // last entry recorded
	public int[] lineSeparatorPositions;
	public int position; // So when first set can be incremented
	public int classFileOffset;
	public int startingClassFileOffset; // I need to keep the starting point inside the byte array
	public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
	public ClassFile classFile; // The current classfile it is associated to.
	// local variable attributes output
	public static final int LOCALS_INCREMENT = 10;
	public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
	static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
	public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
	static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
	int visibleLocalsCount;
	public AbstractMethodDeclaration methodDeclaration;
	public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
	static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
	public int exceptionHandlersNumber;
	public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
	public boolean generateLineNumberAttributes;
	public boolean generateLocalVariableTableAttributes;
	public boolean preserveUnusedLocals;
	// store all the labels placed at the current position to be able to optimize
	// a jump to the next bytecode.
	public Label[] labels = new Label[LABELS_INCREMENT];
	static Label[] noLabels = new Label[LABELS_INCREMENT];
	public int countLabels;
	public int allLocalsCounter;
	public int maxFieldCount;
public CodeStream(ClassFile classFile) {
	generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
	generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
	if (generateLineNumberAttributes) {
		lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
	}
}
final public void aaload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aaload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aaload);
	}
}
final public void aastore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aastore);
	}
}
final public void aconst_null() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aconst_null;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aconst_null);
	}
}
public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
	// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
	if (!generateLocalVariableTableAttributes)
		return;
/*	if (initStateIndex == lastInitStateIndexWhenAddingInits)
		return;
	lastInitStateIndexWhenAddingInits = initStateIndex;
	if (lastInitStateIndexWhenRemovingInits != initStateIndex){
		lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index 
		// remove(1)-add(1)-remove(1) -> ignore second remove
		// remove(1)-add(2)-remove(1) -> perform second remove
	}
	
*/	for (int i = 0; i < visibleLocalsCount; i++) {
		LocalVariableBinding localBinding = visibleLocals[i];
		if (localBinding != null) {
			// Check if the local is definitely assigned
			if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
				if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
					/* There are two cases:
					 * 1) there is no initialization interval opened ==> add an opened interval
					 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
					 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
					 * is equals to -1.
					 * initializationPCs is a collection of pairs of int:
					 * 	first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
					 * 	is not closed yet.
					 */
					localBinding.recordInitializationStartPC(position);
				}
			}
		}
	}
}
public void addLabel(Label aLabel) {
	if (countLabels == labels.length)
		System.arraycopy(labels, 0, (labels = new Label[countLabels + LABELS_INCREMENT]), 0, countLabels);
	labels[countLabels++] = aLabel;
}
public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
	if (!generateLocalVariableTableAttributes)
		return;

	if (visibleLocalsCount >= visibleLocals.length) {
		System.arraycopy(visibleLocals, 0, (visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2]), 0, visibleLocalsCount);
	}
	visibleLocals[visibleLocalsCount++] = localBinding;
}
final public void aload(int iArg) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_aload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_aload);
		}
		writeUnsignedShort(iArg);
	} else {
		// Don't need to use the wide bytecode
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_aload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_aload);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) (iArg);
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void aload_0() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aload_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aload_0);
	}
}
final public void aload_1() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aload_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aload_1);
	}
}
final public void aload_2() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aload_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aload_2);
	}
}
final public void aload_3() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_aload_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_aload_3);
	}
}
public final void anewarray(TypeBinding typeBinding) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_anewarray;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_anewarray);
	}
	writeUnsignedShort(constantPool.literalIndex(typeBinding));
}
public void anewarrayJavaLangClass() {
	// anewarray: java.lang.Class
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_anewarray;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_anewarray);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangClass());
}
public void anewarrayJavaLangObject() {
	// anewarray: java.lang.Object
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_anewarray;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_anewarray);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangObject());
}
final public void areturn() {
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_areturn;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_areturn);
	}
}
public void arrayAt(int typeBindingID) {
	switch (typeBindingID) {
		case T_int :
			this.iaload();
			break;
		case T_byte :
		case T_boolean :
			this.baload();
			break;
		case T_short :
			this.saload();
			break;
		case T_char :
			this.caload();
			break;
		case T_long :
			this.laload();
			break;
		case T_float :
			this.faload();
			break;
		case T_double :
			this.daload();
			break;
		default :
			this.aaload();
	}
}
public void arrayAtPut(int elementTypeID, boolean valueRequired) {
	switch (elementTypeID) {
		case T_int :
			if (valueRequired)
				dup_x2();
			iastore();
			break;
		case T_byte :
		case T_boolean :
			if (valueRequired)
				dup_x2();
			bastore();
			break;
		case T_short :
			if (valueRequired)
				dup_x2();
			sastore();
			break;
		case T_char :
			if (valueRequired)
				dup_x2();
			castore();
			break;
		case T_long :
			if (valueRequired)
				dup2_x2();
			lastore();
			break;
		case T_float :
			if (valueRequired)
				dup_x2();
			fastore();
			break;
		case T_double :
			if (valueRequired)
				dup2_x2();
			dastore();
			break;
		default :
			if (valueRequired)
				dup_x2();
			aastore();
	}
}
final public void arraylength() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_arraylength;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_arraylength);
	}
}
final public void astore(int iArg) {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_astore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_astore);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_astore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_astore);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void astore_0() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_astore_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_astore_0);
	}
}
final public void astore_1() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_astore_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_astore_1);
	}
}
final public void astore_2() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_astore_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_astore_2);
	}
}
final public void astore_3() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_astore_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_astore_3);
	}
}
final public void athrow() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_athrow;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_athrow);
	}
}
final public void baload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_baload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_baload);
	}
}
final public void bastore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_bastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_bastore);
	}
}
final public void bipush(byte b) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_bipush;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_bipush);
	}
	writeSignedByte(b);
}
final public void caload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_caload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_caload);
	}
}
final public void castore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_castore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_castore);
	}
}
public final void checkcast(TypeBinding typeBinding) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_checkcast;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_checkcast);
	}
	writeUnsignedShort(constantPool.literalIndex(typeBinding));
}
public final void checkcastJavaLangError() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_checkcast;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_checkcast);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangError());
}
final public void d2f() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_d2f;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_d2f);
	}
}
final public void d2i() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_d2i;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_d2i);
	}
}
final public void d2l() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_d2l;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_d2l);
	}
}
final public void dadd() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dadd;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dadd);
	}
}
final public void daload() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_daload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_daload);
	}
}
final public void dastore() {
	countLabels = 0;
	stackDepth -= 4;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dastore);
	}
}
final public void dcmpg() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dcmpg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dcmpg);
	}
}
final public void dcmpl() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dcmpl;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dcmpl);
	}
}
final public void dconst_0() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dconst_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dconst_0);
	}
}
final public void dconst_1() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dconst_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dconst_1);
	}
}
final public void ddiv() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ddiv;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ddiv);
	}
}
public void decrStackSize(int offset) {
	stackDepth -= offset;
}
final public void dload(int iArg) {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < iArg + 2) {
		maxLocals = iArg + 2; // + 2 because it is a double
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_dload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_dload);
		}
		writeUnsignedShort(iArg);
	} else {
		// Don't need to use the wide bytecode
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_dload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_dload);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void dload_0() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dload_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dload_0);
	}
}
final public void dload_1() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dload_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dload_1);
	}
}
final public void dload_2() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dload_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dload_2);
	}
}
final public void dload_3() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dload_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dload_3);
	}
}
final public void dmul() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dmul;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dmul);
	}
}
final public void dneg() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dneg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dneg);
	}
}
final public void drem() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_drem;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_drem);
	}
}
final public void dreturn() {
	countLabels = 0;
	stackDepth -= 2;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dreturn;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dreturn);
	}
}
final public void dstore(int iArg) {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_dstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_dstore);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_dstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_dstore);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void dstore_0() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dstore_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dstore_0);
	}
}
final public void dstore_1() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dstore_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dstore_1);
	}
}
final public void dstore_2() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dstore_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dstore_2);
	}
}
final public void dstore_3() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dstore_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dstore_3);
	}
}
final public void dsub() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dsub;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dsub);
	}
}
final public void dup() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup);
	}
}
final public void dup_x1() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup_x1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup_x1);
	}
}
final public void dup_x2() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup_x2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup_x2);
	}
}
final public void dup2() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup2);
	}
}
final public void dup2_x1() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup2_x1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup2_x1);
	}
}
final public void dup2_x2() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_dup2_x2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_dup2_x2);
	}
}
public void exitUserScope(BlockScope blockScope) {
	// mark all the scope's locals as loosing their definite assignment

	if (!generateLocalVariableTableAttributes)
		return;
	for (int i = 0; i < visibleLocalsCount; i++) {
		LocalVariableBinding visibleLocal = visibleLocals[i];
		if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) { 
			// there maybe some some preserved locals never initialized
			if (visibleLocal.initializationCount > 0){
				visibleLocals[i].recordInitializationEndPC(position);
			}
			visibleLocals[i] = null; // this variable is no longer visible afterwards
		}
	}
}
final public void f2d() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_f2d;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_f2d);
	}
}
final public void f2i() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_f2i;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_f2i);
	}
}
final public void f2l() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_f2l;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_f2l);
	}
}
final public void fadd() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fadd;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fadd);
	}
}
final public void faload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_faload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_faload);
	}
}
final public void fastore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fastore);
	}
}
final public void fcmpg() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fcmpg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fcmpg);
	}
}
final public void fcmpl() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fcmpl;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fcmpl);
	}
}
final public void fconst_0() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fconst_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fconst_0);
	}
}
final public void fconst_1() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fconst_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fconst_1);
	}
}
final public void fconst_2() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fconst_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fconst_2);
	}
}
final public void fdiv() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fdiv;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fdiv);
	}
}
final public void fload(int iArg) {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_fload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_fload);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_fload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_fload);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void fload_0() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fload_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fload_0);
	}
}
final public void fload_1() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fload_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fload_1);
	}
}
final public void fload_2() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fload_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fload_2);
	}
}
final public void fload_3() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fload_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fload_3);
	}
}
final public void fmul() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fmul;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fmul);
	}
}
final public void fneg() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fneg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fneg);
	}
}
final public void frem() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_frem;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_frem);
	}
}
final public void freturn() {
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_freturn;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_freturn);
	}
}
final public void fstore(int iArg) {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_fstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_fstore);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_fstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_fstore);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void fstore_0() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fstore_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fstore_0);
	}
}
final public void fstore_1() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fstore_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fstore_1);
	}
}
final public void fstore_2() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fstore_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fstore_2);
	}
}
final public void fstore_3() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fstore_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fstore_3);
	}
}
final public void fsub() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_fsub;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_fsub);
	}
}
/**
 * Macro for building a class descriptor object
 */
public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
	Label endLabel;
	ExceptionLabel anyExceptionHandler;
	int saveStackSize;
	if (accessedType.isBaseType()) {
		this.getTYPE(accessedType.id);
		return;
	}
	endLabel = new Label(this);

	if (syntheticFieldBinding != null) { // non interface case
		this.getstatic(syntheticFieldBinding);
		this.dup();
		this.ifnonnull(endLabel);
		this.pop();
	}

	/* Macro for building a class descriptor object... using or not a field cache to store it into...
	this sequence is responsible for building the actual class descriptor.
	
	If the fieldCache is set, then it is supposed to be the body of a synthetic access method
	factoring the actual descriptor creation out of the invocation site (saving space).
	If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
	we have no way to get a hand on the field cache to do better. */


	// Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError

	anyExceptionHandler = new ExceptionLabel(this, TypeBinding.NullBinding /* represents ClassNotFoundException*/);
	this.ldc(accessedType == TypeBinding.NullBinding ? "java.lang.Object"/*nonNLS*/ : String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
	this.invokeClassForName();

	/* We need to protect the runtime code from binary inconsistencies
	in case the accessedType is missing, the ClassNotFoundException has to be converted
	into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
	anyExceptionHandler.placeEnd();

	if (syntheticFieldBinding != null) { // non interface case
		this.dup();
		this.putstatic(syntheticFieldBinding);
	}
	this.goto_(endLabel);


	// Generate the body of the exception handler
	saveStackSize = stackDepth;
	stackDepth = 1;
	/* ClassNotFoundException on stack -- the class literal could be doing more things
	on the stack, which means that the stack may not be empty at this point in the
	above code gen. So we save its state and restart it from 1. */

	anyExceptionHandler.place();

	// Transform the current exception, and repush and throw a 
	// NoClassDefFoundError(ClassNotFound.getMessage())

	this.newNoClassDefFoundError();
	this.dup_x1();
	this.swap();

	// Retrieve the message from the old exception
	this.invokeThrowableGetMessage();

	// Send the constructor taking a message string as an argument
	this.invokeNoClassDefFoundErrorStringConstructor();
	this.athrow();
	endLabel.place();
	stackDepth = saveStackSize;
}
/**
 * This method returns the exception handler to be able to generate the exception handler
 * attribute.
 */
final public int[] generateCodeAttributeForProblemMethod(String errorName, String problemMessage) {
	/**
	 * Equivalent code:
	 *	try {
	 *		throw ((Error) (Class.forName(errorName).getConstructor(new Class[] {Class.forName("java.lang.String")})).newInstance(new Object[] {problemMessage}));
	 *	} catch (Exception e) {
	 *		throw (NullPointerException) null;
	 *	}
	 */
	int endPC, handlerPC;
	ldc(errorName);
	invokeClassForName();
	iconst_1();
	anewarrayJavaLangClass();
	dup();
	iconst_0();
	ldc("java.lang.String"/*nonNLS*/);
	invokeClassForName();
	aastore();
	invokeConstructorGetConstructor();
	iconst_1();
	anewarrayJavaLangObject();
	dup();
	iconst_0();
	ldc(problemMessage);
	aastore();
	invokeObjectNewInstance();
	checkcastJavaLangError();
	athrow();
	endPC = handlerPC = position;
	pop();
	aconst_null();
	athrow();
	return_();
	return new int[] {0, endPC, handlerPC};
}
public void generateConstant(Constant constant, int implicitConversionCode) {
	int targetTypeID = implicitConversionCode >> 4;
	switch (targetTypeID) {
		case T_boolean :
			generateInlinedValue(constant.booleanValue());
			break;
		case T_char :
			generateInlinedValue(constant.charValue());
			break;
		case T_byte :
			generateInlinedValue(constant.byteValue());
			break;
		case T_short :
			generateInlinedValue(constant.shortValue());
			break;
		case T_int :
			generateInlinedValue(constant.intValue());
			break;
		case T_long :
			generateInlinedValue(constant.longValue());
			break;
		case T_float :
			generateInlinedValue(constant.floatValue());
			break;
		case T_double :
			generateInlinedValue(constant.doubleValue());
			break;
		case T_String :
			this.ldc(constant.stringValue());
			break;
		default : //reference object (constant can be from T_null or T_String)
			if (constant.typeID() == T_String)
				ldc(constant.stringValue());
			else
				aconst_null();
	}
}
/**
 * @param implicitConversionCode int
 */
public void generateImplicitConversion(int implicitConversionCode) {
	switch (implicitConversionCode) {
		case Float2Char :
			this.f2i();
			this.i2c();
			break;
		case Double2Char :
			this.d2i();
			this.i2c();
			break;
		case Int2Char :
		case Short2Char :
		case Byte2Char :
			this.i2c();
			break;
		case Long2Char :
			this.l2i();
			this.i2c();
			break;
		case Char2Float :
		case Short2Float :
		case Int2Float :
		case Byte2Float :
			this.i2f();
			break;
		case Double2Float :
			this.d2f();
			break;
		case Long2Float :
			this.l2f();
			break;
		case Float2Byte :
			this.f2i();
			this.i2b();
			break;
		case Double2Byte :
			this.d2i();
			this.i2b();
			break;
		case Int2Byte :
		case Short2Byte :
		case Char2Byte :
			this.i2b();
			break;
		case Long2Byte :
			this.l2i();
			this.i2b();
			break;
		case Byte2Double :
		case Char2Double :
		case Short2Double :
		case Int2Double :
			this.i2d();
			break;
		case Float2Double :
			this.f2d();
			break;
		case Long2Double :
			this.l2d();
			break;
		case Byte2Short :
		case Char2Short :
		case Int2Short :
			this.i2s();
			break;
		case Double2Short :
			this.d2i();
			this.i2s();
			break;
		case Long2Short :
			this.l2i();
			this.i2s();
			break;
		case Float2Short :
			this.f2i();
			this.i2s();
			break;
		case Double2Int :
			this.d2i();
			break;
		case Float2Int :
			this.f2i();
			break;
		case Long2Int :
			this.l2i();
			break;
		case Int2Long :
		case Char2Long :
		case Byte2Long :
		case Short2Long :
			this.i2l();
			break;
		case Double2Long :
			this.d2l();
			break;
		case Float2Long :
			this.f2l();
	}
}
public void generateInlinedValue(byte inlinedValue) {
	switch (inlinedValue) {
		case -1 :
			this.iconst_m1();
			break;
		case 0 :
			this.iconst_0();
			break;
		case 1 :
			this.iconst_1();
			break;
		case 2 :
			this.iconst_2();
			break;
		case 3 :
			this.iconst_3();
			break;
		case 4 :
			this.iconst_4();
			break;
		case 5 :
			this.iconst_5();
			break;
		default :
			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
				this.bipush((byte) inlinedValue);
				return;
			}
	}
}
public void generateInlinedValue(char inlinedValue) {
	switch (inlinedValue) {
		case 0 :
			this.iconst_0();
			break;
		case 1 :
			this.iconst_1();
			break;
		case 2 :
			this.iconst_2();
			break;
		case 3 :
			this.iconst_3();
			break;
		case 4 :
			this.iconst_4();
			break;
		case 5 :
			this.iconst_5();
			break;
		default :
			if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
				this.bipush((byte) inlinedValue);
				return;
			}
			if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
				this.sipush(inlinedValue);
				return;
			}
			this.ldc(inlinedValue);
	}
}
public void generateInlinedValue(double inlinedValue) {
	if (inlinedValue == 0.0) {
		if (Double.doubleToLongBits(inlinedValue) != 0L)
			this.ldc2_w(inlinedValue);
		else
			this.dconst_0();
		return;
	}
	if (inlinedValue == 1.0) {
		this.dconst_1();
		return;
	}
	this.ldc2_w(inlinedValue);
}
public void generateInlinedValue(float inlinedValue) {
	if (inlinedValue == 0.0f) {
		if (Float.floatToIntBits(inlinedValue) != 0)
			this.ldc(inlinedValue);
		else
			this.fconst_0();
		return;
	}
	if (inlinedValue == 1.0f) {
		this.fconst_1();
		return;
	}
	if (inlinedValue == 2.0f) {
		this.fconst_2();
		return;
	}
	this.ldc(inlinedValue);
}
public void generateInlinedValue(int inlinedValue) {
	switch (inlinedValue) {
		case -1 :
			this.iconst_m1();
			break;
		case 0 :
			this.iconst_0();
			break;
		case 1 :
			this.iconst_1();
			break;
		case 2 :
			this.iconst_2();
			break;
		case 3 :
			this.iconst_3();
			break;
		case 4 :
			this.iconst_4();
			break;
		case 5 :
			this.iconst_5();
			break;
		default :
			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
				this.bipush((byte) inlinedValue);
				return;
			}
			if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
				this.sipush(inlinedValue);
				return;
			}
			this.ldc(inlinedValue);
	}
}
public void generateInlinedValue(long inlinedValue) {
	if (inlinedValue == 0) {
		this.lconst_0();
		return;
	}
	if (inlinedValue == 1) {
		this.lconst_1();
		return;
	}
	this.ldc2_w(inlinedValue);
}
public void generateInlinedValue(short inlinedValue) {
	switch (inlinedValue) {
		case -1 :
			this.iconst_m1();
			break;
		case 0 :
			this.iconst_0();
			break;
		case 1 :
			this.iconst_1();
			break;
		case 2 :
			this.iconst_2();
			break;
		case 3 :
			this.iconst_3();
			break;
		case 4 :
			this.iconst_4();
			break;
		case 5 :
			this.iconst_5();
			break;
		default :
			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
				this.bipush((byte) inlinedValue);
				return;
			}
			this.sipush(inlinedValue);
	}
}
public void generateInlinedValue(boolean inlinedValue) {
	if (inlinedValue)
		this.iconst_1();
	else
		this.iconst_0();
}
public void generateObjectWrapperForType(TypeBinding valueType) {

	/* The top of stack must be encapsulated inside 
	 * a wrapper object if it corresponds to a base type
	 */
	char[][] wrapperTypeCompoundName = null;
	switch (valueType.id) {
		case T_int : // new: java.lang.Integer
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Integer"/*nonNLS*/.toCharArray()};
			break;
		case T_boolean : // new: java.lang.Boolean
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Boolean"/*nonNLS*/.toCharArray()};
			break;
		case T_byte : // new: java.lang.Byte
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Byte"/*nonNLS*/.toCharArray()};
			break;
		case T_char : // new: java.lang.Character
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Character"/*nonNLS*/.toCharArray()};
			break;
		case T_float : // new: java.lang.Float
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Float"/*nonNLS*/.toCharArray()};
			break;
		case T_double : // new: java.lang.Double
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Double"/*nonNLS*/.toCharArray()};
			break;
		case T_short : // new: java.lang.Short
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Short"/*nonNLS*/.toCharArray()};
			break;
		case T_long : // new: java.lang.Long
			wrapperTypeCompoundName = new char[][] {"java"/*nonNLS*/.toCharArray(), "lang"/*nonNLS*/.toCharArray(), "Long"/*nonNLS*/.toCharArray()};
			break;
	}
	TypeBinding wrapperType = methodDeclaration.scope.getType(wrapperTypeCompoundName);
	new_(wrapperType);
	if (valueType.id == T_long || valueType.id == T_double) {
		dup_x2();
		dup_x2();
		pop();
	} else {
		dup_x1();
		swap();
	}
	MethodBinding methodBinding = methodDeclaration.scope.getMethod(wrapperType, QualifiedNamesConstants.Init, new TypeBinding[] {valueType}, null);
	invokespecial(methodBinding);
}
public void generateOuterAccess(Object[] mappingSequence, AstNode invocationSite, Scope scope) {
	if (mappingSequence == null)
		return;
	if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
		if (scope.methodScope().isConstructorCall){
			scope.problemReporter().errorThisSuperInStatic(invocationSite);
		}
		this.aload_0();
		return;
	}
	if (mappingSequence[0] instanceof FieldBinding) {
		FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
		if (scope.methodScope().isConstructorCall){
			scope.problemReporter().errorThisSuperInStatic(invocationSite);
		}
		this.aload_0();
		this.getfield(fieldBinding);
	} else {
		load((LocalVariableBinding) mappingSequence[0]);
	}
	for (int i = 1, length = mappingSequence.length; i < length; i++) {
		if (mappingSequence[i] instanceof FieldBinding) {
			FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
			this.getfield(fieldBinding);
		} else {
			this.invokestatic((MethodBinding) mappingSequence[i]);
		}
	}
}
/**
 * The equivalent code performs a string conversion:
 *
 * @param oper1 org.eclipse.jdt.internal.compiler.lookup.BlockScope
 * @param oper1 org.eclipse.jdt.internal.compiler.ast.Expression
 * @param oper2 org.eclipse.jdt.internal.compiler.ast.Expression
 */
public void generateStringAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
	int pc;
	if (oper1 == null) {
		/* Operand is already on the stack, and maybe nil:
		note type1 is always to  java.lang.String here.*/
		this.newStringBuffer();
		this.dup_x1();
		this.swap();
		// If argument is reference type, need to transform it 
		// into a string (handles null case)
		this.invokeStringValueOf(T_Object);
		this.invokeStringBufferStringConstructor();
	} else {
		pc = position;
		oper1.generateOptimizedStringBufferCreation(blockScope, this, oper1.implicitConversion & 0xF);
		this.recordPositionsFrom(pc, oper1);
	}
	pc = position;
	oper2.generateOptimizedStringBuffer(blockScope, this, oper2.implicitConversion & 0xF);
	this.recordPositionsFrom(pc, oper2);
	this.invokeStringBufferToString();
}
/**
 * Code responsible to generate the suitable code to supply values for the synthetic arguments of
 * a constructor invocation of a nested type.
 */
public void generateSyntheticArgumentValues(BlockScope currentScope, ReferenceBinding targetType, Expression enclosingInstance, AstNode invocationSite) {

	// perform some emulation work in case there is some and we are inside a local type only
	ReferenceBinding[] syntheticArgumentTypes;

	// generate the enclosing instance first
	if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
		ReferenceBinding targetEnclosingType = targetType.enclosingType();
		for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
			ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
			if (enclosingInstance != null && i == 0) {
				boolean enclosingInstanceRequired = targetType.isAnonymousType() ? syntheticArgType == targetType.superclass().enclosingType() // supplying enclosing instance for the anonymous type's superclass
				: syntheticArgType == targetEnclosingType;
				if (!enclosingInstanceRequired) {
					currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, targetType);
				}
				enclosingInstance.generateCode(currentScope, this, enclosingInstanceRequired);
			} else {
				Object[] emulationPath = currentScope.getCompatibleEmulationPath(syntheticArgType);
				if (emulationPath == null) {
					// could not emulate a path to a given enclosing instance (must specify one - if direct enclosing instance)
					if (syntheticArgType == targetEnclosingType) { //  missing direct enclosing instance
						currentScope.problemReporter().missingEnclosingInstanceSpecification(targetEnclosingType, invocationSite);
					} else {
						currentScope.problemReporter().needImplementation();
					}
				} else {
					this.generateOuterAccess(emulationPath, invocationSite, currentScope);
				}
			}
		}
	} else { // we may still have an enclosing instance to consider
		if (enclosingInstance != null) {
			currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, targetType);
			enclosingInstance.generateCode(currentScope, this, false); // do not want the value
		}
	}
	// generate the synthetic outer arguments then
	SyntheticArgumentBinding syntheticArguments[];
	if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
		for (int i = 0, max = syntheticArguments.length; i < max; i++) {
			VariableBinding[] emulationPath = currentScope.getEmulationPath(syntheticArguments[i].actualOuterLocalVariable);
			if (emulationPath == null) {
				// could not emulate a path to a given outer local variable (internal error)
				currentScope.problemReporter().needImplementation();
			} else {
				this.generateOuterAccess(emulationPath, invocationSite, currentScope);
			}
		}
	}
}
/**
 * @param parameters org.eclipse.jdt.internal.compiler.lookup.TypeBinding[]
 * @param constructorBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
 */
public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBinding accessBinding) {

	initializeMaxLocals(accessBinding);

	MethodBinding constructorBinding = accessBinding.targetMethod;
	TypeBinding[] parameters = constructorBinding.parameters;
	int length = parameters.length;
	int resolvedPosition = 1;
	this.aload_0();
	if (constructorBinding.declaringClass.isNestedType()) {
		NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass;
		SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
		for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
			TypeBinding type;
			load((type = syntheticArguments[i].type), resolvedPosition);
			if ((type == DoubleBinding) || (type == LongBinding))
				resolvedPosition += 2;
			else
				resolvedPosition++;
		}
		syntheticArguments = nestedType.syntheticOuterLocalVariables();
		for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
			TypeBinding type;
			load((type = syntheticArguments[i].type), resolvedPosition);
			if ((type == DoubleBinding) || (type == LongBinding))
				resolvedPosition += 2;
			else
				resolvedPosition++;
		}
	}
	for (int i = 0; i < length; i++) {
		load(parameters[i], resolvedPosition);
		if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
			resolvedPosition += 2;
		else
			resolvedPosition++;
	}
	this.invokespecial(constructorBinding);
	this.return_();
}
public void generateSyntheticBodyForFieldReadAccess(SyntheticAccessMethodBinding accessBinding) {
	initializeMaxLocals(accessBinding);
	FieldBinding fieldBinding = accessBinding.targetReadField;
	TypeBinding type;
	if (fieldBinding.isStatic())
		this.getstatic(fieldBinding);
	else {
		this.aload_0();
		this.getfield(fieldBinding);
	}
	if ((type = fieldBinding.type).isBaseType()) {
		if (type == IntBinding)
			this.ireturn();
		else
			if (type == FloatBinding)
				this.freturn();
			else
				if (type == LongBinding)
					this.lreturn();
				else
					if (type == DoubleBinding)
						this.dreturn();
					else
						this.ireturn();
	} else
		this.areturn();
}
public void generateSyntheticBodyForFieldWriteAccess(SyntheticAccessMethodBinding accessBinding) {
	initializeMaxLocals(accessBinding);
	FieldBinding fieldBinding = accessBinding.targetWriteField;
	if (fieldBinding.isStatic()) {
		load(fieldBinding.type, 0);
		this.putstatic(fieldBinding);
	} else {
		this.aload_0();
		load(fieldBinding.type, 1);
		this.putfield(fieldBinding);
	}
	this.return_();
}
public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding accessBinding) {

	initializeMaxLocals(accessBinding);
	MethodBinding methodBinding = accessBinding.targetMethod;
	TypeBinding[] parameters = methodBinding.parameters;
	int length = parameters.length;
	int resolvedPosition;
	if (methodBinding.isStatic())
		resolvedPosition = 0;
	else {
		this.aload_0();
		resolvedPosition = 1;
	}
	for (int i = 0; i < length; i++) {
		load(parameters[i], resolvedPosition);
		if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
			resolvedPosition += 2;
		else
			resolvedPosition++;
	}
	TypeBinding type;
	int id;
	if (methodBinding.isStatic())
		this.invokestatic(methodBinding);
	else {
		if (methodBinding.isConstructor()
			|| methodBinding.isPrivate()
			// qualified super "X.super.foo()" targets methods from superclass
			|| (methodBinding.declaringClass != methodDeclaration.binding.declaringClass)){
			this.invokespecial(methodBinding);
		} else {
			if (methodBinding.declaringClass.isInterface()){
				this.invokeinterface(methodBinding);
			} else {
				this.invokevirtual(methodBinding);
			}
		}
	}
	if ((type = methodBinding.returnType).isBaseType())
		if (type == VoidBinding)
			this.return_();
		else
			if (type == IntBinding)
				this.ireturn();
			else
				if (type == FloatBinding)
					this.freturn();
				else
					if (type == LongBinding)
						this.lreturn();
					else
						if (type == DoubleBinding)
							this.dreturn();
						else
							this.ireturn();
	else
		this.areturn();
}
final public byte[] getContents() {
	byte[] contents;
	System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
	return contents;
}
final public void getfield(FieldBinding fieldBinding) {
	countLabels = 0;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
		if (++stackDepth > stackMax)
			stackMax = stackDepth;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_getfield;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_getfield);
	}
	writeUnsignedShort(constantPool.literalIndex(fieldBinding));
}
final public void getstatic(FieldBinding fieldBinding) {
	countLabels = 0;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long))
		stackDepth += 2;
	else
		stackDepth += 1;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_getstatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_getstatic);
	}
	writeUnsignedShort(constantPool.literalIndex(fieldBinding));
}
public void getSystemOut() {
	countLabels = 0;
	if (++stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_getstatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_getstatic);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangSystemOut());
}
public void getTYPE(int baseTypeID) {
	countLabels = 0;
	if (++stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_getstatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_getstatic);
	}
	switch (baseTypeID) {
		// getstatic: java.lang.Byte.TYPE			
		case T_byte :
			writeUnsignedShort(constantPool.literalIndexForJavaLangByteTYPE());
			break;
			// getstatic: java.lang.Short.TYPE			
		case T_short :
			writeUnsignedShort(constantPool.literalIndexForJavaLangShortTYPE());
			break;
			// getstatic: java.lang.Character.TYPE			
		case T_char :
			writeUnsignedShort(constantPool.literalIndexForJavaLangCharacterTYPE());
			break;
			// getstatic: java.lang.Integer.TYPE			
		case T_int :
			writeUnsignedShort(constantPool.literalIndexForJavaLangIntegerTYPE());
			break;
			// getstatic: java.lang.Long.TYPE			
		case T_long :
			writeUnsignedShort(constantPool.literalIndexForJavaLangLongTYPE());
			break;
			// getstatic: java.lang.Float.TYPE			
		case T_float :
			writeUnsignedShort(constantPool.literalIndexForJavaLangFloatTYPE());
			break;
			// getstatic: java.lang.Double.TYPE			
		case T_double :
			writeUnsignedShort(constantPool.literalIndexForJavaLangDoubleTYPE());
			break;
			// getstatic: java.lang.Boolean.TYPE			
		case T_boolean :
			writeUnsignedShort(constantPool.literalIndexForJavaLangBooleanTYPE());
			break;
			// getstatic: java.lang.Void.TYPE
		case T_void :
			writeUnsignedShort(constantPool.literalIndexForJavaLangVoidTYPE());
			break;
	}
}
/**
 * We didn't call it goto, because there is a conflit with the goto keyword
 */
final public void goto_(Label lbl) {
	try {
		lbl.inlineForwardReferencesFromLabelsTargeting(position);
		/*
		 Possible optimization for code such as:
		 public Object foo() {
			boolean b = true;
			if (b) {
				if (b)
					return null;
			} else {
				if (b) {
					return null;
				}
			}
			return null;
		}
		The goto around the else block for the first if will
		be unreachable, because the thenClause of the second if
		returns.
		See inlineForwardReferencesFromLabelsTargeting defined
		on the Label class for the remaining part of this
		optimization.
		 if (!lbl.isBranchTarget(position)) {
			switch(bCodeStream[classFileOffset-1]) {
				case OPC_return :
				case OPC_areturn:
					return;
			}
		}*/
		position++;
		bCodeStream[classFileOffset++] = OPC_goto;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_goto);
	}
	lbl.branch();
}
final public void goto_w(Label lbl) {
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_goto_w;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_goto_w);
	}
	lbl.branchWide();
}
final public void i2b() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2b);
	}
}
final public void i2c() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2c;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2c);
	}
}
final public void i2d() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2d;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2d);
	}
}
final public void i2f() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2f;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2f);
	}
}
final public void i2l() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2l;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2l);
	}
}
final public void i2s() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_i2s;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_i2s);
	}
}
final public void iadd() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iadd;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iadd);
	}
}
final public void iaload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iaload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iaload);
	}
}
final public void iand() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iand;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iand);
	}
}
final public void iastore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iastore);
	}
}
final public void iconst_0() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_0);
	}
}
final public void iconst_1() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_1);
	}
}
final public void iconst_2() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_2);
	}
}
final public void iconst_3() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_3);
	}
}
final public void iconst_4() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_4;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_4);
	}
}
final public void iconst_5() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_5;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_5);
	}
}
final public void iconst_m1() {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iconst_m1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iconst_m1);
	}
}
final public void idiv() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_idiv;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_idiv);
	}
}
final public void if_acmpeq(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_acmpeq;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_acmpeq);
	}
	lbl.branch();
}
final public void if_acmpne(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_acmpne;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_acmpne);
	}
	lbl.branch();
}
final public void if_icmpeq(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpeq;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmpeq);
	}
	lbl.branch();
}
final public void if_icmpge(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpge;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmpge);
	}
	lbl.branch();
}
final public void if_icmpgt(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpgt;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmpgt);
	}
	lbl.branch();
}
final public void if_icmple(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmple;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmple);
	}
	lbl.branch();
}
final public void if_icmplt(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmplt;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmplt);
	}
	lbl.branch();
}
final public void if_icmpne(Label lbl) {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpne;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_if_icmpne);
	}
	lbl.branch();
}
final public void ifeq(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifeq;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifeq);
	}
	lbl.branch();
}
final public void ifge(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifge;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifge);
	}
	lbl.branch();
}
final public void ifgt(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifgt;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifgt);
	}
	lbl.branch();
}
final public void ifle(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifle;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifle);
	}
	lbl.branch();
}
final public void iflt(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iflt;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iflt);
	}
	lbl.branch();
}
final public void ifne(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifne;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifne);
	}
	lbl.branch();
}
final public void ifnonnull(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifnonnull;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifnonnull);
	}
	lbl.branch();
}
final public void ifnull(Label lbl) {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ifnull;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ifnull);
	}
	lbl.branch();
}
final public void iinc(int index, int value) {
	countLabels = 0;
	if ((index > 255) || (value < -128 || value > 127)) { // have to widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_iinc;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_iinc);
		}
		writeUnsignedShort(index);
		writeSignedShort(value);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_iinc;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_iinc);
		}
		writeUnsignedByte(index);
		writeSignedByte(value);
	}
}
final public void iload(int iArg) {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_iload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_iload);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_iload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_iload);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void iload_0() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 0) {
		maxLocals = 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iload_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iload_0);
	}
}
final public void iload_1() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iload_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iload_1);
	}
}
final public void iload_2() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iload_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iload_2);
	}
}
final public void iload_3() {
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iload_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iload_3);
	}
}
final public void imul() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_imul;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_imul);
	}
}
public void incrementTemp(LocalVariableBinding localBinding, int value) {
	if (value == (short) value) {
		this.iinc(localBinding.resolvedPosition, value);
		return;
	}
	load(localBinding);
	this.ldc(value);
	this.iadd();
	store(localBinding, false);
}
public void incrStackSize(int offset) {
	if ((stackDepth += offset) > stackMax)
		stackMax = stackDepth;
}
public int indexOfSameLineEntrySincePC(int pc, int line) {
	for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
		if (pcToSourceMap[index+1] == line)
			return index;
	}
	return -1;
}
final public void ineg() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ineg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ineg);
	}
}
public void init(ClassFile classFile) {
	this.classFile = classFile;
	this.constantPool = classFile.constantPool;
	this.bCodeStream = classFile.contents;
	this.classFileOffset = classFile.contentsOffset;
	this.startingClassFileOffset = this.classFileOffset;
	pcToSourceMapSize = 0;
	lastEntryPC = 0;
	int length = visibleLocals.length;
	if (noVisibleLocals.length < length) {
		noVisibleLocals = new LocalVariableBinding[length];
	}
	System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
	visibleLocalsCount = 0;
	
	length = locals.length;
	if (noLocals.length < length) {
		noLocals = new LocalVariableBinding[length];
	}
	System.arraycopy(noLocals, 0, locals, 0, length);
	allLocalsCounter = 0;

	length = exceptionHandlers.length;
	if (noExceptionHandlers.length < length) {
		noExceptionHandlers = new ExceptionLabel[length];
	}
	System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
	exceptionHandlersNumber = 0;
	
	length = labels.length;
	if (noLabels.length < length) {
		noLabels = new Label[length];
	}
	System.arraycopy(noLabels, 0, labels, 0, length);
	countLabels = 0;

	stackMax = 0;
	stackDepth = 0;
	maxLocals = 0;
	position = 0;
}
/**
 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
public void initializeMaxLocals(MethodBinding methodBinding) {

	maxLocals = (methodBinding == null || methodBinding.isStatic()) ? 0 : 1;
	// take into account the synthetic parameters
	if (methodBinding != null) {
		if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
			ReferenceBinding enclosingInstanceTypes[];
			if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
				for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
					maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
					// LongBinding or DoubleBinding
				}
			}
			SyntheticArgumentBinding syntheticArguments[];
			if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
				for (int i = 0, max = syntheticArguments.length; i < max; i++) {
					TypeBinding argType;
					if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
						maxLocals += 2;
					} else {
						maxLocals++;
					}
				}
			}
		}
		TypeBinding[] arguments;
		if ((arguments = methodBinding.parameters) != null) {
			for (int i = 0, max = arguments.length; i < max; i++) {
				TypeBinding argType;
				if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
					maxLocals += 2;
				} else {
					maxLocals++;
				}
			}
		}
	}
}
/**
 * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
 * If there is an existing entry it returns -1 (no insertion required).
 * Otherwise it returns the index where the entry for the pc has to be inserted.
 * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
 *
 * @param int pc
 * @return int
 */
public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
	int g = 0;
	int d = length - 2;
	int m = 0;
	while (g <= d) {
		m = (g + d) / 2;
		// we search only on even indexes
		if ((m % 2) != 0)
			m--;
		int currentPC = pcToSourceMap[m];
		if (pc < currentPC) {
			d = m - 2;
		} else
			if (pc > currentPC) {
				g = m + 2;
			} else {
				return -1;
			}
	}
	if (pc < pcToSourceMap[m])
		return m;
	return m + 2;
}
/**
 * We didn't call it instanceof because there is a conflit with the
 * instanceof keyword
 */
final public void instance_of(TypeBinding typeBinding) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_instanceof;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_instanceof);
	}
	writeUnsignedShort(constantPool.literalIndex(typeBinding));
}
public void invokeClassForName() {
	// invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokestatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokestatic);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangClassForName());
}
public void invokeConstructorGetConstructor() {
	// invokevirtual: java.lang.Class.getConstructor(java.lang.Class[])Ljava.lang.reflect.Constructor;
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangClassGetConstructor());
}
final public void invokeinterface(MethodBinding methodBinding) {
	// initialized to 1 to take into account this  immediately
	countLabels = 0;
	int argCount = 1;
	int id;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokeinterface;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokeinterface);
	}
	writeUnsignedShort(constantPool.literalIndex(methodBinding));
	for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
		if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
			argCount += 2;
		else
			argCount += 1;
	writeUnsignedByte(argCount);
	// Generate a  0 into the byte array. Like the array is already fill with 0, we just need to increment
	// the number of bytes.
	position++;
	classFileOffset++;
	if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
		stackDepth += (2 - argCount);
	else
		if (id == T_void)
			stackDepth -= argCount;
		else
			stackDepth += (1 - argCount);
	if (stackDepth > stackMax)
		stackMax = stackDepth;
}
public void invokeJavaLangErrorConstructor() {
	// invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokespecial;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokespecial);
	}
	stackDepth -= 2;
	writeUnsignedShort(constantPool.literalIndexForJavaLangErrorConstructor());
}
public void invokeNoClassDefFoundErrorStringConstructor() {
	// invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokespecial;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokespecial);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundErrorStringConstructor());
	stackDepth -= 2;
}
public void invokeObjectNewInstance() {
	// invokevirtual: java.lang.reflect.Constructor.newInstance(java.lang.Object[])Ljava.lang.Object;
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangReflectConstructorNewInstance());
}
final public void invokespecial(MethodBinding methodBinding) {
	// initialized to 1 to take into account this  immediately
	countLabels = 0;
	int argCount = 1;
	int id;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokespecial;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokespecial);
	}
	writeUnsignedShort(constantPool.literalIndex(methodBinding));
	if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
		// enclosing instances
		TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
		if (syntheticArgumentTypes != null) {
			for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
				if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
					argCount += 2;
				} else {
					argCount++;
				}
			}
		}
		// outer local variables
		SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
		if (syntheticArguments != null) {
			for (int i = 0, max = syntheticArguments.length; i < max; i++) {
				if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
					argCount += 2;
				} else {
					argCount++;
				}
			}
		}
	}
	for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
		if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
			argCount += 2;
		else
			argCount++;
	if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
		stackDepth += (2 - argCount);
	else
		if (id == T_void)
			stackDepth -= argCount;
		else
			stackDepth += (1 - argCount);
	if (stackDepth > stackMax)
		stackMax = stackDepth;
}
final public void invokestatic(MethodBinding methodBinding) {
	// initialized to 0 to take into account that there is no this for
	// a static method
	countLabels = 0;
	int argCount = 0;
	int id;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokestatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokestatic);
	}
	writeUnsignedShort(constantPool.literalIndex(methodBinding));
	for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
		if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
			argCount += 2;
		else
			argCount += 1;
	if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
		stackDepth += (2 - argCount);
	else
		if (id == T_void)
			stackDepth -= argCount;
		else
			stackDepth += (1 - argCount);
	if (stackDepth > stackMax)
		stackMax = stackDepth;
}
/**
 * The equivalent code performs a string conversion of the TOS
 * @param typeID <CODE>int</CODE>
 */
public void invokeStringBufferAppendForType(int typeID) {
	countLabels = 0;
	int usedTypeID;
	if (typeID == T_null)
		usedTypeID = T_String;
	else
		usedTypeID = typeID;
	// invokevirtual
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferAppend(typeID));
	if ((usedTypeID == T_long) || (usedTypeID == T_double))
		stackDepth -= 2;
	else
		stackDepth--;
}
public void invokeStringBufferDefaultConstructor() {
	// invokespecial: java.lang.StringBuffer.<init>()V
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokespecial;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokespecial);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferDefaultConstructor());
	stackDepth--;
}
public void invokeStringBufferStringConstructor() {
	// invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokespecial;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokespecial);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferConstructor());
	stackDepth -= 2;
}
public void invokeStringBufferToString() {
	// invokevirtual: StringBuffer.toString()Ljava.lang.String;
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferToString());
}
public void invokeStringIntern() {
	// invokevirtual: java.lang.String.intern()
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringIntern());
}
public void invokeStringValueOf(int typeID) {
	// invokestatic: java.lang.String.valueOf(argumentType)
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokestatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokestatic);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringValueOf(typeID));
}
public void invokeSystemExit() {
	// invokestatic: java.lang.System.exit(I)
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokestatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokestatic);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangSystemExitInt());
	stackDepth--; // int argument
}
public void invokeThrowableGetMessage() {
	// invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangThrowableGetMessage());
}
final public void invokevirtual(MethodBinding methodBinding) {
	// initialized to 1 to take into account this  immediately
	countLabels = 0;
	int argCount = 1;
	int id;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_invokevirtual;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_invokevirtual);
	}
	writeUnsignedShort(constantPool.literalIndex(methodBinding));
	for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
		if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
			argCount += 2;
		else
			argCount++;
	if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
		stackDepth += (2 - argCount);
	else
		if (id == T_void)
			stackDepth -= argCount;
		else
			stackDepth += (1 - argCount);
	if (stackDepth > stackMax)
		stackMax = stackDepth;
}
final public void ior() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ior;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ior);
	}
}
final public void irem() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_irem;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_irem);
	}
}
final public void ireturn() {
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ireturn;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ireturn);
	}
}
public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
	// Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
	if (initStateIndex == -1)
		return false;
	if (local.isArgument) {
		return true;
	}
	int position = local.id + maxFieldCount;
	MethodScope methodScope = scope.methodScope();
	// id is zero-based
	if (position < UnconditionalFlowInfo.BitCacheSize) {
		return (methodScope.definiteInits[initStateIndex] & (1L << position)) != 0; // use bits
	}
	// use extra vector
	long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
	if (extraInits == null)
		return false; // if vector not yet allocated, then not initialized
	int vectorIndex;
	if ((vectorIndex = (position / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
		return false; // if not enough room in vector, then not initialized 
	return ((extraInits[vectorIndex]) & (1L << (position % UnconditionalFlowInfo.BitCacheSize))) != 0;
}
final public void ishl() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ishl;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ishl);
	}
}
final public void ishr() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ishr;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ishr);
	}
}
final public void istore(int iArg) {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_istore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_istore);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_istore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_istore);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void istore_0() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_istore_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_istore_0);
	}
}
final public void istore_1() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_istore_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_istore_1);
	}
}
final public void istore_2() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_istore_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_istore_2);
	}
}
final public void istore_3() {
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_istore_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_istore_3);
	}
}
final public void isub() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_isub;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_isub);
	}
}
final public void iushr() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_iushr;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_iushr);
	}
}
final public void ixor() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ixor;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ixor);
	}
}
final public void jsr(Label lbl) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_jsr;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_jsr);
	}
	lbl.branch();
}
final public void jsr_w(Label lbl) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_jsr_w;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_jsr_w);
	}
	lbl.branchWide();
}
final public void l2d() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_l2d;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_l2d);
	}
}
final public void l2f() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_l2f;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_l2f);
	}
}
final public void l2i() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_l2i;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_l2i);
	}
}
final public void ladd() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ladd;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ladd);
	}
}
final public void laload() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_laload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_laload);
	}
}
final public void land() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_land;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_land);
	}
}
final public void lastore() {
	countLabels = 0;
	stackDepth -= 4;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lastore);
	}
}
final public void lcmp() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lcmp;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lcmp);
	}
}
final public void lconst_0() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lconst_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lconst_0);
	}
}
final public void lconst_1() {
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lconst_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lconst_1);
	}
}
final public void ldc(float constant) {
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (index > 255) {
		// Generate a ldc_w
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc_w;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ldc_w);
		}
		writeUnsignedShort(index);
	} else {
		// Generate a ldc
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ldc);
		}
		writeUnsignedByte(index);
	}
}
final public void ldc(int constant) {
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (index > 255) {
		// Generate a ldc_w
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc_w;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ldc_w);
		}
		writeUnsignedShort(index);
	} else {
		// Generate a ldc
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ldc);
		}
		writeUnsignedByte(index);
	}
}
final public void ldc(String constant) {
	countLabels = 0;
	int currentConstantPoolIndex = constantPool.currentIndex;
	int currentConstantPoolOffset = constantPool.currentOffset;
	int currentCodeStreamPosition = position;
	int index = constantPool.literalIndexForLdc(constant.toCharArray());
	if (index > 0) {
		// the string already exists inside the constant pool
		// we reuse the same index
		stackDepth++;
		if (stackDepth > stackMax)
			stackMax = stackDepth;
		if (index > 255) {
			// Generate a ldc_w
			try {
				position++;
				bCodeStream[classFileOffset++] = OPC_ldc_w;
			} catch (IndexOutOfBoundsException e) {
				resizeByteArray(OPC_ldc_w);
			}
			writeUnsignedShort(index);
		} else {
			// Generate a ldc
			try {
				position++;
				bCodeStream[classFileOffset++] = OPC_ldc;
			} catch (IndexOutOfBoundsException e) {
				resizeByteArray(OPC_ldc);
			}
			writeUnsignedByte(index);
		}
	} else {
		// the string is too big to be utf8-encoded in one pass.
		// we have to split it into different pieces.
		// first we clean all side-effects due to the code above
		// this case is very rare, so we can afford to lose time to handle it
		char[] constantChars = constant.toCharArray();
		position = currentCodeStreamPosition;
		constantPool.currentIndex = currentConstantPoolIndex;
		constantPool.currentOffset = currentConstantPoolOffset;
		constantPool.stringCache.remove(constantChars);
		constantPool.UTF8Cache.remove(constantChars);
		int i = 0;
		int length = 0;
		int constantLength = constant.length();
		byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
		int utf8encodingLength = 0;
		while ((length < 65532) && (i < constantLength)) {
			char current = constantChars[i];
			// we resize the byte array immediately if necessary
			if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
				System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)]), 0, length);
			}
			if ((current >= 0x0001) && (current <= 0x007F)) {
				// we only need one byte: ASCII table
				utf8encoding[length++] = (byte) current;
			} else {
				if (current > 0x07FF) {
					// we need 3 bytes
					utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
					utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
					utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
				} else {
					// we can be 0 or between 0x0080 and 0x07FF
					// In that case we only need 2 bytes
					utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
					utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
				}
			}
			i++;
		}
		// check if all the string is encoded (PR 1PR2DWJ)
		// the string is too big to be encoded in one pass
		newStringBuffer();
		dup();
		// write the first part
		char[] subChars = new char[i];
		System.arraycopy(constantChars, 0, subChars, 0, i);
		System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[length]), 0, length);
		index = constantPool.literalIndex(subChars, utf8encoding);
		stackDepth++;
		if (stackDepth > stackMax)
			stackMax = stackDepth;
		if (index > 255) {
			// Generate a ldc_w
			try {
				position++;
				bCodeStream[classFileOffset++] = OPC_ldc_w;
			} catch (IndexOutOfBoundsException e) {
				resizeByteArray(OPC_ldc_w);
			}
			writeUnsignedShort(index);
		} else {
			// Generate a ldc
			try {
				position++;
				bCodeStream[classFileOffset++] = OPC_ldc;
			} catch (IndexOutOfBoundsException e) {
				resizeByteArray(OPC_ldc);
			}
			writeUnsignedByte(index);
		}
		// write the remaining part
		invokeStringBufferStringConstructor();
		while (i < constantLength) {
			length = 0;
			utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
			int startIndex = i;
			while ((length < 65532) && (i < constantLength)) {
				char current = constantChars[i];
				// we resize the byte array immediately if necessary
				if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
					System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)]), 0, length);
				}
				if ((current >= 0x0001) && (current <= 0x007F)) {
					// we only need one byte: ASCII table
					utf8encoding[length++] = (byte) current;
				} else {
					if (current > 0x07FF) {
						// we need 3 bytes
						utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
						utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
						utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
					} else {
						// we can be 0 or between 0x0080 and 0x07FF
						// In that case we only need 2 bytes
						utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
						utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
					}
				}
				i++;
			}
			// the next part is done
			subChars = new char[i - startIndex];
			System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
			System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[length]), 0, length);
			index = constantPool.literalIndex(subChars, utf8encoding);
			stackDepth++;
			if (stackDepth > stackMax)
				stackMax = stackDepth;
			if (index > 255) {
				// Generate a ldc_w
				try {
					position++;
					bCodeStream[classFileOffset++] = OPC_ldc_w;
				} catch (IndexOutOfBoundsException e) {
					resizeByteArray(OPC_ldc_w);
				}
				writeUnsignedShort(index);
			} else {
				// Generate a ldc
				try {
					position++;
					bCodeStream[classFileOffset++] = OPC_ldc;
				} catch (IndexOutOfBoundsException e) {
					resizeByteArray(OPC_ldc);
				}
				writeUnsignedByte(index);
			}
			// now on the stack it should be a StringBuffer and a string.
			invokeStringBufferAppendForType(T_String);
		}
		invokeStringBufferToString();
		invokeStringIntern();
	}
}
final public void ldc2_w(double constant) {
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	// Generate a ldc2_w
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ldc2_w;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ldc2_w);
	}
	writeUnsignedShort(index);
}
final public void ldc2_w(long constant) {
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	// Generate a ldc2_w
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ldc2_w;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ldc2_w);
	}
	writeUnsignedShort(index);
}
final public void ldiv() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_ldiv;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_ldiv);
	}
}
final public void lload(int iArg) {
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_lload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_lload);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_lload;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_lload);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void lload_0() {
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lload_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lload_0);
	}
}
final public void lload_1() {
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lload_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lload_1);
	}
}
final public void lload_2() {
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lload_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lload_2);
	}
}
final public void lload_3() {
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lload_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lload_3);
	}
}
final public void lmul() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lmul;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lmul);
	}
}
final public void lneg() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lneg;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lneg);
	}
}
public final void load(LocalVariableBinding localBinding) {
	countLabels = 0;
	TypeBinding typeBinding = localBinding.type;
	int resolvedPosition = localBinding.resolvedPosition;
	// Using dedicated int bytecode
	if (typeBinding == IntBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.iload_0();
				break;
			case 1 :
				this.iload_1();
				break;
			case 2 :
				this.iload_2();
				break;
			case 3 :
				this.iload_3();
				break;
			default :
				this.iload(resolvedPosition);
		}
		return;
	}
	// Using dedicated float bytecode
	if (typeBinding == FloatBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.fload_0();
				break;
			case 1 :
				this.fload_1();
				break;
			case 2 :
				this.fload_2();
				break;
			case 3 :
				this.fload_3();
				break;
			default :
				this.fload(resolvedPosition);
		}
		return;
	}
	// Using dedicated long bytecode
	if (typeBinding == LongBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.lload_0();
				break;
			case 1 :
				this.lload_1();
				break;
			case 2 :
				this.lload_2();
				break;
			case 3 :
				this.lload_3();
				break;
			default :
				this.lload(resolvedPosition);
		}
		return;
	}
	// Using dedicated double bytecode
	if (typeBinding == DoubleBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.dload_0();
				break;
			case 1 :
				this.dload_1();
				break;
			case 2 :
				this.dload_2();
				break;
			case 3 :
				this.dload_3();
				break;
			default :
				this.dload(resolvedPosition);
		}
		return;
	}
	// boolean, byte, char and short are handled as int
	if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
		switch (resolvedPosition) {
			case 0 :
				this.iload_0();
				break;
			case 1 :
				this.iload_1();
				break;
			case 2 :
				this.iload_2();
				break;
			case 3 :
				this.iload_3();
				break;
			default :
				this.iload(resolvedPosition);
		}
		return;
	}

	// Reference object
	switch (resolvedPosition) {
		case 0 :
			this.aload_0();
			break;
		case 1 :
			this.aload_1();
			break;
		case 2 :
			this.aload_2();
			break;
		case 3 :
			this.aload_3();
			break;
		default :
			this.aload(resolvedPosition);
	}
}
public final void load(TypeBinding typeBinding, int resolvedPosition) {
	countLabels = 0;
	// Using dedicated int bytecode
	if (typeBinding == IntBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.iload_0();
				break;
			case 1 :
				this.iload_1();
				break;
			case 2 :
				this.iload_2();
				break;
			case 3 :
				this.iload_3();
				break;
			default :
				this.iload(resolvedPosition);
		}
		return;
	}
	// Using dedicated float bytecode
	if (typeBinding == FloatBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.fload_0();
				break;
			case 1 :
				this.fload_1();
				break;
			case 2 :
				this.fload_2();
				break;
			case 3 :
				this.fload_3();
				break;
			default :
				this.fload(resolvedPosition);
		}
		return;
	}
	// Using dedicated long bytecode
	if (typeBinding == LongBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.lload_0();
				break;
			case 1 :
				this.lload_1();
				break;
			case 2 :
				this.lload_2();
				break;
			case 3 :
				this.lload_3();
				break;
			default :
				this.lload(resolvedPosition);
		}
		return;
	}
	// Using dedicated double bytecode
	if (typeBinding == DoubleBinding) {
		switch (resolvedPosition) {
			case 0 :
				this.dload_0();
				break;
			case 1 :
				this.dload_1();
				break;
			case 2 :
				this.dload_2();
				break;
			case 3 :
				this.dload_3();
				break;
			default :
				this.dload(resolvedPosition);
		}
		return;
	}
	// boolean, byte, char and short are handled as int
	if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
		switch (resolvedPosition) {
			case 0 :
				this.iload_0();
				break;
			case 1 :
				this.iload_1();
				break;
			case 2 :
				this.iload_2();
				break;
			case 3 :
				this.iload_3();
				break;
			default :
				this.iload(resolvedPosition);
		}
		return;
	}

	// Reference object
	switch (resolvedPosition) {
		case 0 :
			this.aload_0();
			break;
		case 1 :
			this.aload_1();
			break;
		case 2 :
			this.aload_2();
			break;
		case 3 :
			this.aload_3();
			break;
		default :
			this.aload(resolvedPosition);
	}
}
public final void loadInt(int resolvedPosition) {
	// Using dedicated int bytecode
	switch (resolvedPosition) {
		case 0 :
			this.iload_0();
			break;
		case 1 :
			this.iload_1();
			break;
		case 2 :
			this.iload_2();
			break;
		case 3 :
			this.iload_3();
			break;
		default :
			this.iload(resolvedPosition);
	}
}
public final void loadObject(int resolvedPosition) {
	switch (resolvedPosition) {
		case 0 :
			this.aload_0();
			break;
		case 1 :
			this.aload_1();
			break;
		case 2 :
			this.aload_2();
			break;
		case 3 :
			this.aload_3();
			break;
		default :
			this.aload(resolvedPosition);
	}
}
final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
	countLabels = 0;
	stackDepth--;
	int length = keys.length;
	int pos = position;
	defaultLabel.placeInstruction();
	for (int i = 0; i < length; i++) {
		casesLabel[i].placeInstruction();
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lookupswitch;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lookupswitch);
	}
	for (int i = (3 - (pos % 4)); i > 0; i--) {
		position++; // Padding
		classFileOffset++;
	}
	defaultLabel.branch();
	writeSignedWord(length);
	for (int i = 0; i < length; i++) {
		writeSignedWord(keys[sortedIndexes[i]]);
		casesLabel[sortedIndexes[i]].branch();
	}
}
final public void lor() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lor;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lor);
	}
}
final public void lrem() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lrem;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lrem);
	}
}
final public void lreturn() {
	countLabels = 0;
	stackDepth -= 2;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lreturn;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lreturn);
	}
}
final public void lshl() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lshl;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lshl);
	}
}
final public void lshr() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lshr;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lshr);
	}
}
final public void lstore(int iArg) {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (iArg > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_lstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_lstore);
		}
		writeUnsignedShort(iArg);
	} else {
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_lstore;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_lstore);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) iArg;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) iArg);
		}
	}
}
final public void lstore_0() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lstore_0;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lstore_0);
	}
}
final public void lstore_1() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lstore_1;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lstore_1);
	}
}
final public void lstore_2() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lstore_2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lstore_2);
	}
}
final public void lstore_3() {
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lstore_3;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lstore_3);
	}
}
final public void lsub() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lsub;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lsub);
	}
}
final public void lushr() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lushr;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lushr);
	}
}
final public void lxor() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_lxor;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_lxor);
	}
}
final public void monitorenter() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_monitorenter;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_monitorenter);
	}
}
final public void monitorexit() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_monitorexit;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_monitorexit);
	}
}
final public void multianewarray(TypeBinding typeBinding, int dimensions) {
	countLabels = 0;
	stackDepth += (1 - dimensions);
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_multianewarray;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_multianewarray);
	}
	writeUnsignedShort(constantPool.literalIndex(typeBinding));
	writeUnsignedByte(dimensions);
}
public static void needImplementation() {
}
/**
 * We didn't call it new, because there is a conflit with the new keyword
 */
final public void new_(TypeBinding typeBinding) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_new;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_new);
	}
	writeUnsignedShort(constantPool.literalIndex(typeBinding));
}
final public void newarray(int array_Type) {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_newarray;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_newarray);
	}
	writeUnsignedByte(array_Type);
}
public void newArray(Scope scope, ArrayBinding arrayBinding) {
	TypeBinding component = arrayBinding.elementsType(scope);
	switch (component.id) {
		case T_int :
			this.newarray(10);
			break;
		case T_byte :
			this.newarray(8);
			break;
		case T_boolean :
			this.newarray(4);
			break;
		case T_short :
			this.newarray(9);
			break;
		case T_char :
			this.newarray(5);
			break;
		case T_long :
			this.newarray(11);
			break;
		case T_float :
			this.newarray(6);
			break;
		case T_double :
			this.newarray(7);
			break;
		default :
			this.anewarray(component);
	}
}
public void newJavaLangError() {
	// new: java.lang.Error
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_new;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_new);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangError());
}
public void newNoClassDefFoundError() { // new: java.lang.NoClassDefFoundError
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_new;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_new);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundError());
}
public void newStringBuffer() { // new: java.lang.StringBuffer
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_new;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_new);
	}
	writeUnsignedShort(constantPool.literalIndexForJavaLangStringBuffer());
}
public void newWrapperFor(int typeID) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_new;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_new);
	}
	switch (typeID) {
		case T_int : // new: java.lang.Integer
			writeUnsignedShort(constantPool.literalIndexForJavaLangInteger());
			break;
		case T_boolean : // new: java.lang.Boolean
			writeUnsignedShort(constantPool.literalIndexForJavaLangBoolean());
			break;
		case T_byte : // new: java.lang.Byte
			writeUnsignedShort(constantPool.literalIndexForJavaLangByte());
			break;
		case T_char : // new: java.lang.Character
			writeUnsignedShort(constantPool.literalIndexForJavaLangCharacter());
			break;
		case T_float : // new: java.lang.Float
			writeUnsignedShort(constantPool.literalIndexForJavaLangFloat());
			break;
		case T_double : // new: java.lang.Double
			writeUnsignedShort(constantPool.literalIndexForJavaLangDouble());
			break;
		case T_short : // new: java.lang.Short
			writeUnsignedShort(constantPool.literalIndexForJavaLangShort());
			break;
		case T_long : // new: java.lang.Long
			writeUnsignedShort(constantPool.literalIndexForJavaLangLong());
			break;
		case T_void : // new: java.lang.Void
			writeUnsignedShort(constantPool.literalIndexForJavaLangVoid());
	}
}
final public void nop() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_nop;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_nop);
	}
}
final public void pop() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_pop;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_pop);
	}
}
final public void pop2() {
	countLabels = 0;
	stackDepth -= 2;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_pop2;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_pop2);
	}
}
final public void putfield(FieldBinding fieldBinding) {
	countLabels = 0;
	int id;
	if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
		stackDepth -= 3;
	else
		stackDepth -= 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_putfield;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_putfield);
	}
	writeUnsignedShort(constantPool.literalIndex(fieldBinding));
}
final public void putstatic(FieldBinding fieldBinding) {
	countLabels = 0;
	int id;
	if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
		stackDepth -= 2;
	else
		stackDepth -= 1;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_putstatic;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_putstatic);
	}
	writeUnsignedShort(constantPool.literalIndex(fieldBinding));
}
public void record(LocalVariableBinding local) {
	if (!generateLocalVariableTableAttributes)
		return;
	if (allLocalsCounter == locals.length) {
		// resize the collection
		System.arraycopy(locals, 0, (locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT]), 0, allLocalsCounter);
	}
	locals[allLocalsCounter++] = local;
	local.initializationPCs = new int[4];
	local.initializationCount = 0;
}
public void recordPositionsFrom(int startPC, AstNode node) {

	/* Record positions in the table, only if nothing has 
	 * already been recorded. Since we output them on the way 
	 * up (children first for more specific info)
	 * The pcToSourceMap table is always sorted.
	 */

	/** OLD CODE
	int startPos, endPos;
	int[] lastEntry;
	if (!generateLineNumberAttributes && !generateLocalVariableTableAttributes)
	return;
	if ((startPos = node.sourceStart()) == 0)
	return;
	if ((endPos = node.sourceEnd()) == 0)
	return;
	
	// Widening an existing entry that already has the same source positions
	if ((pcToSourceMapSize > 0) && (pcToSourceMap[pcToSourceMapSize - 1][2] == startPos) && (pcToSourceMap[pcToSourceMapSize - 1][3] == endPos)) {
	if (pcToSourceMap[pcToSourceMapSize - 1][0] > startPC)
	pcToSourceMap[pcToSourceMapSize - 1][0] = startPC;
	pcToSourceMap[pcToSourceMapSize - 1][1] = position;
	return;
	}
	if (pcToSourceMapSize == pcToSourceMap.length) {
	// resize the array pcToSourceMap		
	System.arraycopy(pcToSourceMap, 0, (pcToSourceMap = new int[pcToSourceMapSize * 2][]), 0, pcToSourceMapSize);
	}
	pcToSourceMap[pcToSourceMapSize++] = new int[] {startPC, position, startPos, endPos};
	
	*/
	int startPos;
	if (!generateLineNumberAttributes)
		return;
	if ((startPos = node.sourceStart()) == 0)
		return;

	// no code generated for this node. e.g. field without any initialization
	if (position == startPC)
		return;

	// Widening an existing entry that already has the same source positions
	if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
		// resize the array pcToSourceMap
		System.arraycopy(pcToSourceMap, 0, (pcToSourceMap = new int[pcToSourceMapSize << 1]), 0, pcToSourceMapSize);
	}
	int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, startPos);
	// lastEntryPC represents the endPC of the lastEntry.
	if (pcToSourceMapSize > 0) {
		// in this case there is already an entry in the table
		if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
			if (startPC < lastEntryPC) {
				// we forgot to add an entry.
				// search if an existing entry exists for startPC
				int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
				if (insertionIndex != -1) {
					// there is no existing entry starting with startPC.
					int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
					/* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
						in this case it is relevant to widen this entry instead of creating a new one.
						line1: this(a,
						  b,
						  c);
						with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
						aload0 bytecode. The first entry is the one for the argument a.
						But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
						So we widen the existing entry (if there is one) or we create a new entry with the startPC.
					*/
					if (existingEntryIndex != -1) {
						// widen existing entry
						pcToSourceMap[existingEntryIndex] = startPC;
					} else {
						// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
						System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
						pcToSourceMap[insertionIndex++] = startPC;
						pcToSourceMap[insertionIndex] = newLine;
						pcToSourceMapSize += 2;
					}
				}
				if (position != lastEntryPC) { // no bytecode since last entry pc
					pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
					pcToSourceMap[pcToSourceMapSize++] = newLine;
				}
			} else {
				// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
				pcToSourceMap[pcToSourceMapSize++] = startPC;
				pcToSourceMap[pcToSourceMapSize++] = newLine;
			}
		} else {
			/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
			   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
			*/	
			if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
				int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
				if (insertionIndex != -1) {
					// widen the existing entry
					// we have to figure out if we need to move the last entry at another location to keep a sorted table
					if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
						System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
						pcToSourceMap[insertionIndex++] = startPC;
						pcToSourceMap[insertionIndex] = newLine;						
					} else {
						pcToSourceMap[pcToSourceMapSize - 2] = startPC;
					}
				}
			}
		}
		lastEntryPC = position;
	} else {
		// record the first entry
		pcToSourceMap[pcToSourceMapSize++] = startPC;
		pcToSourceMap[pcToSourceMapSize++] = newLine;
		lastEntryPC = position;
	}
}
/**
 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
 */
public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
	int length;
	if (exceptionHandlersNumber >= (length = exceptionHandlers.length)) {
		// resize the exception handlers table
		System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
	}
	// no need to resize. So just add the new exception label
	exceptionHandlers[exceptionHandlersNumber++] = anExceptionLabel;
}
public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
	// given some flow info, make sure we did not loose some variables initialization
	// if this happens, then we must update their pc entries to reflect it in debug attributes
	if (!generateLocalVariableTableAttributes)
		return;
/*	if (initStateIndex == lastInitStateIndexWhenRemovingInits)
		return;
		
	lastInitStateIndexWhenRemovingInits = initStateIndex;
	if (lastInitStateIndexWhenAddingInits != initStateIndex){
		lastInitStateIndexWhenAddingInits = -2;// reinitialize add index 
		// add(1)-remove(1)-add(1) -> ignore second add
		// add(1)-remove(2)-add(1) -> perform second add
	}*/
	for (int i = 0; i < visibleLocalsCount; i++) {
		LocalVariableBinding localBinding = visibleLocals[i];
		if (localBinding != null) {
			if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
				if (localBinding.initializationCount > 0) {
					localBinding.recordInitializationEndPC(position);
				}
			}
		}
	}
}
/**
 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
public void reset(AbstractMethodDeclaration methodDeclaration, ClassFile classFile) {
	init(classFile);
	this.methodDeclaration = methodDeclaration;
	preserveUnusedLocals = methodDeclaration.scope.problemReporter().options.preserveAllLocalVariables;
	initializeMaxLocals(methodDeclaration.binding);
}
/**
 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
public void resetForProblemClinit(ClassFile classFile) {
	init(classFile);
	maxLocals = 0;
}
protected final void resizeByteArray() {
	int actualLength = bCodeStream.length;
	int requiredSize = actualLength + growFactor;
	if (classFileOffset > requiredSize) {
		requiredSize = classFileOffset + growFactor;
	}
	System.arraycopy(bCodeStream, 0, (bCodeStream = new byte[requiredSize]), 0, actualLength);
}
/**
 * This method is used to resize the internal byte array in 
 * case of a ArrayOutOfBoundsException when adding the value b.
 * Resize and add the new byte b inside the array.
 * @param b byte
 */
protected final void resizeByteArray(byte b) {
	resizeByteArray();
	bCodeStream[classFileOffset - 1] = b;
}
final public void ret(int index) {
	countLabels = 0;
	if (index > 255) { // Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_wide;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_wide);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ret;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ret);
		}
		writeUnsignedShort(index);
	} else { // Don't Widen
		try {
			position++;
			bCodeStream[classFileOffset++] = OPC_ret;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray(OPC_ret);
		}
		try {
			position++;
			bCodeStream[classFileOffset++] = (byte) index;
		} catch (IndexOutOfBoundsException e) {
			resizeByteArray((byte) index);
		}
	}
}
final public void return_() {
	countLabels = 0;
	// the stackDepth should be equal to 0 
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_return;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_return);
	}
}
final public void saload() {
	countLabels = 0;
	stackDepth--;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_saload;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_saload);
	}
}
final public void sastore() {
	countLabels = 0;
	stackDepth -= 3;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_sastore;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_sastore);
	}
}
/**
 * @param operatorConstant int
 * @param type_ID int
 */
public void sendOperator(int operatorConstant, int type_ID) {
	switch (type_ID) {
		case T_int :
		case T_boolean :
		case T_char :
		case T_byte :
		case T_short :
			switch (operatorConstant) {
				case PLUS :
					this.iadd();
					break;
				case MINUS :
					this.isub();
					break;
				case MULTIPLY :
					this.imul();
					break;
				case DIVIDE :
					this.idiv();
					break;
				case REMAINDER :
					this.irem();
					break;
				case LEFT_SHIFT :
					this.ishl();
					break;
				case RIGHT_SHIFT :
					this.ishr();
					break;
				case UNSIGNED_RIGHT_SHIFT :
					this.iushr();
					break;
				case AND :
					this.iand();
					break;
				case OR :
					this.ior();
					break;
				case XOR :
					this.ixor();
					break;
			}
			break;
		case T_long :
			switch (operatorConstant) {
				case PLUS :
					this.ladd();
					break;
				case MINUS :
					this.lsub();
					break;
				case MULTIPLY :
					this.lmul();
					break;
				case DIVIDE :
					this.ldiv();
					break;
				case REMAINDER :
					this.lrem();
					break;
				case LEFT_SHIFT :
					this.lshl();
					break;
				case RIGHT_SHIFT :
					this.lshr();
					break;
				case UNSIGNED_RIGHT_SHIFT :
					this.lushr();
					break;
				case AND :
					this.land();
					break;
				case OR :
					this.lor();
					break;
				case XOR :
					this.lxor();
					break;
			}
			break;
		case T_float :
			switch (operatorConstant) {
				case PLUS :
					this.fadd();
					break;
				case MINUS :
					this.fsub();
					break;
				case MULTIPLY :
					this.fmul();
					break;
				case DIVIDE :
					this.fdiv();
					break;
				case REMAINDER :
					this.frem();
			}
			break;
		case T_double :
			switch (operatorConstant) {
				case PLUS :
					this.dadd();
					break;
				case MINUS :
					this.dsub();
					break;
				case MULTIPLY :
					this.dmul();
					break;
				case DIVIDE :
					this.ddiv();
					break;
				case REMAINDER :
					this.drem();
			}
	}
}
final public void sipush(int s) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_sipush;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_sipush);
	}
	writeSignedShort(s);
}
public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
	int lo = lo0;
	int hi = hi0;
	int mid;
	if (hi0 > lo0) {
		/* Arbitrarily establishing partition element as the midpoint of
		  * the array.
		  */
		mid = tab[ (lo0 + hi0) / 2];
		// loop through the array until indices cross
		while (lo <= hi) {
			/* find the first element that is greater than or equal to 
			 * the partition element starting from the left Index.
			 */
			while ((lo < hi0) && (tab[lo] < mid))
				++lo;
			/* find an element that is smaller than or equal to 
			 * the partition element starting from the right Index.
			 */
			while ((hi > lo0) && (tab[hi] > mid))
				--hi;
			// if the indexes have not crossed, swap
			if (lo <= hi) {
				swap(tab, lo, hi, result);
				++lo;
				--hi;
			}
		}
		/* If the right index has not reached the left side of array
		  * must now sort the left partition.
		  */
		if (lo0 < hi)
			sort(tab, lo0, hi, result);
		/* If the left index has not reached the right side of array
		  * must now sort the right partition.
		  */
		if (lo < hi0)
			sort(tab, lo, hi0, result);
	}
}
public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
	TypeBinding type = localBinding.type;
	int position = localBinding.resolvedPosition;
	// Using dedicated int bytecode
	if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
		if (valueRequired)
			this.dup();
		switch (position) {
			case 0 :
				this.istore_0();
				break;
			case 1 :
				this.istore_1();
				break;
			case 2 :
				this.istore_2();
				break;
			case 3 :
				this.istore_3();
				break;
			default :
				this.istore(position);
		}
		return;
	}
	// Using dedicated float bytecode
	if (type == FloatBinding) {
		if (valueRequired)
			this.dup();
		switch (position) {
			case 0 :
				this.fstore_0();
				break;
			case 1 :
				this.fstore_1();
				break;
			case 2 :
				this.fstore_2();
				break;
			case 3 :
				this.fstore_3();
				break;
			default :
				this.fstore(position);
		}
		return;
	}
	// Using dedicated long bytecode
	if (type == LongBinding) {
		if (valueRequired)
			this.dup2();
		switch (position) {
			case 0 :
				this.lstore_0();
				break;
			case 1 :
				this.lstore_1();
				break;
			case 2 :
				this.lstore_2();
				break;
			case 3 :
				this.lstore_3();
				break;
			default :
				this.lstore(position);
		}
		return;
	}
	// Using dedicated double bytecode
	if (type == DoubleBinding) {
		if (valueRequired)
			this.dup2();
		switch (position) {
			case 0 :
				this.dstore_0();
				break;
			case 1 :
				this.dstore_1();
				break;
			case 2 :
				this.dstore_2();
				break;
			case 3 :
				this.dstore_3();
				break;
			default :
				this.dstore(position);
		}
		return;
	}
	// Reference object
	if (valueRequired)
		this.dup();
	switch (position) {
		case 0 :
			this.astore_0();
			break;
		case 1 :
			this.astore_1();
			break;
		case 2 :
			this.astore_2();
			break;
		case 3 :
			this.astore_3();
			break;
		default :
			this.astore(position);
	}
}
public final void store(TypeBinding type, int position) {
	// Using dedicated int bytecode
	if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
		switch (position) {
			case 0 :
				this.istore_0();
				break;
			case 1 :
				this.istore_1();
				break;
			case 2 :
				this.istore_2();
				break;
			case 3 :
				this.istore_3();
				break;
			default :
				this.istore(position);
		}
		return;
	}
	// Using dedicated float bytecode
	if (type == FloatBinding) {
		switch (position) {
			case 0 :
				this.fstore_0();
				break;
			case 1 :
				this.fstore_1();
				break;
			case 2 :
				this.fstore_2();
				break;
			case 3 :
				this.fstore_3();
				break;
			default :
				this.fstore(position);
		}
		return;
	}
	// Using dedicated long bytecode
	if (type == LongBinding) {
		switch (position) {
			case 0 :
				this.lstore_0();
				break;
			case 1 :
				this.lstore_1();
				break;
			case 2 :
				this.lstore_2();
				break;
			case 3 :
				this.lstore_3();
				break;
			default :
				this.lstore(position);
		}
		return;
	}
	// Using dedicated double bytecode
	if (type == DoubleBinding) {
		switch (position) {
			case 0 :
				this.dstore_0();
				break;
			case 1 :
				this.dstore_1();
				break;
			case 2 :
				this.dstore_2();
				break;
			case 3 :
				this.dstore_3();
				break;
			default :
				this.dstore(position);
		}
		return;
	}
	// Reference object
	switch (position) {
		case 0 :
			this.astore_0();
			break;
		case 1 :
			this.astore_1();
			break;
		case 2 :
			this.astore_2();
			break;
		case 3 :
			this.astore_3();
			break;
		default :
			this.astore(position);
	}
}
public final void storeInt(int position) {
	switch (position) {
		case 0 :
			this.istore_0();
			break;
		case 1 :
			this.istore_1();
			break;
		case 2 :
			this.istore_2();
			break;
		case 3 :
			this.istore_3();
			break;
		default :
			this.istore(position);
	}
}
public final void storeObject(int position) {
	switch (position) {
		case 0 :
			this.astore_0();
			break;
		case 1 :
			this.astore_1();
			break;
		case 2 :
			this.astore_2();
			break;
		case 3 :
			this.astore_3();
			break;
		default :
			this.astore(position);
	}
}
final public void swap() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_swap;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_swap);
	}
}
private static final void swap(int a[], int i, int j, int result[]) {
	int T;
	T = a[i];
	a[i] = a[j];
	a[j] = T;
	T = result[j];
	result[j] = result[i];
	result[i] = T;
}
final public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
	countLabels = 0;
	stackDepth--;
	int length = casesLabel.length;
	int pos = position;
	defaultLabel.placeInstruction();
	for (int i = 0; i < length; i++)
		casesLabel[i].placeInstruction();
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_tableswitch;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_tableswitch);
	}
	for (int i = (3 - (pos % 4)); i > 0; i--) {
		position++; // Padding
		classFileOffset++;
	}
	defaultLabel.branch();
	writeSignedWord(low);
	writeSignedWord(high);
	int j = low;
	// the index j is used to know if the index i is one of the missing entries in case of an 
	// optimized tableswitch
	for (int i = low; i <= high; i++) {
		int index;
		int key = keys[index = sortedIndexes[j - low]];
		if (key == i) {
			casesLabel[index].branch();
			j++;
		} else {
			defaultLabel.branch();
		}
	}
}
public String toString() {
	StringBuffer buffer = new StringBuffer("( position:"/*nonNLS*/);
	buffer.append(position);
	buffer.append(",\nstackDepth:"/*nonNLS*/);
	buffer.append(stackDepth);
	buffer.append(",\nmaxStack:"/*nonNLS*/);
	buffer.append(stackMax);
	buffer.append(",\nmaxLocals:"/*nonNLS*/);
	buffer.append(maxLocals);
	buffer.append(")"/*nonNLS*/);
	return buffer.toString();
}
public void updateLastRecordedEndPC(int pos) {

	/* Tune positions in the table, this is due to some 
	 * extra bytecodes being
	 * added to some user code (jumps). */
	/** OLD CODE
		if (!generateLineNumberAttributes)
			return;
		pcToSourceMap[pcToSourceMapSize - 1][1] = position;
		// need to update the initialization endPC in case of generation of local variable attributes.
		updateLocalVariablesAttribute(pos);	
	*/	

	if (!generateLineNumberAttributes)
		return;
	// need to update the initialization endPC in case of generation of local variable attributes.
	updateLocalVariablesAttribute(pos);
}
public void updateLocalVariablesAttribute(int pos) {
	// need to update the initialization endPC in case of generation of local variable attributes.
	if (generateLocalVariableTableAttributes) {
		for (int i = 0, max = locals.length; i < max; i++) {
			LocalVariableBinding local = locals[i];
			if ((local != null) && (local.initializationCount > 0)) {
				if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
					local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
				}
			}
		}
	}
}
final public void wide() {
	countLabels = 0;
	try {
		position++;
		bCodeStream[classFileOffset++] = OPC_wide;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(OPC_wide);
	}
}
public final void writeByte(byte b) {
	try {
		position++;
		bCodeStream[classFileOffset++] = b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray(b);
	}
}
public final void writeByteAtPos(int pos, byte b) {
	try {
		bCodeStream[pos] = b;
	} catch (IndexOutOfBoundsException ex) {
		resizeByteArray();
		bCodeStream[pos] = b;
	}
}
/**
 * Write a unsigned 8 bits value into the byte array
 * @param 
 */
public final void writeSignedByte(int b) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) b);
	}
}
/**
 * Write a signed 16 bits value into the byte array
 * @param 
 */
public final void writeSignedShort(int b) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (b >> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (b >> 8));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) b);
	}
}
public final void writeSignedShort(int pos, int b) {
	int currentOffset = startingClassFileOffset + pos;
	try {
		bCodeStream[currentOffset] = (byte) (b >> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset] = (byte) (b >> 8);
	}
	try {
		bCodeStream[currentOffset + 1] = (byte) b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset + 1] = (byte) b;
	}
}
public final void writeSignedWord(int value) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) ((value & 0xFF000000) >> 24));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) ((value & 0xFF0000) >> 16));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) ((value & 0xFF00) >> 8));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (value & 0xFF));
	}
}
public final void writeSignedWord(int pos, int value) {
	int currentOffset = startingClassFileOffset + pos;
	try {
		bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset-1] = (byte) ((value & 0xFF000000) >> 24);
	}
	try {
		bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset-1] = (byte) ((value & 0xFF0000) >> 16);
	}
	try {
		bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset-1] = (byte) ((value & 0xFF00) >> 8);
	}
	try {
		bCodeStream[currentOffset++] = (byte) (value & 0xFF);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray();
		bCodeStream[currentOffset-1] = (byte) (value & 0xFF);
	}
}
/**
 * Write a unsigned 8 bits value into the byte array
 * @param 
 */
public final void writeUnsignedByte(int b) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) b);
	}
}
/**
 * Write a unsigned 16 bits value into the byte array
 * @param 
 */
public final void writeUnsignedShort(int b) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (b >>> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (b >>> 8));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) b;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) b);
	}
}
/**
 * Write a unsigned 32 bits value into the byte array
 * @param 
 */
public final void writeUnsignedWord(int value) {
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (value >>> 24);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (value >>> 24));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (value >>> 16);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (value >>> 16));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) (value >>> 8);
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) (value >>> 8));
	}
	try {
		position++;
		bCodeStream[classFileOffset++] = (byte) value;
	} catch (IndexOutOfBoundsException e) {
		resizeByteArray((byte) value);
	}
}
}
