/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;

import org.eclipse.jdt.core.compiler.CharOperation;
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, Opcodes, BaseTypes, TypeConstants, TypeIds {

	public static final boolean DEBUG = false;
	
	// 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 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 exceptionHandlersIndex;
	public int exceptionHandlersCounter;
	
	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;
	// to handle goto_w
	public boolean wideMode = false;
	public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
	
	// target level to manage different code generation between different target levels
	private long targetLevel;
	
public CodeStream(ClassFile classFile, long targetLevel) {
	this.targetLevel = targetLevel;
	this.generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
	this.generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
	if (this.generateLineNumberAttributes) {
		this.lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
	}
}
final public void aaload() {
	if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aaload;
}
final public void aastore() {
	if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aastore;
}
final public void aconst_null() {
	if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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) {
	if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_aload;
		writeUnsignedShort(iArg);
	} else {
		// Don't need to use the wide bytecode
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_aload;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void aload_0() {
	if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aload_0;
}
final public void aload_1() {
	if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aload_1;
}
final public void aload_2() {
	if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aload_2;
}
final public void aload_3() {
	if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_aload_3;
}
public final void anewarray(TypeBinding typeBinding) {
	if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_anewarray;
	writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void areturn() {
	if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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() {
	if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_arraylength;
}
final public void astore(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position+=2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_astore;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position+=2;
		bCodeStream[classFileOffset++] = OPC_astore;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void astore_0() {
	if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_astore_0;
}
final public void astore_1() {
	if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_astore_1;
}
final public void astore_2() {
	if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_astore_2;
}
final public void astore_3() {
	if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_astore_3;
}
final public void athrow() {
	if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_athrow;
}
final public void baload() {
	if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_baload;
}
final public void bastore() {
	if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_bastore;
}
final public void bipush(byte b) {
	if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 1 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 2;
	bCodeStream[classFileOffset++] = OPC_bipush;
	bCodeStream[classFileOffset++] = b;
}
final public void caload() {
	if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_caload;
}
final public void castore() {
	if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_castore;
}
public final void checkcast(TypeBinding typeBinding) {
	if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_checkcast;
	writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void d2f() {
	if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_d2f;
}
final public void d2i() {
	if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_d2i;
}
final public void d2l() {
	if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_d2l;
}
final public void dadd() {
	if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dadd;
}
final public void daload() {
	if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_daload;
}
final public void dastore() {
	if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 4;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dastore;
}
final public void dcmpg() {
	if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dcmpg;
}
final public void dcmpl() {
	if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dcmpl;
}
final public void dconst_0() {
	if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dconst_0;
}
final public void dconst_1() {
	if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dconst_1;
}
final public void ddiv() {
	if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ddiv;
}
public void decrStackSize(int offset) {
	stackDepth -= offset;
}
final public void dload(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
	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
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_dload;
		writeUnsignedShort(iArg);
	} else {
		// Don't need to use the wide bytecode
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_dload;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void dload_0() {
	if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dload_0;
}
final public void dload_1() {
	if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dload_1;
}
final public void dload_2() {
	if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dload_2;
}
final public void dload_3() {
	if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dload_3;
}
final public void dmul() {
	if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dmul;
}
final public void dneg() {
	if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dneg;
}
final public void drem() {
	if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_drem;
}
final public void dreturn() {
	if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dreturn;
}
final public void dstore(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_dstore;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_dstore;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void dstore_0() {
	if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dstore_0;
}
final public void dstore_1() {
	if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dstore_1;
}
final public void dstore_2() {
	if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dstore_2;
}
final public void dstore_3() {
	if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dstore_3;
}
final public void dsub() {
	if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dsub;
}
final public void dup() {
	if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup;
}
final public void dup_x1() {
	if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup_x1;
}
final public void dup_x2() {
	if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup_x2;
}
final public void dup2() {
	if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup2;
}
final public void dup2_x1() {
	if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup2_x1;
}
final public void dup2_x2() {
	if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_dup2_x2;
}
public void exitUserScope(BlockScope currentScope) {
	// mark all the scope's locals as loosing their definite assignment

	if (!generateLocalVariableTableAttributes)
		return;
	while (visibleLocalsCount > 0) {
		LocalVariableBinding visibleLocal = visibleLocals[this.visibleLocalsCount - 1];
		if (visibleLocal == null)
			continue;
		if (visibleLocal.declaringScope != currentScope) // left currentScope
			break;

		// there maybe some some preserved locals never initialized
		if (visibleLocal.initializationCount > 0){
			visibleLocal.recordInitializationEndPC(position);
		}
		visibleLocals[--this.visibleLocalsCount] = null; // this variable is no longer visible afterwards
	}
}
final public void f2d() {
	if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_f2d;
}
final public void f2i() {
	if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_f2i;
}
final public void f2l() {
	if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_f2l;
}
final public void fadd() {
	if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fadd;
}
final public void faload() {
	if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_faload;
}
final public void fastore() {
	if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fastore;
}
final public void fcmpg() {
	if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fcmpg;
}
final public void fcmpl() {
	if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fcmpl;
}
final public void fconst_0() {
	if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fconst_0;
}
final public void fconst_1() {
	if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fconst_1;
}
final public void fconst_2() {
	if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fconst_2;
}
final public void fdiv() {
	if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fdiv;
}
final public void fload(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_fload;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_fload;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void fload_0() {
	if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fload_0;
}
final public void fload_1() {
	if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fload_1;
}
final public void fload_2() {
	if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fload_2;
}
final public void fload_3() {
	if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fload_3;
}
final public void fmul() {
	if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fmul;
}
final public void fneg() {
	if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fneg;
}
final public void frem() {
	if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_frem;
}
final public void freturn() {
	if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_freturn;
}
final public void fstore(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_fstore;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_fstore;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void fstore_0() {
	if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fstore_0;
}
final public void fstore_1() {
	if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fstore_1;
}
final public void fstore_2() {
	if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fstore_2;
}
final public void fstore_3() {
	if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_fstore_3;
}
final public void fsub() {
	if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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() && accessedType != NullBinding) {
		this.getTYPE(accessedType.id);
		return;
	}

	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
		// generation using the new ldc_w bytecode
		this.ldc(accessedType);
	} else {
		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, BaseTypes.NullBinding /* represents ClassNotFoundException*/);
		this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
		this.invokeClassForName();
	
		/* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
		if (accessedType == BaseTypes.NullBinding) {
			this.ldc("java.lang.Object"); //$NON-NLS-1$
		} else if (accessedType.isArrayType()) {
			this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
		} else {
			// we make it an array type (to avoid class initialization)
			this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
		}
		this.invokeClassForName();
		if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
			this.invokeJavaLangClassGetComponentType();
		}	
		*/
		/* 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();
		stackDepth = saveStackSize;
		endLabel.place();
	}
}
/**
 * This method generates the code attribute bytecode
 */
final public void generateCodeAttributeForProblemMethod(String problemMessage) {
	newJavaLangError();
	dup();
	ldc(problemMessage);
	invokeJavaLangErrorConstructor();
	athrow();
}
public void generateConstant(Constant constant, int implicitConversionCode) {
	int targetTypeID = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
	if (targetTypeID != 0) {
		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_JavaLangString :
				ldc(constant.stringValue());
		}
	} else {
		ldc(constant.stringValue());
	}
	if ((implicitConversionCode & BOXING) != 0) {
		// need boxing
		generateBoxingConversion(targetTypeID);
	}
}

/**
 * Generates the sequence of instructions which will perform the conversion of the expression
 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
 * @param implicitConversionCode int
 */
public void generateImplicitConversion(int implicitConversionCode) {
	if ((implicitConversionCode & UNBOXING) != 0) {
		final int typeId = implicitConversionCode & COMPILE_TYPE_MASK;
		generateUnboxingConversion(typeId);
		// unboxing can further involve base type conversions
	}
	switch (implicitConversionCode & IMPLICIT_CONVERSION_MASK) {
		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();
	}
	if ((implicitConversionCode & BOXING) != 0) {
		// need to unbox/box the constant
		final int typeId = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
		generateBoxingConversion(typeId);
	}
}
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(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 generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
	if (mappingSequence == null) {
		if (target instanceof LocalVariableBinding) {
			scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
		} else {
			scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
		}
		return;
	}
	if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
		scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
		return;
	} else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
		scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
		return;
	}
	
	if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
		this.aload_0();
		return;
	} else if (mappingSequence[0] instanceof FieldBinding) {
		FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
		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]);
		}
	}
}
public void generateReturnBytecode(Expression expression) {
	
	if (expression == null) {
		this.return_();
	} else {
		final int implicitConversion = expression.implicitConversion;
		if ((implicitConversion & BOXING) != 0) {
			this.areturn();
			return;
		}
		int runtimeType = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
		switch (runtimeType) {
			case T_boolean :
			case T_int :
				this.ireturn();
				break;
			case T_float :
				this.freturn();
				break;
			case T_long :
				this.lreturn();
				break;
			case T_double :
				this.dreturn();
				break;
			default :
				this.areturn();
		}
	}
}
/**
 * The equivalent code performs a string conversion:
 *
 * @param blockScope the given blockScope
 * @param oper1 the first expression
 * @param oper2 the second expression
 */
public void generateStringConcatenationAppend(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.newStringContatenation();
		this.dup_x1();
		this.swap();
		// If argument is reference type, need to transform it 
		// into a string (handles null case)
		this.invokeStringValueOf(T_JavaLangObject);
		this.invokeStringConcatenationStringConstructor();
	} else {
		pc = position;
		oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & COMPILE_TYPE_MASK);
		this.recordPositionsFrom(pc, oper1.sourceStart);
	}
	pc = position;
	oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & COMPILE_TYPE_MASK);
	this.recordPositionsFrom(pc, oper2.sourceStart);
	this.invokeStringConcatenationToString();
}
/**
 * Code responsible to generate the suitable code to supply values for the synthetic enclosing
 * instance arguments of a constructor invocation of a nested type.
 */
public void generateSyntheticEnclosingInstanceValues(
		BlockScope currentScope, 
		ReferenceBinding targetType, 
		Expression enclosingInstance, 
		ASTNode invocationSite) {

	// supplying enclosing instance for the anonymous type's superclass
	ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? (ReferenceBinding)targetType.superclass().erasure() : targetType;
	boolean hasExtraEnclosingInstance = enclosingInstance != null;
	if (hasExtraEnclosingInstance 
			&& (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
		currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
		return;
	}

	// perform some emulation work in case there is some and we are inside a local type only
	ReferenceBinding[] syntheticArgumentTypes;
	if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {

		ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
		long compliance = currentScope.compilerOptions().complianceLevel;

		// deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
		// always consider it if complying to 1.5
		boolean denyEnclosingArgInConstructorCall;
		if (compliance <= ClassFileConstants.JDK1_3) {
			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
		} else if (compliance == ClassFileConstants.JDK1_4){
			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
				|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess();
		} else {
			//compliance >= JDK1_5
			denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression
					|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess()) 
				&& !targetType.isLocalType();
		}
		
		boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
		for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
			ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
			if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
				hasExtraEnclosingInstance = false;
				enclosingInstance.generateCode(currentScope, this, true);
				if (complyTo14){
					dup();
					invokeObjectGetClass(); // will perform null check
					pop();
				}
			} else {
				Object[] emulationPath = currentScope.getEmulationPath(
						syntheticArgType, 
						false /*not only exact match (that is, allow compatible)*/,
						denyEnclosingArgInConstructorCall);
				this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
			}
		}
		if (hasExtraEnclosingInstance){
			currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
		}
	}
}

/**
 * Code responsible to generate the suitable code to supply values for the synthetic outer local
 * variable arguments of a constructor invocation of a nested type.
 * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
 */
public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {

	// generate the synthetic outer arguments then
	SyntheticArgumentBinding syntheticArguments[];
	if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
		for (int i = 0, max = syntheticArguments.length; i < max; i++) {
			LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
			VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
			this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
		}
	}
}

/**
 * @param accessBinding the access method binding to generate
 */
public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {

	initializeMaxLocals(accessBinding);

	MethodBinding constructorBinding = accessBinding.targetMethod;
	TypeBinding[] parameters = constructorBinding.parameters;
	int length = parameters.length;
	int resolvedPosition = 1;
	this.aload_0();
	// special name&ordinal argument generation for enum constructors
	TypeBinding declaringClass = constructorBinding.declaringClass;
	if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
		this.aload_1(); // pass along name param as name arg
		this.iload_2(); // pass along ordinal param as ordinal arg
        resolvedPosition += 2;
	}	
	if (declaringClass.isNestedType()) {
		NestedTypeBinding nestedType = (NestedTypeBinding) 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++;
		}
	}
	for (int i = 0; i < length; i++) {
		load(parameters[i], resolvedPosition);
		if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
			resolvedPosition += 2;
		else
			resolvedPosition++;
	}
	
	if (declaringClass.isNestedType()) {
		NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
		SyntheticArgumentBinding[] 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++;
		}
	}
	this.invokespecial(constructorBinding);
	this.return_();
}
//static X[] values() {
// X[] values;
// int length;
// X[] result;
// System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
// return result;
//}
public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
	FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
	initializeMaxLocals(methodBinding);
	TypeBinding enumArray = methodBinding.returnType;
	
	this.getstatic(enumValuesSyntheticfield);
	this.dup();
	this.astore_0();
	this.iconst_0();
	this.aload_0();
	this.arraylength();
	this.dup();
	this.istore_1();
	this.newArray((ArrayBinding) enumArray);
	this.dup();
	this.astore_2();
	this.iconst_0();
	this.iload_1();
	this.invokeSystemArraycopy();
	this.aload_2();
	this.areturn();
}
//static X valueOf(String name) {
// X[] values;
// for (int i = (values = $VALUES).length; --i >= 0;) {
// 		 X value;
// 		 if (name.equals(value = values[i].name())) return value;
// }
// throw new IllegalArgumentException(name);
//}		
public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
	FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
	initializeMaxLocals(methodBinding);
	Label loopCond = new Label(this);
	Label loopStart = new Label(this);
	Label wrongConstant = new Label(this);

	this.getstatic(enumValuesSyntheticfield);
	this.dup();
	this.astore_1();
	this.arraylength();
	this.istore_2();
	this.goto_(loopCond);
	loopStart.place();
	this.aload_0();
	this.aload_1();
	this.iload_2();
	this.aaload();
	this.dup();
	this.astore_3();
	this.invokeJavaLangEnumname(this.classFile.referenceBinding);
	this.invokeStringEquals();
	this.ifeq(wrongConstant);
	this.aload_3();
	this.areturn();
	wrongConstant.place();
	loopCond.place();
	this.iinc(2, -1);		
	this.iload_2();
	this.ifge(loopStart);
	this.newJavaLangIllegalArgumentException();
	this.dup();
	this.aload_0();
	this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
	this.athrow();
}
public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
	initializeMaxLocals(methodBinding);
	final Label nullLabel = new Label(this);
	FieldBinding syntheticFieldBinding = methodBinding.targetReadField;

	this.getstatic(syntheticFieldBinding);
	this.dup();
	this.ifnull(nullLabel);
	final int stackSizeForIf = this.stackDepth;
	this.areturn();
	nullLabel.place();
	this.stackDepth = stackSizeForIf;
	this.pop();
	ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
	char[] signature = "()".toCharArray(); //$NON-NLS-1$
	ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
	signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
	this.invoke(OPC_invokestatic, 0, 1, enumBinding.constantPoolName(), TypeConstants.VALUES, signature);
	this.arraylength();
	this.newarray(ClassFileConstants.INT_ARRAY);
	this.astore_0();
	final FieldBinding[] fields = enumBinding.fields();
	if (fields != null) {
		for (int i = 0, max = fields.length; i < max; i++) {
			FieldBinding fieldBinding = fields[i];
			if ((fieldBinding.getAccessFlags() & ClassFileConstants.AccEnum) != 0) {
				final Label endLabel = new Label(this);
				final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, BaseTypes.LongBinding /* represents NoSuchFieldError*/);
				this.aload_0();
				this.getstatic(fieldBinding);
				this.invokeEnumOrdinal(enumBinding.constantPoolName());
				this.generateInlinedValue(fieldBinding.id);
				this.iastore();
				anyExceptionHandler.placeEnd();
				this.goto_(endLabel);
				// Generate the body of the exception handler
				final int saveStackSize = stackDepth;
				stackDepth = 1;
				anyExceptionHandler.place();
				this.pop(); // we don't use it so we can pop it
				stackDepth = saveStackSize;
				endLabel.place();				
			}
		}
	}
	this.aload_0();
	this.dup();
	this.putstatic(syntheticFieldBinding);
	areturn();
}
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
	initializeMaxLocals(accessBinding);
	FieldBinding fieldBinding = accessBinding.targetReadField;
	if (fieldBinding.isStatic())
		this.getstatic(fieldBinding);
	else {
		this.aload_0();
		this.getfield(fieldBinding);
	}
	switch (fieldBinding.type.id) {
//		case T_void :
//			this.return_();
//			break;
		case T_boolean :
		case T_byte :
		case T_char :
		case T_short :
		case T_int :
			this.ireturn();
			break;
		case T_long :
			this.lreturn();
			break;
		case T_float :
			this.freturn();
			break;
		case T_double :
			this.dreturn();
			break;
		default :
			this.areturn();
	}	
}
public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding 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(SyntheticMethodBinding accessMethod) {

	initializeMaxLocals(accessMethod);
	MethodBinding targetMethod = accessMethod.targetMethod;
	TypeBinding[] parameters = targetMethod.parameters;
	int length = parameters.length;
	TypeBinding[] arguments = accessMethod.kind == SyntheticMethodBinding.BridgeMethod 
													? accessMethod.parameters
													: null;
	int resolvedPosition;
	if (targetMethod.isStatic())
		resolvedPosition = 0;
	else {
		this.aload_0();
		resolvedPosition = 1;
	}
	for (int i = 0; i < length; i++) {
	    TypeBinding parameter = parameters[i];
	    if (arguments != null) { // for bridge methods
		    TypeBinding argument = arguments[i];
			load(argument, resolvedPosition);
			if (argument != parameter) 
			    checkcast(parameter);
	    } else {
			load(parameter, resolvedPosition);
		}
		if ((parameter == DoubleBinding) || (parameter == LongBinding))
			resolvedPosition += 2;
		else
			resolvedPosition++;
	}
	if (targetMethod.isStatic())
		this.invokestatic(targetMethod);
	else {
		if (targetMethod.isConstructor()
			|| targetMethod.isPrivate()
			// qualified super "X.super.foo()" targets methods from superclass
			|| accessMethod.kind == SyntheticMethodBinding.SuperMethodAccess){
			this.invokespecial(targetMethod);
		} else {
			if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
				this.invokeinterface(targetMethod);
			} else {
				this.invokevirtual(targetMethod);
			}
		}
	}
	switch (targetMethod.returnType.id) {
		case T_void :
			this.return_();
			break;
		case T_boolean :
		case T_byte :
		case T_char :
		case T_short :
		case T_int :
			this.ireturn();
			break;
		case T_long :
			this.lreturn();
			break;
		case T_float :
			this.freturn();
			break;
		case T_double :
			this.dreturn();
			break;
		default :
			TypeBinding accessErasure = accessMethod.returnType.erasure();
			if (!targetMethod.returnType.isCompatibleWith(accessErasure))
				this.checkcast(accessErasure); // for bridge methods
			this.areturn();
	}
}
public void generateBoxingConversion(int unboxedTypeID) {
    switch (unboxedTypeID) {
        case T_byte :
            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
    			if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Byte.valueOf(byte)"); //$NON-NLS-1$
               // invokestatic: Byte.valueOf(byte)
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangByteConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.byteByteSignature);
            } else {
               // new Byte( byte )
    			if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Byte(byte)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x1();
                swap();
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangByteConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.ByteConstrSignature);
            }       
            break;
        case T_short :
            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
                // invokestatic: Short.valueOf(short)
    			if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Short.valueOf(short)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangShortConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.shortShortSignature);
            } else {
                // new Short(short)
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Short(short)"); //$NON-NLS-1$
            	newWrapperFor(unboxedTypeID);                
                dup_x1();
                swap();             
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangShortConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.ShortConstrSignature);     
            }
            break;
        case T_char :
            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
                // invokestatic: Character.valueOf(char)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Character.valueOf(char)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangCharacterConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.charCharacterSignature);
            } else {
                // new Char( char )
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Character(char)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x1();
                swap();
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangCharacterConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.CharConstrSignature);
            }       
            break;
        case T_int :             
            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
                // invokestatic: Integer.valueOf(int)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Integer.valueOf(int)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangIntegerConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.IntIntegerSignature);
            } else {
                // new Integer(int)
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Integer(int)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x1();
                swap();             
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangIntegerConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.IntConstrSignature);
            }
            break;
        case T_long :
            if (this.targetLevel >= ClassFileConstants.JDK1_5) { 
                // invokestatic: Long.valueOf(long)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Long.valueOf(long)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    2, // argCount
                    1, // return type size
                    ConstantPool.JavaLangLongConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.longLongSignature);
            } else {
                // new Long( long )
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Long(long)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x2();
                dup_x2();
                pop();
                this.invoke(
                    OPC_invokespecial,
                    2, // argCount
                    0, // return type size
                    ConstantPool.JavaLangLongConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.LongConstrSignature);
            }                   
            break;
        case T_float :
            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
                // invokestatic: Float.valueOf(float)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Float.valueOf(float)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangFloatConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.floatFloatSignature);
            } else {
                // new Float(float)
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Float(float)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x1();
                swap();             
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangFloatConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.FloatConstrSignature);
            }       
            break;
        case T_double :
            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) { 
                // invokestatic: Double.valueOf(double)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Double.valueOf(double)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    2, // argCount
                    1, // return type size
                    ConstantPool.JavaLangDoubleConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.doubleDoubleSignature);
            } else {
                // new Double( double )
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Double(double)"); //$NON-NLS-1$
            	newWrapperFor(unboxedTypeID);                
                dup_x2();
                dup_x2();
                pop();
                
                this.invoke(
                    OPC_invokespecial,
                    2, // argCount
                    0, // return type size
                    ConstantPool.JavaLangDoubleConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.DoubleConstrSignature);
            }       
            
            break;  
        case T_boolean :
            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
                // invokestatic: Boolean.valueOf(boolean)
            	if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Boolean.valueOf(boolean)"); //$NON-NLS-1$
                this.invoke(
                    OPC_invokestatic,
                    1, // argCount
                    1, // return type size
                    ConstantPool.JavaLangBooleanConstantPoolName,
                    ConstantPool.ValueOf,
                    ConstantPool.booleanBooleanSignature);
            } else {
                // new Boolean(boolean)
            	if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Boolean(boolean)"); //$NON-NLS-1$
                newWrapperFor(unboxedTypeID);
                dup_x1();
                swap();             
                this.invoke(
                    OPC_invokespecial,
                    1, // argCount
                    0, // return type size
                    ConstantPool.JavaLangBooleanConstantPoolName,
                    ConstantPool.Init,
                    ConstantPool.BooleanConstrSignature);
            }
    }
}
public void generateUnboxingConversion(int unboxedTypeID) {
	switch (unboxedTypeID) {
		case T_byte :
			// invokevirtual: byteValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangByteConstantPoolName,
					ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
					ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
			break;
		case T_short :
			// invokevirtual: shortValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangShortConstantPoolName,
					ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
					ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
			break;
		case T_char :
			// invokevirtual: charValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangCharacterConstantPoolName,
					ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
					ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
			break;
		case T_int :
			// invokevirtual: intValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangIntegerConstantPoolName,
					ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
					ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
			break;
		case T_long :
			// invokevirtual: longValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					2, // return type size
					ConstantPool.JavaLangLongConstantPoolName,
					ConstantPool.LONGVALUE_LONG_METHOD_NAME,
					ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
			break;
		case T_float :
			// invokevirtual: floatValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangFloatConstantPoolName,
					ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
					ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
			break;
		case T_double :
			// invokevirtual: doubleValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					2, // return type size
					ConstantPool.JavaLangDoubleConstantPoolName,
					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
			break;
		case T_boolean :
			// invokevirtual: booleanValue()
			this.invoke(
					OPC_invokevirtual,
					0, // argCount
					1, // return type size
					ConstantPool.JavaLangBooleanConstantPoolName,
					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
	}
}
final public byte[] getContents() {
	byte[] contents;
	System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
	return contents;
}
final public void getfield(FieldBinding fieldBinding) {
	if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
	int returnTypeSize = 1;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
		returnTypeSize = 2;
	}
	generateFieldAccess(
			OPC_getfield,
			returnTypeSize,
			fieldBinding.declaringClass.constantPoolName(),
			fieldBinding.name,
			fieldBinding.type.signature());
}
private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
	countLabels = 0;
	switch(opcode) {
		case OPC_getfield :
			if (returnTypeSize == 2) {
				stackDepth++;
			}
			break;
		case OPC_getstatic :
			if (returnTypeSize == 2) {
				stackDepth += 2;
			} else {
				stackDepth++;
			}
			break;
		case OPC_putfield :
			if (returnTypeSize == 2) {
				stackDepth -= 3;
			} else {
				stackDepth -= 2;
			}
			break;
		case OPC_putstatic :
			if (returnTypeSize == 2) {
				stackDepth -= 2;
			} else {
				stackDepth--;
			}
	}
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = opcode;
	writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature));
}
final public void getstatic(FieldBinding fieldBinding) {
	if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
	int returnTypeSize = 1;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
		returnTypeSize = 2;
	}
	generateFieldAccess(
			OPC_getstatic,
			returnTypeSize,
			fieldBinding.declaringClass.constantPoolName(),
			fieldBinding.name,
			fieldBinding.type.signature());
}
public void getTYPE(int baseTypeID) {
	countLabels = 0;
	switch (baseTypeID) {
		case T_byte :
			// getstatic: java.lang.Byte.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangByteConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_short :
			// getstatic: java.lang.Short.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangShortConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_char :
			// getstatic: java.lang.Character.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangCharacterConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_int :
			// getstatic: java.lang.Integer.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangIntegerConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_long :
			// getstatic: java.lang.Long.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangLongConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_float :
			// getstatic: java.lang.Float.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangFloatConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_double :
			// getstatic: java.lang.Double.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangDoubleConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_boolean :
			// getstatic: java.lang.Boolean.TYPE			
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangBooleanConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
		case T_void :
			// getstatic: java.lang.Void.TYPE
			if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
			generateFieldAccess(
					OPC_getstatic,
					1,
					ConstantPool.JavaLangVoidConstantPoolName,
					ConstantPool.TYPE,
					ConstantPool.JavaLangClassSignature);
			break;
	}
}
/**
 * We didn't call it goto, because there is a conflit with the goto keyword
 */
final public void goto_(Label label) {
	if (this.wideMode) {
		this.goto_w(label);
		return;
	}
	if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	label.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;
	label.branch();
}

final public void goto_w(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_goto_w;
	lbl.branchWide();
}
final public void i2b() {
	if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2b;
}
final public void i2c() {
	if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2c;
}
final public void i2d() {
	if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2d;
}
final public void i2f() {
	if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2f;
}
final public void i2l() {
	if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2l;
}
final public void i2s() {
	if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_i2s;
}
final public void iadd() {
	if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iadd;
}
final public void iaload() {
	if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iaload;
}
final public void iand() {
	if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iand;
}
final public void iastore() {
	if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iastore;
}
final public void iconst_0() {
	if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_0;
}
final public void iconst_1() {
	if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_1;
}
final public void iconst_2() {
	if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_2;
}
final public void iconst_3() {
	if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_3;
}
final public void iconst_4() {
	if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_4;
}
final public void iconst_5() {
	if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_5;
}
final public void iconst_m1() {
	if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iconst_m1;
}
final public void idiv() {
	if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_idiv;
}
final public void if_acmpeq(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth-=2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_acmpne, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_acmpeq;
		lbl.branch();
	}
}
final public void if_acmpne(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth-=2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_acmpeq, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_acmpne;
		lbl.branch();
	}
}
final public void if_icmpeq(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmpne, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpeq;
		lbl.branch();
	}
}
final public void if_icmpge(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_iacmpge:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmplt, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpge;
		lbl.branch();
	}
}
final public void if_icmpgt(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_iacmpgt:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmple, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpgt;
		lbl.branch();
	}
}
final public void if_icmple(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_iacmple:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmpgt, lbl);
	} else {	
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmple;
		lbl.branch();
	}
}
final public void if_icmplt(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_iacmplt:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmpge, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmplt;
		lbl.branch();
	}
}
final public void if_icmpne(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tif_iacmpne:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_if_icmpeq, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_if_icmpne;
		lbl.branch();
	}
}
final public void ifeq(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifne, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifeq;
		lbl.branch();
	}
}
final public void ifge(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_iflt, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifge;
		lbl.branch();
	}
}
final public void ifgt(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifle, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifgt;
		lbl.branch();
	}
}
final public void ifle(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifgt, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifle;
		lbl.branch();
	}
}
final public void iflt(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifge, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_iflt;
		lbl.branch();
	}
}
final public void ifne(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifeq, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifne;
		lbl.branch();
	}
}
final public void ifnonnull(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifnull, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifnonnull;
		lbl.branch();
	}
}
final public void ifnull(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (this.wideMode) {
		generateWideRevertedConditionalBranch(OPC_ifnonnull, lbl);
	} else {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ifnull;
		lbl.branch();
	}
}
final public void iinc(int index, int value) {
	if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
	countLabels = 0;
	if ((index > 255) || (value < -128 || value > 127)) { // have to widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_iinc;
		writeUnsignedShort(index);
		writeSignedShort(value);
	} else {
		if (classFileOffset + 2 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 3;
		bCodeStream[classFileOffset++] = OPC_iinc;
		bCodeStream[classFileOffset++] = (byte) index;
		bCodeStream[classFileOffset++] = (byte) value;
	}
}
final public void iload(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_iload;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_iload;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void iload_0() {
	if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 0) {
		maxLocals = 1;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iload_0;
}
final public void iload_1() {
	if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iload_1;
}
final public void iload_2() {
	if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iload_2;
}
final public void iload_3() {
	if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iload_3;
}
final public void imul() {
	if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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() {
	if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ineg;
}
public void init(ClassFile targetClassFile) {
	this.classFile = targetClassFile;
	this.constantPool = targetClassFile.constantPool;
	this.bCodeStream = targetClassFile.contents;
	this.classFileOffset = targetClassFile.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);
	exceptionHandlersIndex = 0;
	exceptionHandlersCounter = 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 methodBinding the given method binding to initialize the max locals
 */
public void initializeMaxLocals(MethodBinding methodBinding) {

	if (methodBinding == null) {
		this.maxLocals = 0;
		return;
	}
	
	this.maxLocals = methodBinding.isStatic() ? 0 : 1;
	
	// take into account enum constructor synthetic name+ordinal
	if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) {
		this.maxLocals += 2; // String and int (enum constant name+ordinal)
	}
	
	// take into account the synthetic parameters
	if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
		ReferenceBinding enclosingInstanceTypes[];
		if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
			for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
				this.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)) {
					this.maxLocals += 2;
				} else {
					this.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)) {
				this.maxLocals += 2;
			} else {
				this.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 pcToSourceMap the given pcToSourceMap array
 * @param length the given length
 * @param pc the given 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) {
	if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_instanceof;
	writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
public void invokeClassForName() {
	// invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
	if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
	this.invoke(
		OPC_invokestatic,
		1, // argCount
		1, // return type size
		ConstantPool.JavaLangClassConstantPoolName,
		ConstantPool.ForName,
		ConstantPool.ForNameSignature);
}
public void invokeJavaLangClassDesiredAssertionStatus() {
	// invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			ConstantPool.JavaLangClassConstantPoolName,
			ConstantPool.DesiredAssertionStatus,
			ConstantPool.DesiredAssertionStatusSignature);
}

public void invokeJavaLangClassGetComponentType() {
	// invokevirtual: java.lang.Class.getComponentType()java.lang.Class;
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			ConstantPool.JavaLangClassConstantPoolName,
			ConstantPool.GetComponentType,
			ConstantPool.GetComponentTypeSignature);
}
public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
	// invokevirtual: <enumConstantPoolName>.ordinal()
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			enumTypeConstantPoolName,
			ConstantPool.Ordinal,
			ConstantPool.OrdinalSignature);
}
final public void invokeinterface(MethodBinding methodBinding) {
	// initialized to 1 to take into account this  immediately
	if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
	countLabels = 0;
	int argCount = 1;
	int id;
	if (classFileOffset + 4 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 3;
	bCodeStream[classFileOffset++] = OPC_invokeinterface;
	writeUnsignedShort(
		constantPool.literalIndexForMethod(
			methodBinding.constantPoolDeclaringClass().constantPoolName(),
			methodBinding.selector,
			methodBinding.signature(),
			true));
	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;
	bCodeStream[classFileOffset++] = (byte) 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.
	bCodeStream[classFileOffset++] = 0;
	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
	if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
	this.invoke(
			OPC_invokespecial,
			1, // argCount
			0, // return type size
			ConstantPool.JavaLangErrorConstantPoolName,
			ConstantPool.Init,
			ConstantPool.StringConstructorSignature);
}
public void invokeNoClassDefFoundErrorStringConstructor() {
	// invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
	if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
	this.invoke(
			OPC_invokespecial,
			1, // argCount
			0, // return type size
			ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
			ConstantPool.Init,
			ConstantPool.StringConstructorSignature);
}
public void invokeObjectGetClass() {
	// invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			ConstantPool.JavaLangObjectConstantPoolName,
			ConstantPool.GetClass,
			ConstantPool.GetClassSignature);
}

final public void invokespecial(MethodBinding methodBinding) {
	if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
	// initialized to 1 to take into account this  immediately
	countLabels = 0;
	int argCount = 1;
	int id;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_invokespecial;
	writeUnsignedShort(
		constantPool.literalIndexForMethod(
			methodBinding.constantPoolDeclaringClass().constantPoolName(),
			methodBinding.selector,
			methodBinding.signature(),
			false));
	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) {
	if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
	// initialized to 0 to take into account that there is no this for
	// a static method
	countLabels = 0;
	int argCount = 0;
	int id;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_invokestatic;
	writeUnsignedShort(
		constantPool.literalIndexForMethod(
			methodBinding.constantPoolDeclaringClass().constantPoolName(),
			methodBinding.selector,
			methodBinding.signature(),
			false));
	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 invokeStringConcatenationAppendForType(int typeID) {
	if (DEBUG) {
		if (this.targetLevel >= ClassFileConstants.JDK1_5) {
			System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
		} else {
			System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
		}
	}
	int argCount = 1;
	int returnType = 1;
	char[] declarinClass = null;
	char[] selector = ConstantPool.Append;
	char[] signature = null;
	switch (typeID) {
		case T_int :
		case T_byte :
		case T_short :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendIntSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendIntSignature;
			}
			break;
		case T_long :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendLongSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendLongSignature;
			}
			argCount = 2;
			break;
		case T_float :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendFloatSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendFloatSignature;
			}
			break;
		case T_double :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendDoubleSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendDoubleSignature;
			}
			argCount = 2;
			break;
		case T_char :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendCharSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendCharSignature;
			}
			break;
		case T_boolean :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendBooleanSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendBooleanSignature;
			}
			break;
		case T_undefined :
		case T_JavaLangObject :
		case T_null :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendObjectSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendObjectSignature;
			}
			break;
		case T_JavaLangString :
			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
				declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
				signature = ConstantPool.StringBuilderAppendStringSignature;
			} else {
				declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
				signature = ConstantPool.StringBufferAppendStringSignature;
			}
			break;
	}
	this.invoke(
			OPC_invokevirtual,
			argCount, // argCount
			returnType, // return type size
			declarinClass,
			selector,
			signature);
}

public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
	// invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
	if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
	int argCount = 1;
	char[] signature = null;
	switch (typeBindingID) {
		case T_int :
		case T_byte :
		case T_short :
			signature = ConstantPool.IntConstrSignature;
			break;
		case T_long :
			signature = ConstantPool.LongConstrSignature;
			argCount = 2;
			break;
		case T_float :
			signature = ConstantPool.FloatConstrSignature;
			break;
		case T_double :
			signature = ConstantPool.DoubleConstrSignature;
			argCount = 2;
			break;
		case T_char :
			signature = ConstantPool.CharConstrSignature;
			break;
		case T_boolean :
			signature = ConstantPool.BooleanConstrSignature;
			break;
		case T_JavaLangObject :
		case T_JavaLangString :
		case T_null :
			signature = ConstantPool.ObjectConstrSignature;
			break;
	}
	this.invoke(
			OPC_invokespecial,
			argCount, // argCount
			0, // return type size
			ConstantPool.JavaLangAssertionErrorConstantPoolName,
			ConstantPool.Init,
			signature);
}

public void invokeJavaLangAssertionErrorDefaultConstructor() {
	// invokespecial: java.lang.AssertionError.<init>()V
	if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
	this.invoke(
			OPC_invokespecial,
			0, // argCount
			0, // return type size
			ConstantPool.JavaLangAssertionErrorConstantPoolName,
			ConstantPool.Init,
			ConstantPool.DefaultConstructorSignature);
}
public void invokeJavaLangEnumname(TypeBinding typeBinding) {
	// invokevirtual: java.lang.Enum.name()String
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Enum.name()Ljava/lang/String;"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0,
			1,
			typeBinding.constantPoolName(),
			ConstantPool.Name,
			ConstantPool.NameSignature);
}
public void invokeJavaLangIllegalArgumentExceptionStringConstructor() {
	// invokespecial: java.lang.IllegalArgumentException.<init>(String)V
	if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.IllegalArgumentException.<init>(java.lang.String)V"); //$NON-NLS-1$
	this.invoke(
			OPC_invokespecial,
			1, // argCount
			0, // return type size
			ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName,
			ConstantPool.Init,
			ConstantPool.StringConstructorSignature);
}

public void invokeJavaUtilIteratorHasNext() {
	// invokeinterface java.util.Iterator.hasNext()Z
	if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
	this.invoke(
			OPC_invokeinterface,
			0, // argCount
			1, // return type size
			ConstantPool.JavaUtilIteratorConstantPoolName,
			ConstantPool.HasNext,
			ConstantPool.HasNextSignature);
}
public void invokeJavaUtilIteratorNext() {
	// invokeinterface java.util.Iterator.next()java.lang.Object
	if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
	this.invoke(
			OPC_invokeinterface,
			0, // argCount
			1, // return type size
			ConstantPool.JavaUtilIteratorConstantPoolName,
			ConstantPool.Next,
			ConstantPool.NextSignature);
}
public void invokeStringConcatenationDefaultConstructor() {
	// invokespecial: java.lang.StringBuffer.<init>()V
	if (DEBUG) {
		if (this.targetLevel >= ClassFileConstants.JDK1_5) {
			System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
		} else {
			System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
		}
	}
	char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
	}
	this.invoke(
			OPC_invokespecial,
			0, // argCount
			0, // return type size
			declaringClass,
			ConstantPool.Init,
			ConstantPool.DefaultConstructorSignature);
}
public void invokeStringConcatenationStringConstructor() {
	if (DEBUG) {
		if (this.targetLevel >= ClassFileConstants.JDK1_5) {
			System.out.println(position + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
		} else {
			System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
		}
	}
	char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
	}
	this.invoke(
			OPC_invokespecial,
			1, // argCount
			0, // return type size
			declaringClass,
			ConstantPool.Init,
			ConstantPool.StringConstructorSignature);
}

public void invokeStringConcatenationToString() {
	if (DEBUG) {
		if (this.targetLevel >= ClassFileConstants.JDK1_5) {
			System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
		} else {
			System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
		}
	}
	char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
	}
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			declaringClass,
			ConstantPool.ToString,
			ConstantPool.ToStringSignature);
}
public void invokeStringEquals() {
	// invokevirtual: java.lang.String.equals(java.lang.Object)
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.equals(...)"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			1, // argCount
			1, // return type size
			ConstantPool.JavaLangStringConstantPoolName,
			ConstantPool.Equals,
			ConstantPool.EqualsSignature);
}
public void invokeStringIntern() {
	// invokevirtual: java.lang.String.intern()
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			ConstantPool.JavaLangStringConstantPoolName,
			ConstantPool.Intern,
			ConstantPool.InternSignature);
}
public void invokeStringValueOf(int typeID) {
	// invokestatic: java.lang.String.valueOf(argumentType)
	if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
	int argCount = 1;
	char[] signature = null;
	switch (typeID) {
		case T_int :
		case T_byte :
		case T_short :
			signature = ConstantPool.ValueOfIntSignature;
			break;
		case T_long :
			signature = ConstantPool.ValueOfLongSignature;
			argCount = 2;
			break;
		case T_float :
			signature = ConstantPool.ValueOfFloatSignature;
			break;
		case T_double :
			signature = ConstantPool.ValueOfDoubleSignature;
			argCount = 2;
			break;
		case T_char :
			signature = ConstantPool.ValueOfCharSignature;
			break;
		case T_boolean :
			signature = ConstantPool.ValueOfBooleanSignature;
			break;
		case T_JavaLangObject :
		case T_JavaLangString :
		case T_null :
		case T_undefined :
			signature = ConstantPool.ValueOfObjectSignature;
			break;
	}
	this.invoke(
			OPC_invokestatic,
			argCount, // argCount
			1, // return type size
			ConstantPool.JavaLangStringConstantPoolName,
			ConstantPool.ValueOf,
			signature);
}
public void invokeSystemArraycopy() {
	// invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
	this.invoke(
			OPC_invokestatic,
			5, // argCount
			0, // return type size
			ConstantPool.JavaLangSystemConstantPoolName,
			ConstantPool.ArrayCopy,
			ConstantPool.ArrayCopySignature);
}
public void invokeThrowableGetMessage() {
	// invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
	this.invoke(
			OPC_invokevirtual,
			0, // argCount
			1, // return type size
			ConstantPool.JavaLangThrowableConstantPoolName,
			ConstantPool.GetMessage,
			ConstantPool.GetMessageSignature);
}
final public void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
	countLabels = 0;
	int argCount = argsSize;
	switch(opcode) {
		case OPC_invokeinterface :
			if (classFileOffset + 4 >= bCodeStream.length) {
				resizeByteArray();
			}
			position +=3;
			bCodeStream[classFileOffset++] = OPC_invokeinterface;
			writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
			argCount++;
			bCodeStream[classFileOffset++] = (byte) argCount;
			bCodeStream[classFileOffset++] = 0;
			break;
		case OPC_invokevirtual :
		case OPC_invokespecial :
			if (classFileOffset + 2 >= bCodeStream.length) {
				resizeByteArray();
			}
			position++;
			bCodeStream[classFileOffset++] = (byte) opcode;
			writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
			argCount++;
			break;
		case OPC_invokestatic :
			if (classFileOffset + 2 >= bCodeStream.length) {
				resizeByteArray();
			}
			position++;
			bCodeStream[classFileOffset++] = OPC_invokestatic;
			writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
	}
	stackDepth += returnTypeSize - argCount;
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
}
final public void invokevirtual(MethodBinding methodBinding) {
	if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
	// initialized to 1 to take into account this  immediately
	countLabels = 0;
	int argCount = 1;
	int id;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_invokevirtual;
	writeUnsignedShort(
		constantPool.literalIndexForMethod(
			methodBinding.constantPoolDeclaringClass().constantPoolName(),
			methodBinding.selector,
			methodBinding.signature(),
			false));
	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() {
	if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ior;
}
final public void irem() {
	if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_irem;
}
final public void ireturn() {
	if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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 localPosition = local.id + maxFieldCount;
	MethodScope methodScope = scope.methodScope();
	// id is zero-based
	if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
		return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 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 = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
		return false; // if not enough room in vector, then not initialized 
	return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
}
final public void ishl() {
	if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ishl;
}
final public void ishr() {
	if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ishr;
}
final public void istore(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= iArg) {
		maxLocals = iArg + 1;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_istore;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_istore;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void istore_0() {
	if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals == 0) {
		maxLocals = 1;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_istore_0;
}
final public void istore_1() {
	if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 1) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_istore_1;
}
final public void istore_2() {
	if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 2) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_istore_2;
}
final public void istore_3() {
	if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (maxLocals <= 3) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_istore_3;
}
final public void isub() {
	if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_isub;
}
final public void iushr() {
	if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_iushr;
}
final public void ixor() {
	if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ixor;
}
final public void jsr(Label lbl) {
	if (this.wideMode) {
		this.jsr_w(lbl);
		return;
	}
	if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_jsr;
	lbl.branch();
}
final public void jsr_w(Label lbl) {
	if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_jsr_w;
	lbl.branchWide();
}
final public void l2d() {
	if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_l2d;
}
final public void l2f() {
	if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_l2f;
}
final public void l2i() {
	if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_l2i;
}
final public void ladd() {
	if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ladd;
}
final public void laload() {
	if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_laload;
}
final public void land() {
	if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_land;
}
final public void lastore() {
	if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 4;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lastore;
}
final public void lcmp() {
	if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lcmp;
}
final public void lconst_0() {
	if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lconst_0;
}
final public void lconst_1() {
	if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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) {
		if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
		// Generate a ldc_w
		if (classFileOffset + 2 >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ldc_w;
		writeUnsignedShort(index);
	} else {
		if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
		// Generate a ldc
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_ldc;
		bCodeStream[classFileOffset++] = (byte) index;
	}
}
final public void ldc(int constant) {
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (index > 255) {
		if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
		// Generate a ldc_w
		if (classFileOffset + 2 >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ldc_w;
		writeUnsignedShort(index);
	} else {
		if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
		// Generate a ldc
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_ldc;
		bCodeStream[classFileOffset++] = (byte) 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) {
			if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
			// Generate a ldc_w
			if (classFileOffset + 2 >= bCodeStream.length) {
				resizeByteArray();
			}
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc_w;
			writeUnsignedShort(index);
		} else {
			if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
			// Generate a ldc
			if (classFileOffset + 1 >= bCodeStream.length) {
				resizeByteArray();
			}
			position += 2;
			bCodeStream[classFileOffset++] = OPC_ldc;
			bCodeStream[classFileOffset++] = (byte) 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
		newStringContatenation();
		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
			if (classFileOffset + 2 >= bCodeStream.length) {
				resizeByteArray();
			}
			position++;
			bCodeStream[classFileOffset++] = OPC_ldc_w;
			writeUnsignedShort(index);
		} else {
			// Generate a ldc
			if (classFileOffset + 1 >= bCodeStream.length) {
				resizeByteArray();
			}
			position += 2;
			bCodeStream[classFileOffset++] = OPC_ldc;
			bCodeStream[classFileOffset++] = (byte) index;
		}
		// write the remaining part
		invokeStringConcatenationStringConstructor();
		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
				if (classFileOffset + 2 >= bCodeStream.length) {
					resizeByteArray();
				}
				position++;
				bCodeStream[classFileOffset++] = OPC_ldc_w;
				writeUnsignedShort(index);
			} else {
				// Generate a ldc
				if (classFileOffset + 1 >= bCodeStream.length) {
					resizeByteArray();
				}
				position += 2;
				bCodeStream[classFileOffset++] = OPC_ldc;
				bCodeStream[classFileOffset++] = (byte) index;
			}
			// now on the stack it should be a StringBuffer and a string.
			invokeStringConcatenationAppendForType(T_JavaLangString);
		}
		invokeStringConcatenationToString();
		invokeStringIntern();
	}
}
final public void ldc(TypeBinding typeBinding) {
	countLabels = 0;
	int index = constantPool.literalIndexForType(typeBinding.constantPoolName());
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (index > 255) {
		if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$
		// Generate a ldc_w
		if (classFileOffset + 2 >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = OPC_ldc_w;
		writeUnsignedShort(index);
	} else {
		if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$
		// Generate a ldc
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_ldc;
		bCodeStream[classFileOffset++] = (byte) index;
	}
}
final public void ldc2_w(double constant) {
	if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	// Generate a ldc2_w
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ldc2_w;
	writeUnsignedShort(index);
}
final public void ldc2_w(long constant) {
	if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
	countLabels = 0;
	int index = constantPool.literalIndex(constant);
	stackDepth += 2;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	// Generate a ldc2_w
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ldc2_w;
	writeUnsignedShort(index);
}
final public void ldiv() {
	if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_ldiv;
}
final public void lload(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_lload;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_lload;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void lload_0() {
	if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lload_0;
}
final public void lload_1() {
	if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lload_1;
}
final public void lload_2() {
	if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lload_2;
}
final public void lload_3() {
	if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth += 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lload_3;
}
final public void lmul() {
	if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lmul;
}
final public void lneg() {
	if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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;
			//case -1 :
			// internal failure: trying to load variable not supposed to be generated
			//	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) {
	if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	int length = keys.length;
	int pos = position;
	defaultLabel.placeInstruction();
	for (int i = 0; i < length; i++) {
		casesLabel[i].placeInstruction();
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lookupswitch;
	for (int i = (3 - (pos % 4)); i > 0; i--) {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = 0;
	}
	defaultLabel.branch();
	writeSignedWord(length);
	for (int i = 0; i < length; i++) {
		writeSignedWord(keys[sortedIndexes[i]]);
		casesLabel[sortedIndexes[i]].branch();
	}
}
final public void lor() {
	if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lor;
}
final public void lrem() {
	if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lrem;
}
final public void lreturn() {
	if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lreturn;
}
final public void lshl() {
	if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lshl;
}
final public void lshr() {
	if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lshr;
}
final public void lstore(int iArg) {
	if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals <= iArg + 1) {
		maxLocals = iArg + 2;
	}
	if (iArg > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_lstore;
		writeUnsignedShort(iArg);
	} else {
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_lstore;
		bCodeStream[classFileOffset++] = (byte) iArg;
	}
}
final public void lstore_0() {
	if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 2) {
		maxLocals = 2;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lstore_0;
}
final public void lstore_1() {
	if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 3) {
		maxLocals = 3;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lstore_1;
}
final public void lstore_2() {
	if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 4) {
		maxLocals = 4;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lstore_2;
}
final public void lstore_3() {
	if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (maxLocals < 5) {
		maxLocals = 5;
	}
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lstore_3;
}
final public void lsub() {
	if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lsub;
}
final public void lushr() {
	if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lushr;
}
final public void lxor() {
	if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_lxor;
}
final public void monitorenter() {
	if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_monitorenter;
}
final public void monitorexit() {
	if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_monitorexit;
}
final public void multianewarray(TypeBinding typeBinding, int dimensions) {
	if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
	countLabels = 0;
	stackDepth += (1 - dimensions);
	if (classFileOffset + 3 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 2;
	bCodeStream[classFileOffset++] = OPC_multianewarray;
	writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
	bCodeStream[classFileOffset++] = (byte) dimensions;
}
/**
 * We didn't call it new, because there is a conflit with the new keyword
 */
final public void new_(TypeBinding typeBinding) {
	if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void newarray(int array_Type) {
	if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset + 1 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 2;
	bCodeStream[classFileOffset++] = OPC_newarray;
	bCodeStream[classFileOffset++] = (byte) array_Type;
}
public void newArray(ArrayBinding arrayBinding) {
	TypeBinding component = arrayBinding.elementsType();
	switch (component.id) {
		case T_int :
			this.newarray(ClassFileConstants.INT_ARRAY);
			break;
		case T_byte :
			this.newarray(ClassFileConstants.BYTE_ARRAY);
			break;
		case T_boolean :
			this.newarray(ClassFileConstants.BOOLEAN_ARRAY);
			break;
		case T_short :
			this.newarray(ClassFileConstants.SHORT_ARRAY);
			break;
		case T_char :
			this.newarray(ClassFileConstants.CHAR_ARRAY);
			break;
		case T_long :
			this.newarray(ClassFileConstants.LONG_ARRAY);
			break;
		case T_float :
			this.newarray(ClassFileConstants.FLOAT_ARRAY);
			break;
		case T_double :
			this.newarray(ClassFileConstants.DOUBLE_ARRAY);
			break;
		default :
			this.anewarray(component);
	}
}
public void newJavaLangError() {
	// new: java.lang.Error
	if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
}

public void newJavaLangAssertionError() {
	// new: java.lang.AssertionError
	if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
}
public void newJavaLangIllegalArgumentException() {
	// new: java.lang.IllegalArgumentException
	if (DEBUG) System.out.println(position + "\t\tnew: java.lang.IllegalArgumentException"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName));
}
public void newNoClassDefFoundError() {
	// new: java.lang.NoClassDefFoundError
	if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
}
public void newStringContatenation() {
	// new: java.lang.StringBuffer
	// new: java.lang.StringBuilder
	if (DEBUG) {
		if (this.targetLevel >= ClassFileConstants.JDK1_5) {
			System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
		} else {
			System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
		}
	}
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax) {
		stackMax = stackDepth;
	}
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
		writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
	} else {
		writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
	}
}
public void newWrapperFor(int typeID) {
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset + 2 >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_new;
	switch (typeID) {
		case T_int : // new: java.lang.Integer
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
			break;
		case T_boolean : // new: java.lang.Boolean
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
			break;
		case T_byte : // new: java.lang.Byte
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
			break;
		case T_char : // new: java.lang.Character
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
			break;
		case T_float : // new: java.lang.Float
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
			break;
		case T_double : // new: java.lang.Double
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
			break;
		case T_short : // new: java.lang.Short
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
			break;
		case T_long : // new: java.lang.Long
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
			break;
		case T_void : // new: java.lang.Void
			if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
			writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
	}
}
final public void nop() {
	if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_nop;
}
final public void pop() {
	if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_pop;
}
final public void pop2() {
	if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 2;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_pop2;
}
final public void putfield(FieldBinding fieldBinding) {
	if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
	int returnTypeSize = 1;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
		returnTypeSize = 2;
	}
	generateFieldAccess(
			OPC_putfield,
			returnTypeSize,
			fieldBinding.declaringClass.constantPoolName(),
			fieldBinding.name,
			fieldBinding.type.signature());
}
final public void putstatic(FieldBinding fieldBinding) {
	if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
	int returnTypeSize = 1;
	if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
		returnTypeSize = 2;
	}
	generateFieldAccess(
			OPC_putstatic,
			returnTypeSize,
			fieldBinding.declaringClass.constantPoolName(),
			fieldBinding.name,
			fieldBinding.type.signature());
}
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, int sourcePos) {

	/* 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.
	 */

	if (!generateLineNumberAttributes)
		return;
	if (sourcePos == 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, sourcePos);
	// 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 if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) {
						// 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;
					}
				} else 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
					/* First we need to check if at the insertion position there is not an existing entry
					 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
					 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
					 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
					 */
					if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
						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 (exceptionHandlersIndex >= (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[exceptionHandlersIndex++] = anExceptionLabel;
	exceptionHandlersCounter++;
}
public void removeExceptionHandler(ExceptionLabel exceptionLabel) {
	for (int i = 0; i < exceptionHandlersIndex; i++) {
		if (exceptionHandlers[i] == exceptionLabel) {
			exceptionHandlers[i] = null;
			exceptionHandlersCounter--;
			return;
		}
	}
}
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 referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
 * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
	init(targetClassFile);
	this.methodDeclaration = referenceMethod;
	this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
	initializeMaxLocals(referenceMethod.binding);
}
/**
 * @param targetClassFile The given classfile to reset the code stream
 */
public void resetForProblemClinit(ClassFile targetClassFile) {
	init(targetClassFile);
	maxLocals = 0;
}
private final void resizeByteArray() {
	int length = bCodeStream.length;
	int requiredSize = length + length;
	if (classFileOffset >= requiredSize) {
		// must be sure to grow enough
		requiredSize = classFileOffset + length;
	}
	System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
}
final public void ret(int index) {
	if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
	countLabels = 0;
	if (index > 255) { // Widen
		if (classFileOffset + 3 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_wide;
		bCodeStream[classFileOffset++] = OPC_ret;
		writeUnsignedShort(index);
	} else { // Don't Widen
		if (classFileOffset + 1 >= bCodeStream.length) {
			resizeByteArray();
		}
		position += 2;
		bCodeStream[classFileOffset++] = OPC_ret;
		bCodeStream[classFileOffset++] = (byte) index;
	}
}
final public void return_() {
	if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
	countLabels = 0;
	// the stackDepth should be equal to 0 
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_return;
}
final public void saload() {
	if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_saload;
}
final public void sastore() {
	if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth -= 3;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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) {
	if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
	countLabels = 0;
	stackDepth++;
	if (stackDepth > stackMax)
		stackMax = stackDepth;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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) {
	int localPosition = localBinding.resolvedPosition;
	// Using dedicated int bytecode
	switch(localBinding.type.id) {
		case TypeIds.T_int :
		case TypeIds.T_char :
		case TypeIds.T_byte :
		case TypeIds.T_short :
		case TypeIds.T_boolean :
			if (valueRequired)
				this.dup();
			switch (localPosition) {
				case 0 :
					this.istore_0();
					break;
				case 1 :
					this.istore_1();
					break;
				case 2 :
					this.istore_2();
					break;
				case 3 :
					this.istore_3();
					break;
				//case -1 :
				// internal failure: trying to store into variable not supposed to be generated
				//	break;
				default :
					this.istore(localPosition);
			}
			break;
		case TypeIds.T_float :
			if (valueRequired)
				this.dup();
			switch (localPosition) {
				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(localPosition);
			}
			break;
		case TypeIds.T_double :
			if (valueRequired)
				this.dup2();
			switch (localPosition) {
				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(localPosition);
			}
			break;
		case TypeIds.T_long :
			if (valueRequired)
				this.dup2();
			switch (localPosition) {
				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(localPosition);
			}
			break;
		default:
			// Reference object
			if (valueRequired)
				this.dup();
			switch (localPosition) {
				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(localPosition);
			}
	}
}
public final void store(TypeBinding type, int localPosition) {
	// Using dedicated int bytecode
	if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
		switch (localPosition) {
			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(localPosition);
		}
		return;
	}
	// Using dedicated float bytecode
	if (type == FloatBinding) {
		switch (localPosition) {
			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(localPosition);
		}
		return;
	}
	// Using dedicated long bytecode
	if (type == LongBinding) {
		switch (localPosition) {
			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(localPosition);
		}
		return;
	}
	// Using dedicated double bytecode
	if (type == DoubleBinding) {
		switch (localPosition) {
			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(localPosition);
		}
		return;
	}
	// Reference object
	switch (localPosition) {
		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(localPosition);
	}
}
public final void storeInt(int localPosition) {
	switch (localPosition) {
		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(localPosition);
	}
}
public final void storeObject(int localPosition) {
	switch (localPosition) {
		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(localPosition);
	}
}
final public void swap() {
	if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
	countLabels = 0;
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = 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) {
	if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
	countLabels = 0;
	stackDepth--;
	int length = casesLabel.length;
	int pos = position;
	defaultLabel.placeInstruction();
	for (int i = 0; i < length; i++)
		casesLabel[i].placeInstruction();
	if (classFileOffset >= bCodeStream.length) {
		resizeByteArray();
	}
	position++;
	bCodeStream[classFileOffset++] = OPC_tableswitch;
	for (int i = (3 - (pos % 4)); i > 0; i--) {
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = 0;
	}
	defaultLabel.branch();
	writeSignedWord(low);
	writeSignedWord(high);
	int i = low, 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
	while (true) {
		int index;
		int key = keys[index = sortedIndexes[j - low]];
		if (key == i) {
			casesLabel[index].branch();
			j++;
			if (i == high) break; // if high is maxint, then avoids wrapping to minint.
		} else {
			defaultLabel.branch();
		}
		i++;
	}
}
public String toString() {
	StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
	buffer.append(position);
	buffer.append(",\nstackDepth:"); //$NON-NLS-1$
	buffer.append(stackDepth);
	buffer.append(",\nmaxStack:"); //$NON-NLS-1$
	buffer.append(stackMax);
	buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
	buffer.append(maxLocals);
	buffer.append(")"); //$NON-NLS-1$
	return buffer.toString();
}
/**
 * Note: it will walk the locals table and extend the end range for all matching ones, no matter if
 * visible or not.
 * {  int i = 0;
 *    {  int j = 1; }
 * }   <== would process both 'i' and 'j'
 * Processing non-visible ones is mandated in some cases (include goto instruction after if-then block)
 */
public void updateLastRecordedEndPC(Scope scope, 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;
	this.lastEntryPC = pos;
	// need to update the initialization endPC in case of generation of local variable attributes.
	if (this.generateLocalVariableTableAttributes) {
		for (int i = 0, max = this.locals.length; i < max; i++) {
			LocalVariableBinding local = this.locals[i];
			if (local != null && local.declaringScope == scope && local.initializationCount > 0) {
				if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
					local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position;
				}
			}
		}
	}
}

/**
 * Write a signed 16 bits value into the byte array
 * @param value the signed short
 */
public final void writeSignedShort(int value) {
	// we keep the resize in here because it is used outside the code stream
	if (classFileOffset + 1 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 2;
	bCodeStream[classFileOffset++] = (byte) (value >> 8);
	bCodeStream[classFileOffset++] = (byte) value;
}
public final void writeSignedShort(int pos, int value) {
	int currentOffset = startingClassFileOffset + pos;
	if (currentOffset + 1 >= bCodeStream.length) {
		resizeByteArray();
	}
	bCodeStream[currentOffset] = (byte) (value >> 8);
	bCodeStream[currentOffset + 1] = (byte) value;
}
public final void writeSignedWord(int value) {
	// we keep the resize in here because it is used outside the code stream
	if (classFileOffset + 3 >= bCodeStream.length) {
		resizeByteArray();
	}
	position += 4;
	bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
	bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
	bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
	bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
}
public final void writeSignedWord(int pos, int value) {
	int currentOffset = startingClassFileOffset + pos;
	if (currentOffset + 4 >= bCodeStream.length) {
		resizeByteArray();
	}
	bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
	bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
	bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
	bCodeStream[currentOffset++] = (byte) (value & 0xFF);
}
/**
 * Write a unsigned 16 bits value into the byte array
 * @param value the unsigned short
 */
protected final void writeUnsignedShort(int value) {
	position += 2;
	bCodeStream[classFileOffset++] = (byte) (value >>> 8);
	bCodeStream[classFileOffset++] = (byte) value;
}
/*
 * Wide conditional branch compare, improved by swapping comparison opcode
 *   ifeq WideTarget
 * becomes
 *    ifne Intermediate
 *    gotow WideTarget
 *    Intermediate:
 */
public void generateWideRevertedConditionalBranch(byte revertedOpcode, Label wideTarget) {
		Label intermediate = new Label(this);
		if (classFileOffset >= bCodeStream.length) {
			resizeByteArray();
		}
		position++;
		bCodeStream[classFileOffset++] = revertedOpcode;
		intermediate.branch();
		this.goto_w(wideTarget);
		intermediate.place();
}
}
