/*******************************************************************************
 * Copyright (c) 2000, 2011 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.debug.eval.ast.engine;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayAccess;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.AssertStatement;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BlockComment;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.BreakStatement;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.CharacterLiteral;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.ContinueStatement;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EmptyStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.LabeledStatement;
import org.eclipse.jdt.core.dom.LineComment;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.MethodRefParameter;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.SynchronizedStatement;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TextElement;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.dom.WildcardType;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.AndOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAllocation;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayInitializerInstruction;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.AssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Cast;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.CompoundInstruction;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.ConditionalJump;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Constructor;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.DivideAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.DivideOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Dup;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.DupX1;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.EqualEqualOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.GreaterEqualOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.GreaterOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstanceOfOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Instruction;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstructionSequence;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Jump;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.LeftShiftAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.LeftShiftOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.LessEqualOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.LessOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.LocalVariableCreation;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.MinusAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.MinusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.MultiplyAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.MultiplyOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.NoOp;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.NotOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.OrAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.OrOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PlusAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PlusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Pop;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PostfixMinusMinusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PostfixPlusPlusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PrefixMinusMinusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PrefixPlusPlusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushArrayLength;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushArrayType;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushBoolean;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushChar;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushClassLiteralValue;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushDouble;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushFieldVariable;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushFloat;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushInt;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushLocalVariable;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushLong;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushNull;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushPrimitiveType;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushStaticFieldVariable;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushString;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushThis;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.PushType;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.RemainderOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.ReturnInstruction;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.RightShiftOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.SendMessage;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.SendStaticMessage;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.ThrowInstruction;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.TwiddleOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnaryMinusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnaryPlusOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnsignedRightShiftAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.UnsignedRightShiftOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.Value;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.XorAssignmentOperator;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.XorOperator;

import com.ibm.icu.text.MessageFormat;

/**
 * The AST instruction compiler generates a sequence
 * of instructions (InstructionSequence) from a
 * DOM AST.
 */
public class ASTInstructionCompiler extends ASTVisitor {

	/**
	 * Represent a break or a continue instruction.
	 * These instructions needs are stored and managed later by their
	 * related statement.
	 */
	class CompleteInstruction {
		Jump fInstruction;
		String fLabel;
		boolean fIsBreak;

		public CompleteInstruction(Jump instruction, String label, boolean isBreak) {
			fInstruction= instruction;
			fLabel= label;
			fIsBreak= isBreak;
		}
	}

	/**
	 * Whether to print debug messages to the console
	 */
	private static boolean VERBOSE = false;

	private InstructionSequence fInstructions;

	/**
	 * The list of pending break and continue instruction.
	 */
	private List fCompleteInstructions;

	private int fStartPosition;

	private boolean fActive;

	private boolean fHasErrors;

	private Stack fStack;

	private int fCounter;
	
	// internal index used to create unique variable name
	private int fUniqueIdIndex= 0;


	/**
	 * Create a new AST instruction compiler
	 */
	public ASTInstructionCompiler(int startPosition, String snippet) {
		fStartPosition = startPosition;
		fInstructions = new InstructionSequence(snippet);
		fStack = new Stack();
		fCompleteInstructions= new ArrayList();
	}

	/**
	 * Returns the instruction sequence generated
	 * by this AST instruction compiler
	 */
	public InstructionSequence getInstructions() {
		return fInstructions;
	}

	/**
	 * Returns whether the generated instruction sequence
	 * has errors.
	 * Errors include:
	 * <ol>
	 * <li>AST contains unimplemented operations (features which will be supported,
	 *  but aren't yet)</li>
	 * <li>AST contains unsupported operations (features which are not yet implemented
	 *  and are likely NOT to be implemented)</li>
	 * </ol>
	 */
	public boolean hasErrors() {
		return fHasErrors;
	}

	private void setHasError(boolean value) {
		fHasErrors= value;
	}

	private void addErrorMessage(String message) {
		fInstructions.addError(message);
	}

	private boolean isActive() {
		return fActive;
	}

	private void setActive(boolean active) {
		fActive = active;
	}


	private void push(Instruction i) {
		fStack.push(i);
	}

	private Instruction pop() {
		return (Instruction)fStack.pop();
	}

	private void storeInstruction() {
		Instruction instruction= pop();
		fCounter++;
		if (instruction instanceof CompoundInstruction) {
			((CompoundInstruction)instruction).setEnd(fCounter);
		}
		fInstructions.add(instruction);
		verbose("Add " + instruction.toString()); //$NON-NLS-1$
	}


	/**
	 * Prints the given message to the console if verbose
	 * mode is on.
	 *
	 * @param message the message to display
	 */
	private void verbose(String message) {
		if (VERBOSE) {
			System.out.println(message);
		}
	}

	private String getTypeName(ITypeBinding typeBinding) {
		if (typeBinding.isRawType()) {
			typeBinding= typeBinding.getErasure();
		}
		if (typeBinding.isTypeVariable()) {
			ITypeBinding[] typeBounds= typeBinding.getTypeBounds();
			if (typeBounds.length > 0) {
				String name= getTypeName(typeBounds[0]);
				if (typeBounds.length > 1 && "java.lang.Object".equals(name)) { //$NON-NLS-1$
					return getTypeName(typeBounds[1]);
				}
				return name;
			}
			return "java.lang.Object"; //$NON-NLS-1$
		}
		StringBuffer name;
		if (typeBinding.isArray()) {
			name= new StringBuffer(getTypeName(typeBinding.getElementType()));
			int dimensions= typeBinding.getDimensions();
			for (int i= 0; i < dimensions; i++) {
				name.append("[]"); //$NON-NLS-1$
			}
			return name.toString();
		}
		String typeName= typeBinding.getName();
		int parameters= typeName.indexOf('<');
		if (parameters >= 0) {
			typeName= typeName.substring(0, parameters);
		}
		name= new StringBuffer(typeName);
		IPackageBinding packageBinding= typeBinding.getPackage();
		typeBinding= typeBinding.getDeclaringClass();
		while(typeBinding != null) {
			name.insert(0, '$').insert(0, typeBinding.getName());
			typeBinding= typeBinding.getDeclaringClass();
		}
		if (packageBinding != null && !packageBinding.isUnnamed()) {
			name.insert(0, '.').insert(0, packageBinding.getName());
		}
		return name.toString();
	}

	private String getTypeSignature(ITypeBinding typeBinding) {
		return Signature.createTypeSignature(getTypeName(typeBinding), true).replace('.', '/');
	}

	private boolean isALocalType(ITypeBinding typeBinding) {
		while(typeBinding != null) {
			if (typeBinding.isLocal()) {
				return true;
			}
			typeBinding= typeBinding.getDeclaringClass();
		}
		return false;
	}

	private boolean containsALocalType(IMethodBinding methodBinding) {
		ITypeBinding[] typeBindings= methodBinding.getParameterTypes();
		for (int i= 0, length= typeBindings.length; i < length; i++) {
			if (isALocalType(typeBindings[i])) {
				return true;
			}
		}
		return false;
	}

	private int getEnclosingLevel(ASTNode node, ITypeBinding referenceTypeBinding) {
		ASTNode parent = node;
		ITypeBinding refbinding = referenceTypeBinding.isParameterizedType() ? referenceTypeBinding.getTypeDeclaration() : referenceTypeBinding;
		do {
			parent = parent.getParent();
		} while (parent != null && !(parent instanceof AbstractTypeDeclaration || parent instanceof AnonymousClassDeclaration));
		if(parent == null) {
			return 0;
		}
		ITypeBinding parentBinding = null;
		if(parent instanceof AbstractTypeDeclaration) {
			parentBinding = ((AbstractTypeDeclaration)parent).resolveBinding();
		}
		else if(parent instanceof AnonymousClassDeclaration) {
			parentBinding = ((AnonymousClassDeclaration)parent).resolveBinding();
		}
		if (parentBinding != null && (parentBinding.isEqualTo(refbinding) || parentBinding.isCastCompatible(refbinding))) {
			return 0;
		}
		return getEnclosingLevel(parent, referenceTypeBinding) + 1;
	}

	private int getSuperLevel(ITypeBinding current, ITypeBinding reference) {
		if (current.equals(reference)) {
			return 0;
		}
		return getSuperLevel(current.getSuperclass(), reference);
	}

	/**
	 * Return the label associated with the given statement.
	 *
	 * @param statement the statement.
	 * @return the associated label, or <code>null</code> if there is none.
	 */
	private String getLabel(Statement statement) {
		ASTNode parent= statement.getParent();
		if (parent instanceof LabeledStatement) {
			return ((LabeledStatement)parent).getLabel().getIdentifier();
		}
		return null;
	}

	/**
	 * Append a pop instruction in the instruction list if needed.
	 * A pop instruction is added when the expression has a return value,
	 * i.e. all expressions expect method invocation expressions which
	 * have <code>void</code> as return type and variable declaration expression.
	 *
	 * @param expression the expression to test.
	 */
	private void addPopInstructionIfNeeded(Expression expression) {
		boolean pop= true;

		if (expression instanceof MethodInvocation) {
			IMethodBinding methodBinding= (IMethodBinding)((MethodInvocation)expression).getName().resolveBinding();
			if (methodBinding != null && "void".equals(methodBinding.getReturnType().getName())) { //$NON-NLS-1$
				pop= false;
			}
		} else if (expression instanceof SuperMethodInvocation) {
			IMethodBinding methodBinding= (IMethodBinding)((SuperMethodInvocation)expression).getName().resolveBinding();
			if (methodBinding != null && "void".equals(methodBinding.getReturnType().getName())) { //$NON-NLS-1$
				pop= false;
			}
		} else if (expression instanceof VariableDeclarationExpression) {
			pop= false;
		}

		if (pop) {
			addPopInstruction();
		}
	}

	/**
	 * 
	 */
	private void addPopInstruction() {
		Instruction lastInstruction= fInstructions.getInstruction(fInstructions.getEnd());
		push(new Pop(lastInstruction.getSize() + 1));
		storeInstruction();
	}
	
	/**
	 * Check the current type of a value and the requested type to decide if boxing/un-boxing is required.
	 * If needed, the correct instruction is added to the stack
	 * Returns true if a storeInstruction() is needed after visiting the expression
	 */
	private boolean checkAutoBoxing(ITypeBinding valueBinding, ITypeBinding requestedBinding) {
		if (valueBinding == null) {
			return false; // unresolved
		}
		if (valueBinding.isPrimitive() == requestedBinding.isPrimitive()) {
			return false;
		}
		if (requestedBinding.isPrimitive()) {
			unBoxing(valueBinding);
		} else {
			boxing(requestedBinding, valueBinding);
		}
		return true;
	}

	/**
	 * Add to the stack the instruction to box a primitive value.
	 */
	private void boxing(ITypeBinding requestedBinding, ITypeBinding valueBinding) {
		String requestedTypeName= requestedBinding.getQualifiedName();
		if ("java.lang.Object".equals(requestedTypeName)) { //$NON-NLS-1$
			switch (valueBinding.getBinaryName().charAt(0)) {
				case 'I':
					push(new SendStaticMessage("java.lang.Integer", "valueOf", "(I)Ljava/lang/Integer;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'C':
					push(new SendStaticMessage("java.lang.Character", "valueOf", "(C)Ljava/lang/Character;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'B':
					push(new SendStaticMessage("java.lang.Byte", "valueOf", "(B)Ljava/lang/Byte;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'S':
					push(new SendStaticMessage("java.lang.Short", "valueOf", "(S)Ljava/lang/Short;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'J':
					push(new SendStaticMessage("java.lang.Long", "valueOf", "(J)Ljava/lang/Long;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'F':
					push(new SendStaticMessage("java.lang.Float", "valueOf", "(F)Ljava/lang/Float;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'D':
					push(new SendStaticMessage("java.lang.Double", "valueOf", "(D)Ljava/lang/Double;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
				case 'Z':
					push(new SendStaticMessage("java.lang.Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					break;
			}
		} else if ("java.lang.Integer".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(I)Ljava/lang/Integer;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Character".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(C)Ljava/lang/Character;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Byte".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(B)Ljava/lang/Byte;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Short".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(S)Ljava/lang/Short;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Long".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(J)Ljava/lang/Long;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Float".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(F)Ljava/lang/Float;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Double".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(D)Ljava/lang/Double;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Boolean".equals(requestedTypeName)) { //$NON-NLS-1$
			push(new SendStaticMessage(requestedTypeName, "valueOf", "(Z)Ljava/lang/Boolean;", 1, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * Add the instruction to un-box a non-primitive value if needed.
	 * Returns true if a storeInstruction() is needed after visiting the expression
	 */
	private boolean unBoxing(ITypeBinding valueBinding) {
		String valueTypeName= valueBinding.getQualifiedName();
		if ("java.lang.Integer".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("intValue", "()I", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Character".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("charValue", "()C", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Byte".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("byteValue", "()B", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Short".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("shortValue", "()S", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Long".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("longValue", "()J", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Float".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("floatValue", "()F", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Double".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("doubleValue", "()D", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else if ("java.lang.Boolean".equals(valueTypeName)) { //$NON-NLS-1$
			push(new SendMessage("booleanValue", "()Z", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			return false;
		}
		return true;
	}

	/**
	 * End visit methods
	 *
	 * There are two paths to ending a visit to a node:
	 * <ol>
	 * <li>For control statements, the necessary control
	 *  instructions (jump, conditional jump) are inserted
	 *  into the instruction sequence</li>
	 * <li>For other cases, we simply remove the node's
	 *  instruction from the stack and add it to the
	 *  instruction sequence.</li>
	 * </ol>
	 */

	/**
	 * @see ASTVisitor#endVisit(AnonymousClassDeclaration)
	 */
	public void endVisit(AnonymousClassDeclaration node) {

	}

	/**
	 * @see ASTVisitor#endVisit(ArrayAccess)
	 */
	public void endVisit(ArrayAccess node) {
		if (!isActive() || hasErrors())
			return;
		ITypeBinding typeBinding = node.getIndex().resolveTypeBinding();
		if (typeBinding != null && unBoxing(typeBinding)) {
			// un-box the index, if required
			storeInstruction();
		}
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ArrayCreation)
	 */
	public void endVisit(ArrayCreation node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ArrayInitializer)
	 */
	public void endVisit(ArrayInitializer node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ArrayType)
	 */
	public void endVisit(ArrayType node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(AssertStatement)
	 */
	public void endVisit(AssertStatement node) {

	}

	/**
	 * @see ASTVisitor#endVisit(Assignment)
	 */
	public void endVisit(Assignment node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(Block)
	 */
	public void endVisit(Block node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(BooleanLiteral)
	 */
	public void endVisit(BooleanLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(BreakStatement)
	 */
	public void endVisit(BreakStatement node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(CastExpression)
	 */
	public void endVisit(CastExpression node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(CatchClause)
	 */
	public void endVisit(CatchClause node) {

	}

	/**
	 * @see ASTVisitor#endVisit(CharacterLiteral)
	 */
	public void endVisit(CharacterLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ClassInstanceCreation)
	 */
	public void endVisit(ClassInstanceCreation node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(CompilationUnit)
	 */
	public void endVisit(CompilationUnit node) {

	}

	/**
	 * @see ASTVisitor#endVisit(ConditionalExpression)
	 */
	public void endVisit(ConditionalExpression node) {
		if (!isActive() || hasErrors())
			return;

		// Get the instructions
		int ifFalseAddress= fInstructions.getEnd();
		Instruction ifFalse= fInstructions.get(ifFalseAddress);
		int ifTrueAddress= ifFalseAddress - ifFalse.getSize();
		Instruction ifTrue= fInstructions.get(ifTrueAddress);
		int conditionalAddress= ifTrueAddress - ifTrue.getSize();

		// Insert the conditional jump
		ConditionalJump conditionalJump= new ConditionalJump(false);
		fInstructions.insert(conditionalJump, conditionalAddress + 1);

		// Insert the jump
		int jumpAddress= ifTrueAddress + 2;
		Jump jump= new Jump();
		fInstructions.insert(jump, jumpAddress);

		// Set the jump offsets
		conditionalJump.setOffset(ifTrue.getSize() + 1);
		jump.setOffset(ifFalse.getSize() + 1);

		fCounter += 2;
		storeInstruction();

	}

	/**
	 * @see ASTVisitor#endVisit(ConstructorInvocation)
	 */
	public void endVisit(ConstructorInvocation node) {

	}

	/**
	 * @see ASTVisitor#endVisit(ContinueStatement)
	 */
	public void endVisit(ContinueStatement node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(DoStatement)
	 */
	public void endVisit(DoStatement node) {
		if (!isActive() || hasErrors())
			return;

		/* The structure of generated instructions is :
		 *
		 * --
		 * | body
		 * --
		 * --
		 * |condition
		 * --
		 * - jump to the first instruction of the body if the condition is true.
		 *
		 */

		String label= getLabel(node);

		// get address of each part
		int conditionAddress= fInstructions.getEnd();
		Instruction condition= fInstructions.getInstruction(conditionAddress);
		int bodyAddress= conditionAddress - condition.getSize();
		Instruction body= fInstructions.getInstruction(bodyAddress);
		int bodyStartAddress= bodyAddress - body.getSize();

		// add the conditionnalJump
		ConditionalJump conditionalJump= new ConditionalJump(true);
		fInstructions.add(conditionalJump);
		fCounter++;

		// set jump offsets
		conditionalJump.setOffset(-(condition.getSize() + body.getSize() + 1));

		// for each pending break or continue instruction which are related to
		// this loop, set the offset of the corresponding jump.
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			Jump jumpInstruction= instruction.fInstruction;
			int instructionAddress= fInstructions.indexOf(jumpInstruction);
			if (instructionAddress > bodyStartAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
				iter.remove();
				if (instruction.fIsBreak) {
					// jump to the instruction after the last jump
					jumpInstruction.setOffset((conditionAddress - instructionAddress) + 1);
				} else {
					// jump to the first instruction of the condition
					jumpInstruction.setOffset(bodyAddress - instructionAddress);
				}
			}
		}

		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(EmptyStatement)
	 */
	public void endVisit(EmptyStatement node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.EnhancedForStatement)
	 */
	public void endVisit(EnhancedForStatement node) {
		if (!isActive() || hasErrors())
			return;

		/* The structure of generated instructions is :
		 *
		 * For an array:
		 * --
		 * | <ParameterType>[] a= Expression
		 * | int i= 0
		 * | <ParameterType> <ParameterName>
		 * --
		 * --
		 * | i < a.length
		 * - jump to the instruction after the last jump if the condition is false.
		 * --
		 * --
		 * | s= a[i]
		 * | Body
		 * --
		 * --
		 * - jump to the first instruction of the condition.
		 *
		 * For an Iterable:
		 * --
		 * | Iterator i= Expression.iterator()
		 * | <ParameterType> <ParameterName>
		 * --
		 * --
		 * | i.hasNext()
		 * - jump to the instruction after the last jump if the condition is false.
		 * --
		 * --
		 * | s= i.next()
		 * | Body
		 * --
		 * --
		 * - jump to the first instruction of the condition.
		 *
		 */

		int bodyAddress= fInstructions.getEnd();
		Instruction body= fInstructions.getInstruction(bodyAddress);
		int conditionAddress= bodyAddress - body.getSize();
		Instruction condition= fInstructions.getInstruction(conditionAddress);
		int initAddress= conditionAddress - condition.getSize();
		
		// add conditional jump
		ConditionalJump condJump= new ConditionalJump(false);
		fInstructions.insert(condJump, conditionAddress + 1);
		bodyAddress++;
		fCounter++;
		condJump.setOffset(body.getSize() + 1);
		
		// add jump
		Jump jump= new Jump();
		fInstructions.add(jump);
		fCounter++;
		jump.setOffset(initAddress - (bodyAddress + 1));
		

		// for each pending break or continue instruction which are related to
		// this loop, set the offset of the corresponding jump.
		String label= getLabel(node);
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			Jump jumpInstruction= instruction.fInstruction;
			int instructionAddress= fInstructions.indexOf(jumpInstruction);
			if (instructionAddress > conditionAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
				iter.remove();
				if (instruction.fIsBreak) {
					// jump to the instruction after the last jump
					jumpInstruction.setOffset((bodyAddress - instructionAddress) + 1);
				} else {
					// jump to the first instruction of the condition
					jumpInstruction.setOffset(initAddress - instructionAddress);
				}
			}
		}
		
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ExpressionStatement)
	 */
	public void endVisit(ExpressionStatement node) {
		if (!isActive() || hasErrors())
			return;

		addPopInstructionIfNeeded(node.getExpression());
	}

	/**
	 * @see ASTVisitor#endVisit(FieldAccess)
	 */
	public void endVisit(FieldAccess node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(FieldDeclaration)
	 */
	public void endVisit(FieldDeclaration node) {

	}

	/**
	 * @see ASTVisitor#endVisit(ForStatement)
	 */
	public void endVisit(ForStatement node) {
		if (!isActive() || hasErrors())
			return;

		/* The structure of generated instructions is :
		 *
		 * --
		 * |initialization
		 * --
		 * --
		 * |condition
		 * --
		 * - jump to the instruction after the last jump if the condition is false.
		 * --
		 * | body
		 * --
		 * --
		 * | updaters
		 * --
		 * - jump to the first instruction of the condition.
		 *
		 */

		String label= getLabel(node);
		boolean hasCondition= node.getExpression() != null;

		// get address of each part
		int updatersAddress= fInstructions.getEnd();
		Instruction updaters= fInstructions.getInstruction(updatersAddress);
		int bodyAddress= updatersAddress - updaters.getSize();
		Instruction body= fInstructions.getInstruction(bodyAddress);
		int bodyStartAddress= bodyAddress - body.getSize();

		int conditionAddress;
		Instruction condition;

		if (hasCondition) {
			conditionAddress= bodyStartAddress;
			condition= fInstructions.getInstruction(conditionAddress);
		} else {
			conditionAddress= 0;
			condition= null;
		}

		// add jump
		Jump jump= new Jump();
		fInstructions.add(jump);
		fCounter++;

		if (hasCondition) {
			// add conditional jump
			ConditionalJump condJump= new ConditionalJump(false);
			fInstructions.insert(condJump, conditionAddress + 1);
			bodyAddress++;
			bodyStartAddress++;
			updatersAddress++;
			fCounter++;
			// set conditional jump offset
			condJump.setOffset(body.getSize() + updaters.getSize() + 1);
		}

		// set jump offset
		jump.setOffset(-((hasCondition && (condition != null) ? condition.getSize() : 0) + body.getSize() + updaters.getSize() + 2));

		// for each pending break or continue instruction which are related to
		// this loop, set the offset of the corresponding jump.
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			Jump jumpInstruction= instruction.fInstruction;
			int instructionAddress= fInstructions.indexOf(jumpInstruction);
			if (instructionAddress > bodyStartAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
				iter.remove();
				if (instruction.fIsBreak) {
					// jump to the instruction after the last jump
					jumpInstruction.setOffset((updatersAddress - instructionAddress) + 1);
				} else {
					// jump to the first instruction of the condition
					jumpInstruction.setOffset(bodyAddress - instructionAddress);
				}
			}
		}

		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(IfStatement)
	 */
	public void endVisit(IfStatement node) {
		if (!isActive() || hasErrors())
			return;

		boolean hasElseStatement= node.getElseStatement() != null;

		// Get the instructions

		int ifFalseAddress= 0;
		Instruction ifFalse= null;
		int ifTrueAddress= 0;
		Instruction ifTrue= null;

		if (hasElseStatement) {
			ifFalseAddress= fInstructions.getEnd();
			ifFalse= fInstructions.get(ifFalseAddress);
			ifTrueAddress= ifFalseAddress - ifFalse.getSize();
			ifTrue= fInstructions.get(ifTrueAddress);
		} else {
			ifTrueAddress= fInstructions.getEnd();
			ifTrue= fInstructions.get(ifTrueAddress);
		}

		int conditionalAddress= ifTrueAddress - ifTrue.getSize();

		// Insert the conditional jump
		ConditionalJump conditionalJump= new ConditionalJump(false);
		fInstructions.insert(conditionalJump, conditionalAddress + 1);
		// Set the jump offset
		conditionalJump.setOffset(ifTrue.getSize() + ((hasElseStatement)? 1 : 0));
		fCounter++;

		if (hasElseStatement) {
			// Insert the jump
			int jumpAddress= ifTrueAddress + 2;
			Jump jump= new Jump();
			fInstructions.insert(jump, jumpAddress);
			// Set the jump offset
			jump.setOffset(ifFalse.getSize() + 1);
			fCounter++;
		}

		storeInstruction();

	}

	/**
	 * @see ASTVisitor#endVisit(ImportDeclaration)
	 */
	public void endVisit(ImportDeclaration node) {

	}

	/**
	 * @see ASTVisitor#endVisit(InfixExpression)
	 */
	public void endVisit(InfixExpression node) {
	}

	/**
	 * @see ASTVisitor#endVisit(Initializer)
	 */
	public void endVisit(Initializer node) {

	}

	/**
	 * @see ASTVisitor#endVisit(InstanceofExpression)
	 */
	public void endVisit(InstanceofExpression node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(Javadoc)
	 */
	public void endVisit(Javadoc node) {

	}

	/**
	 * @see ASTVisitor#endVisit(LabeledStatement)
	 */
	public void endVisit(LabeledStatement node) {
		if (!isActive() || hasErrors())
			return;

		String label= node.getLabel().getIdentifier();

		// for each pending continue instruction which are related to
		// this statement, set the offset of the corresponding jump.
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			if (instruction.fLabel != null && instruction.fLabel.equals(label)) {
				iter.remove();
				Jump jumpInstruction= instruction.fInstruction;
				int instructionAddress= fInstructions.indexOf(jumpInstruction);
				if (instruction.fIsBreak) {
					// jump to the instruction after the statement
					jumpInstruction.setOffset(fInstructions.getEnd() - instructionAddress);
				}
			}
		}
	}

	/**
	 * @see ASTVisitor#endVisit(MethodDeclaration)
	 */
	public void endVisit(MethodDeclaration node) {
		setActive(false);
	}

	/**
	 * @see ASTVisitor#endVisit(MethodInvocation)
	 */
	public void endVisit(MethodInvocation node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(NullLiteral)
	 */
	public void endVisit(NullLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(NumberLiteral)
	 */
	public void endVisit(NumberLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(PackageDeclaration)
	 */
	public void endVisit(PackageDeclaration node) {

	}

	/**
	 * @see ASTVisitor#endVisit(SimpleType)
	 */
	public void endVisit(ParameterizedType node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ParenthesizedExpression)
	 */
	public void endVisit(ParenthesizedExpression node) {

	}

	/**
	 * @see ASTVisitor#endVisit(PostfixExpression)
	 */
	public void endVisit(PostfixExpression node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(PrefixExpression)
	 */
	public void endVisit(PrefixExpression node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(PrimitiveType)
	 */
	public void endVisit(PrimitiveType node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();		
	}

	/**
	 * @see ASTVisitor#endVisit(QualifiedName)
	 */
	public void endVisit(QualifiedName node) {
	}

	/**
	 * @see ASTVisitor#endVisit(SimpleType)
	 */
	public void endVisit(QualifiedType node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ReturnStatement)
	 */
	public void endVisit(ReturnStatement node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SimpleName)
	 */
	public void endVisit(SimpleName node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SimpleType)
	 */
	public void endVisit(SimpleType node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SingleVariableDeclaration)
	 */
	public void endVisit(SingleVariableDeclaration node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(StringLiteral)
	 */
	public void endVisit(StringLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SuperConstructorInvocation)
	 */
	public void endVisit(SuperConstructorInvocation node) {

	}

	/**
	 * @see ASTVisitor#endVisit(SuperFieldAccess)
	 */
	public void endVisit(SuperFieldAccess node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SuperMethodInvocation)
	 */
	public void endVisit(SuperMethodInvocation node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(SwitchCase)
	 */
	public void endVisit(SwitchCase node) {
		// never called
	}

	/**
	 * @see ASTVisitor#endVisit(SwitchStatement)
	 */
	public void endVisit(SwitchStatement node) {
		// nothing to do
	}

	/**
	 * @see ASTVisitor#endVisit(SynchronizedStatement)
	 */
	public void endVisit(SynchronizedStatement node) {

	}

	/**
	 * @see ASTVisitor#endVisit(ThisExpression)
	 */
	public void endVisit(ThisExpression node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(ThrowStatement)
	 */
	public void endVisit(ThrowStatement node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(TryStatement)
	 */
	public void endVisit(TryStatement node) {

	}

	/**
	 * @see ASTVisitor#endVisit(TypeDeclaration)
	 */
	public void endVisit(TypeDeclaration node) {

	}

	/**
	 * @see ASTVisitor#endVisit(TypeDeclarationStatement)
	 */
	public void endVisit(TypeDeclarationStatement node) {

	}

	/**
	 * @see ASTVisitor#endVisit(TypeLiteral)
	 */
	public void endVisit(TypeLiteral node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(VariableDeclarationExpression)
	 */
	public void endVisit(VariableDeclarationExpression node) {

	}

	/**
	 * @see ASTVisitor#endVisit(VariableDeclarationFragment)
	 */
	public void endVisit(VariableDeclarationFragment node) {
		if (!isActive() || hasErrors())
			return;
		storeInstruction();
	}

	/**
	 * @see ASTVisitor#endVisit(VariableDeclarationStatement)
	 */
	public void endVisit(VariableDeclarationStatement node) {

	}

	/**
	 * @see ASTVisitor#endVisit(WhileStatement)
	 */
	public void endVisit(WhileStatement node) {
		if (!isActive() || hasErrors())
			return;

		/* The structure of generated instructions is :
		 *
		 * --
		 * |condition
		 * --
		 * - jump to the instruction after the last jump if the condition is false.
		 * --
		 * | body
		 * --
		 * - jump to the first instruction of the condition.
		 *
		 */

		String label= getLabel(node);

		// get address of each part
		int bodyAddress= fInstructions.getEnd();
		Instruction body= fInstructions.getInstruction(bodyAddress);
		int conditionAddress= bodyAddress - body.getSize();
		Instruction condition= fInstructions.getInstruction(conditionAddress);

		// add the conditionnalJump
		ConditionalJump conditionalJump= new ConditionalJump(false);
		fInstructions.insert(conditionalJump, conditionAddress + 1);

		// add the jump
		Jump jump= new Jump();
		fInstructions.add(jump);

		// set jump offsets
		conditionalJump.setOffset(body.getSize() + 1);
		jump.setOffset(-(condition.getSize() + body.getSize() + 2));

		// for each pending break or continue instruction which are related to
		// this loop, set the offset of the corresponding jump.
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			Jump jumpInstruction= instruction.fInstruction;
			int instructionAddress= fInstructions.indexOf(jumpInstruction);
			if (instructionAddress > conditionAddress && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
				iter.remove();
				if (instruction.fIsBreak) {
					// jump to the instruction after the last jump
					jumpInstruction.setOffset((bodyAddress - instructionAddress) + 2);
				} else {
					// jump to the first instruction of the condition
					jumpInstruction.setOffset((conditionAddress - condition.getSize()) - instructionAddress);
				}
			}
		}

		fCounter+= 2;
		storeInstruction();
	}

	/*
	 * Visit methods
	 *
	 * There are two variations of node visiting:
	 * <ol>
	 * <li>Push the instruction corresponding to the node
	 *  onto the stack and return <code>true</code> to visit
	 *  the children of the node.</li>
	 * <li>Push the instruction corresponding to the node
	 *  onto the stack and visit the children of the node
	 *  manually (return <code>false</code> to avoid the
	 *  default child visiting implementation).</li>
	 * </ol>
	 */

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
	 */
	public boolean visit(AnnotationTypeDeclaration node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration)
	 */
	public boolean visit(AnnotationTypeMemberDeclaration node) {
		return false;
	}

	/**
	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
	 */
	public boolean visit(AnonymousClassDeclaration node) {
		if (!isActive()) {
			return true;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_2); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ArrayAccess)
	 */
	public boolean visit(ArrayAccess node) {
		if (!isActive()) {
			return false;
		}

		push(new org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAccess(fCounter));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(ArrayCreation)
	 */
	public boolean visit(ArrayCreation node) {
		if (!isActive()) {
			return false;
		}

		ArrayType arrayType= node.getType();

		ITypeBinding binding = resolveTypeBinding(arrayType);
		if (binding != null && isALocalType(binding.getElementType())) {
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Local_type_array_instance_creation_cannot_be_used_in_an_evaluation_expression_29); 
			setHasError(true);
			return false;
		}

		push(new ArrayAllocation(arrayType.getDimensions(), node.dimensions().size(), node.getInitializer() != null, fCounter));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(ArrayInitializer)
	 */
	public boolean visit(ArrayInitializer node) {
		if (!isActive()) {
			return false;
		}

		ITypeBinding typeBinding = resolveTypeBinding(node);
		if (typeBinding != null) {
			int dimension= typeBinding.getDimensions();
			String signature= getTypeSignature(typeBinding.getElementType());
			push(new ArrayInitializerInstruction(signature, node.expressions().size(), dimension, fCounter));
		}

		return true;
	}

	/**
	 * @see ASTVisitor#visit(ArrayType)
	 */
	public boolean visit(ArrayType node) {
		if (!isActive()) {
			return false;
		}
		ITypeBinding arrayTypeBinding= resolveTypeBinding(node);
		if (arrayTypeBinding != null) {
			int dimension= arrayTypeBinding.getDimensions();
			String signature= getTypeSignature(arrayTypeBinding.getElementType());
			push(new PushArrayType(signature, dimension, fCounter));
		}

		return false;
	}

	/**
	 * @see ASTVisitor#visit(AssertStatement)
	 */
	public boolean visit(AssertStatement node) {
		if (!isActive()) {
			return false;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Assert_statement_cannot_be_used_in_an_evaluation_expression_3); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(Assignment)
	 */
	public boolean visit(Assignment node) {
		if (!isActive()) {
			return false;
		}
		Expression leftHandSide= node.getLeftHandSide();
		Expression rightHandSide= node.getRightHandSide();
		int variableTypeId = getTypeId(leftHandSide);
		int valueTypeId = getTypeId(rightHandSide);

		String opToken = node.getOperator().toString();
		int opTokenLength = opToken.length();
		char char0 = opToken.charAt(0);
		char char2 = '\0';
		if (opTokenLength > 2) {
			char2 = opToken.charAt(2);
		}

		ITypeBinding rightBinding = resolveTypeBinding(rightHandSide);
		if (rightBinding == null) {
			return false;
		}
		ITypeBinding leftBinding = resolveTypeBinding(leftHandSide);
		if (leftBinding == null) {
			return false;
		}
		if (variableTypeId == Instruction.T_Object) {
			// If the variable is an object, the value may need to be boxed for
			// the simple assignment.
			// For the compound assignment operators, the value of the variable
			// have to be un-boxed before the operation is done, then re-boxed to
			// to be stored in the variable.
	
			int unboxedVariableTypeId= getUnBoxedTypeId(leftHandSide);
			int unboxedValueTypeId= getUnBoxedTypeId(rightHandSide);
			int unboxedResultTypeId= Instruction.getBinaryPromotionType(unboxedVariableTypeId, unboxedValueTypeId);

			push(new AssignmentOperator(variableTypeId, variableTypeId, fCounter));
			
			leftHandSide.accept(this);
			
			if (char0 == '=') {
				
				boolean storeRequired= false;
				if (rightBinding.isPrimitive()) {
					boxing(leftBinding, rightBinding);
					storeRequired= true;
				}
				rightHandSide.accept(this);
				if (storeRequired) {
					storeInstruction(); // boxing
				}
				
			} else {
				boolean unrecognized = false;
				
				
				boxing(leftBinding, rightBinding);
				
				switch (char0) {
					case '=': // equal
						break;
					case '+': // plus equal
						push(new PlusOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '-': // minus equal
						push(new MinusOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '*': // multiply equal
						push(new MultiplyOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '/': // divide equal
						push(new DivideOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '%': // remainder equal
						push(new RemainderOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '^': // XOr equal
						push(new XorOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '|': // or equal
						push(new OrOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '&': // and equal
						push(new AndOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '<': // left shift equal
						push(new LeftShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
						break;
					case '>': // right shift equal or unsigned right shift equal
						switch (char2) {
							case '=': // right shift equal
								push(new RightShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
								break;
							case '>': // unsigned right shift equal
								push(new UnsignedRightShiftOperator(unboxedVariableTypeId, unboxedValueTypeId, unboxedResultTypeId, fCounter));
								break;
							default:
								unrecognized = true;
								break;
						}
						break;
					default:
						unrecognized = true;
						break;
				}

				if (unrecognized) {
					setHasError(true);
					addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_assignment_operator____4 + opToken); 
					return false;
				}

				unBoxing(leftBinding);
				push(new Dup());
				storeInstruction(); // dupe
				storeInstruction(); // un-boxing
			
				boolean storeRequired= unBoxing(rightBinding);
				rightHandSide.accept(this);
				if (storeRequired) {
					storeInstruction(); // un-boxing
				}
				
				storeInstruction(); // operation
				storeInstruction(); // boxing
				
			}
			
		} else {
			boolean unrecognized = false;
			
			switch (char0) {
				case '=': // equal
					push(new AssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '+': // plus equal
					push(new PlusAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '-': // minus equal
					push(new MinusAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '*': // multiply equal
					push(new MultiplyAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '/': // divide equal
					push(new DivideAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '%': // remainder equal
					push(new RemainderAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '^': // XOr equal
					push(new XorAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '|': // or equal
					push(new OrAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '&': // and equal
					push(new AndAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '<': // left shift equal
					push(new LeftShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter));
					break;
				case '>': // right shift equal or unsigned right shift equal
					switch (char2) {
						case '=': // right shift equal
							push(new RightShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter));
							break;
						case '>': // unsigned right shift equal
							push(new UnsignedRightShiftAssignmentOperator(variableTypeId, valueTypeId, fCounter));
							break;
						default:
							unrecognized = true;
							break;
					}
					break;
				default:
					unrecognized = true;
					break;
			}
	
			if (unrecognized) {
				setHasError(true);
				addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_assignment_operator____4 + opToken); 
				return false;
			}
			
			leftHandSide.accept(this);
			boolean storeRequired= unBoxing(rightBinding);
			rightHandSide.accept(this);
			if (storeRequired) {
				storeInstruction();
			}
		}
	
		return false;
			
	}

	/**
	 * @see ASTVisitor#visit(Block)
	 */
	public boolean visit(Block node) {
		int start= node.getStartPosition();
		if (start == fStartPosition || start == (fStartPosition + 1)) {
			setActive(true);
		}
		if (!isActive()) {
			return true;
		}

		push(new NoOp(fCounter));

		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BlockComment)
	 */
	public boolean visit(BlockComment node) {
		return false;
	}
	
	/**
	 * @see ASTVisitor#visit(BooleanLiteral)
	 */
	public boolean visit(BooleanLiteral node) {
		if (!isActive()) {
			return false;
		}

		push(new PushBoolean(node.booleanValue()));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(BreakStatement)
	 */
	public boolean visit(BreakStatement node) {
		if (!isActive()) {
			return false;
		}
		// create the equivalent jump instruction in the instruction
		// and add an element in the list of pending break and continue
		// instructions
		Jump instruction= new Jump();
		SimpleName labelName= node.getLabel();
		String label= null;
		if (labelName != null) {
			label= labelName.getIdentifier();
		}
		push(instruction);
		fCompleteInstructions.add(new CompleteInstruction(instruction, label, true));

		return false;
	}

	/**
	 * @see ASTVisitor#visit(CastExpression)
	 */
	public boolean visit(CastExpression node) {
		if (!isActive()) {
			return false;
		}

		Type type= node.getType();
		int typeId= getTypeId(type);
		ITypeBinding typeBinding= resolveTypeBinding(type);
		
		if (typeBinding != null) {
			String baseTypeSignature;
			int dimension= typeBinding.getDimensions();
			if (typeBinding.isArray()) {
				typeBinding= typeBinding.getElementType();
			}
			baseTypeSignature= getTypeName(typeBinding);
			push(new Cast(typeId, baseTypeSignature, dimension, fCounter));
			node.getExpression().accept(this);
		}

		return false;
	}

	/**
	 * @see ASTVisitor#visit(CatchClause)
	 */
	public boolean visit(CatchClause node) {
		if (!isActive()) {
			return false;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Catch_clause_cannot_be_used_in_an_evaluation_expression_6); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(CharacterLiteral)
	 */
	public boolean visit(CharacterLiteral node) {
		if (!isActive()) {
			return false;
		}

		push(new PushChar(node.charValue()));

		return true;
	}

	/**
	 * return false, visit expression, type name & arguments, don't visit body declaration
	 * @see ASTVisitor#visit(ClassInstanceCreation)
	 */
	public boolean visit(ClassInstanceCreation node) {
		if (!isActive()) {
			return true;
		}

		if (node.getAnonymousClassDeclaration() != null) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Anonymous_type_declaration_cannot_be_used_in_an_evaluation_expression_7); 
		}

		IMethodBinding methodBinding= node.resolveConstructorBinding();
		if (methodBinding == null) {
			setHasError(true);
			addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_1, new String[]{node.toString()}));
			return false;
		}
		ITypeBinding typeBinding= methodBinding.getDeclaringClass();

		boolean isInstanceMemberType= typeBinding.isMember() && ! Modifier.isStatic(typeBinding.getModifiers());

		if (isALocalType(typeBinding)) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Constructor_of_a_local_type_cannot_be_used_in_an_evaluation_expression_8); 
		}

		if (containsALocalType(methodBinding)) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Constructor_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_30); 
		}


		if (hasErrors()) {
			return false;
		}

		int paramCount= methodBinding.getParameterTypes().length;

		String enclosingTypeSignature= null;
		ITypeBinding enclosingTypeBinding= null;
		if (isInstanceMemberType) {
			enclosingTypeBinding= typeBinding.getDeclaringClass();
			if (enclosingTypeBinding == null) {
				setHasError(true);
				addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_2, new String[]{typeBinding.getQualifiedName()}));
				return false;
			}
			enclosingTypeSignature= getTypeSignature(enclosingTypeBinding);
			paramCount++;
		}

		String signature= getMethodSignature(methodBinding, enclosingTypeSignature).replace('.','/');

		push(new Constructor(signature, paramCount, fCounter));

		push(new PushType(getTypeName(typeBinding)));
		storeInstruction();

		if (isInstanceMemberType) {
			Expression optionalExpression= node.getExpression();
			if (optionalExpression != null) {
				optionalExpression.accept(this);
			} else {
				// for a non-static inner class, check if we are not in a static context (method)
				ASTNode parent= node;
				do {
					parent= parent.getParent();
				} while (! (parent instanceof MethodDeclaration));
				if (Modifier.isStatic(((MethodDeclaration)parent).getModifiers())) {
					setHasError(true);
					addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Must_explicitly_qualify_the_allocation_with_an_instance_of_the_enclosing_type_33); 
					return false;
				}

				push(new PushThis(getEnclosingLevel(node, enclosingTypeBinding)));
				storeInstruction();
			}
		}

		List arguments = node.arguments();
		pushMethodArguments(methodBinding, arguments);

		return false;
	}

	/**
	 * @see ASTVisitor#visit(CompilationUnit)
	 */
	public boolean visit(CompilationUnit node) {
		return true;
	}

	/**
	 * @see ASTVisitor#visit(ConditionalExpression)
	 */
	public boolean visit(ConditionalExpression node) {
		if (!isActive()) {
			return true;
		}

		push(new NoOp(fCounter));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(ConstructorInvocation)
	 */
	public boolean visit(ConstructorInvocation node) {
		if (!isActive()) {
			return false;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_this_constructor_invocation_cannot_be_used_in_an_evaluation_expression_9); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ContinueStatement)
	 */
	public boolean visit(ContinueStatement node) {
		if (!isActive()) {
			return false;
		}
		// create the equivalent jump instruction in the instruction
		// and add an element in the list of pending break and continue
		// instructions
		Jump instruction= new Jump();
		SimpleName labelName= node.getLabel();
		String label= null;
		if (labelName != null) {
			label= labelName.getIdentifier();
		}
		push(instruction);
		fCompleteInstructions.add(new CompleteInstruction(instruction, label, false));

		return false;
	}

	/**
	 * @see ASTVisitor#visit(DoStatement)
	 */
	public boolean visit(DoStatement node) {
		if (!isActive()) {
			return false;
		}

		push(new NoOp(fCounter));
		return true;
	}

	/**
	 * @see ASTVisitor#visit(EmptyStatement)
	 */
	public boolean visit(EmptyStatement node) {
		if (!isActive()) {
			return false;
		}
		push(new NoOp(fCounter));
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnhancedForStatement)
	 */
	public boolean visit(EnhancedForStatement node) {
		if (!isActive()) {
			return false;
		}
		
		push(new NoOp(fCounter));
		
		
		ITypeBinding typeBinding= resolveTypeBinding(node.getExpression());
		if (typeBinding == null) {
			return false;
		}
		Type paramType= node.getParameter().getType();
        ITypeBinding paramBinding = resolveTypeBinding(paramType);
        if (paramBinding == null) {
			return false;
        }
		String typeSignature= getTypeSignature(paramBinding);
		int paramTypeId= getTypeId(paramType);
		boolean isParamPrimitiveType= paramTypeId != Instruction.T_Object && paramTypeId != Instruction.T_String;
		String paramIdentifier= node.getParameter().getName().getIdentifier();
		
		if (typeBinding.isArray()) {
			// the expression returns an array
			int idIndex= fUniqueIdIndex++;
			String arrayIdentifier= "#a" + idIndex; //$NON-NLS-1$
			String varIdentifier= "#i" + idIndex; //$NON-NLS-1$
			push(new LocalVariableCreation(arrayIdentifier, typeSignature, 1, isParamPrimitiveType, true, fCounter));
				node.getExpression().accept(this);
			storeInstruction();
			push(new LocalVariableCreation(varIdentifier, "I", 0, true, true, fCounter)); //$NON-NLS-1$
				push(new PushInt(0));
				storeInstruction();
			storeInstruction();
			push(new LocalVariableCreation(paramIdentifier, typeSignature, 0, isParamPrimitiveType, false, fCounter));
			storeInstruction();
			
			push(new LessOperator(Instruction.T_int, Instruction.T_int, fCounter));
				push(new PushLocalVariable(varIdentifier));
				storeInstruction();
				push(new PushArrayLength(fCounter));
					push(new PushLocalVariable(arrayIdentifier));
					storeInstruction();
				storeInstruction();
			storeInstruction();
			
			// conditional jump will be added here
			
			push(new NoOp(fCounter));
				push(new AssignmentOperator(paramTypeId, paramTypeId, fCounter));
					push(new PushLocalVariable(paramIdentifier));
					storeInstruction();
					push(new org.eclipse.jdt.internal.debug.eval.ast.instructions.ArrayAccess(fCounter));
						push(new PushLocalVariable(arrayIdentifier));
						storeInstruction();
						push(new PostfixPlusPlusOperator(Instruction.T_int, fCounter));
							push(new PushLocalVariable(varIdentifier));
							storeInstruction();
						storeInstruction();
					storeInstruction();
                    if (checkAutoBoxing(typeBinding.getElementType(), paramBinding)) {
                        storeInstruction();
                    }                        
				storeInstruction();
				addPopInstruction();
				node.getBody().accept(this);
			storeInstruction();
			
			// jump will be added here
			
		} else {
			// the expression returns a collection
			String iteratorIdentifier= "#i" + fUniqueIdIndex++; //$NON-NLS-1$
			push(new LocalVariableCreation(iteratorIdentifier, "Ljava/util/Iterator;", 0, false, true, fCounter)); //$NON-NLS-1$
				push(new SendMessage("iterator", "()Ljava/util/Iterator;", 0, null, fCounter));  //$NON-NLS-1$//$NON-NLS-2$
					node.getExpression().accept(this);
				storeInstruction();
			storeInstruction();
			push(new LocalVariableCreation(paramIdentifier, typeSignature, 0, isParamPrimitiveType, false, fCounter));
			storeInstruction();
			
			push(new SendMessage("hasNext", "()Z", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
				push(new PushLocalVariable(iteratorIdentifier));
				storeInstruction();
			storeInstruction();
			
			// conditional jump will be added here
			
			push(new NoOp(fCounter));
				push(new AssignmentOperator(paramTypeId, paramTypeId, fCounter));
					push(new PushLocalVariable(paramIdentifier));
					storeInstruction();
					push(new SendMessage("next", "()Ljava/lang/Object;", 0, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
						push(new PushLocalVariable(iteratorIdentifier));
						storeInstruction();
					storeInstruction();
                    if (checkAutoBoxing(typeBinding.getTypeArguments()[0], paramBinding)) {
                        storeInstruction();
                    }
				storeInstruction();
				addPopInstruction();
				node.getBody().accept(this);
			storeInstruction();
			
			// jump will be added here
			
		}

		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
	 */
	public boolean visit(EnumConstantDeclaration node) {
		if (!isActive()) {
			return true;
		}

		// nothing to do, we shouldn't hit this node
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration)
	 */
	public boolean visit(EnumDeclaration node) {
		if (!isActive()) {
			return true;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_0); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ExpressionStatement)
	 */
	public boolean visit(ExpressionStatement node) {
		return true;
	}

	/**
	 * return false, visit expression, don't visit name
	 *
	 * @see ASTVisitor#visit(FieldAccess)
	 */
	public boolean visit(FieldAccess node) {
		if (!isActive()) {
			return false;
		}

		SimpleName fieldName= node.getName();
		IVariableBinding fieldBinding= (IVariableBinding) fieldName.resolveBinding();
		if(fieldBinding != null) {
			ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass();
			Expression expression = node.getExpression();
			String fieldId = fieldName.getIdentifier();
	
			if (Modifier.isStatic(fieldBinding.getModifiers())) {
				push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter));
				expression.accept(this);
				addPopInstruction();
			} else {
				if (declaringTypeBinding == null) { // it is a field without declaring type => it is the special length array field
					push(new PushArrayLength(fCounter));
				} else {
					if (isALocalType(declaringTypeBinding)) {
						setHasError(true);
						addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Qualified_local_type_field_access_cannot_be_used_in_an_evaluation_expression_31); 
						return false;
					}
					push(new PushFieldVariable(fieldId, getTypeSignature(declaringTypeBinding), fCounter));
				}
				expression.accept(this);
			}
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(FieldDeclaration)
	 */
	public boolean visit(FieldDeclaration node) {
		return true;
	}

	/**
	 * @see ASTVisitor#visit(ForStatement)
	 * return <code>false</code>, don't use the standard accept order.
	 * order used for visiting children :
	 * initializers, condition, body, updaters
	 */
	public boolean visit(ForStatement node) {
		if (!isActive()) {
			return false;
		}

		push(new NoOp(fCounter));

		push(new NoOp(fCounter));
		for (Iterator iter= node.initializers().iterator(); iter.hasNext();) {
			Expression expr= (Expression) iter.next();
			expr.accept(this);
			addPopInstructionIfNeeded(expr);
		}
		storeInstruction();

		Expression condition= node.getExpression();
		if (condition != null) {
			condition.accept(this);
		}

		node.getBody().accept(this);

		push(new NoOp(fCounter));
		for (Iterator iter= node.updaters().iterator(); iter.hasNext();) {
			Expression expr= (Expression) iter.next();
			expr.accept(this);
			addPopInstructionIfNeeded(expr);
		}
		storeInstruction();

		return false;
	}

	/**
	 * @see ASTVisitor#visit(IfStatement)
	 */
	public boolean visit(IfStatement node) {
		if (!isActive()) {
			return false;
		}

		push(new NoOp(fCounter));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(ImportDeclaration)
	 */
	public boolean visit(ImportDeclaration node) {
		return false;
	}

	/**
	 * return <code>false</code>, don't use the standard accept order.
	 *
	 * @see ASTVisitor#visit(InfixExpression)
	 */
	public boolean visit(InfixExpression node) {
		if (!isActive()) {
			return false;
		}

		String opToken = node.getOperator().toString();
		int opTokenLength = opToken.length();
		char char0 = opToken.charAt(0);
		char char1 = '\0';
		char char2 = '\0';
		if (opTokenLength > 1) {
			char1 = opToken.charAt(1);
			if (opTokenLength > 2) {
				char2 = opToken.charAt(2);
			}
		}

		List extendedOperands = node.extendedOperands();

		int operatorNumber=extendedOperands.size() + 1;

		int[][] types = new int[operatorNumber][3];

		Iterator iterator = extendedOperands.iterator();

		Expression leftOperand= node.getLeftOperand();
		Expression rightOperand= node.getRightOperand();
		int leftTypeId;
		int rightTypeId;
		boolean unbox = false;
		// for == and != un-box when at least operand is primitive (otherwise compare the objects)
		ITypeBinding leftBinding = resolveTypeBinding(leftOperand);
		if (leftBinding == null) {
			return false;
		}
		ITypeBinding rightBinding = resolveTypeBinding(rightOperand);
		if (rightBinding == null) {
			return false;
		}
		if ((char0 == '=' || char0 == '!') && char1 == '=') {
			unbox = leftBinding.isPrimitive() || rightBinding.isPrimitive();
		} else {
			unbox = true;
		}
		if (unbox) {
			leftTypeId= getUnBoxedTypeId(leftOperand);
			rightTypeId = getUnBoxedTypeId(rightOperand);
		} else {
			leftTypeId= getTypeId(leftOperand);
			rightTypeId = getTypeId(rightOperand);
		}
		int resultTypeId = Instruction.getBinaryPromotionType(leftTypeId, rightTypeId);

		types[0][0] = resultTypeId;
		types[0][1] = leftTypeId;
		types[0][2] = rightTypeId;

		for (int i = 1; i < operatorNumber; i++) {
			Expression operand = (Expression) iterator.next();
			leftTypeId = resultTypeId;
			rightTypeId = getUnBoxedTypeId(operand);
			resultTypeId = Instruction.getBinaryPromotionType(leftTypeId, rightTypeId);
			types[i][0] = resultTypeId;
			types[i][1] = leftTypeId;
			types[i][2] = rightTypeId;
		}

		boolean unrecognized= false;

		switch (char0) {
			case '*': // multiply
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new MultiplyOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '/': // divide
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new DivideOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '%': // remainder
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new RemainderOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '+': // plus
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new PlusOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '-': // minus
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new MinusOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '<': // left shift or less or less equal
				switch (char1) {
					case '\0': // less
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new LessOperator(types[i][1], types[i][2], fCounter));
						}
						break;
					case '<': // left shift
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new LeftShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter));
						}
						break;
					case '=': // less equal
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new LessEqualOperator(types[i][1], types[i][2], fCounter));
						}
						break;
					default:
						unrecognized= true;
						break;
				}
				break;
			case '>': // right shift or unsigned right shift or greater or greater equal
				switch (char1) {
					case '\0': // greater
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new GreaterOperator(types[i][1], types[i][2], fCounter));
						}
						break;
					case '>': // right shift or unsigned right shift
						switch (char2) {
							case '\0': // right shift
								for (int i = operatorNumber - 1; i >= 0; i--) {
									push(new RightShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter));
								}
								break;
							case '>': // unsigned right shift
								for (int i = operatorNumber - 1; i >= 0; i--) {
									push(new UnsignedRightShiftOperator(Instruction.getUnaryPromotionType(types[i][1]), types[i][1], types[i][2], fCounter));
								}
								break;
						}
						break;
					case '=': // greater equal
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new GreaterEqualOperator(types[i][1], types[i][2], fCounter));
						}
						break;
					default:
						unrecognized= true;
						break;
				}
				break;
			case '=': // equal equal
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new EqualEqualOperator(types[i][1], types[i][2], true, fCounter));
				}
				break;
			case '!': // not equal
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new EqualEqualOperator(types[i][1], types[i][2], false, fCounter));
				}
				break;
			case '^': // XOr
				for (int i = operatorNumber - 1; i >= 0; i--) {
					push(new XorOperator(types[i][0], types[i][1], types[i][2], fCounter));
				}
				break;
			case '|': // or or or or
				switch (char1) {
					case '\0': // or
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new OrOperator(types[i][0], types[i][1], types[i][2], fCounter));
						}
						break;
					case '|': // or or
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new NoOp(fCounter));
						}
						break;
					default:
						unrecognized= true;
						break;
				}
				break;
			case '&': // and or and and
				switch (char1) {
					case '\0': // and
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new AndOperator(types[i][0], types[i][1], types[i][2], fCounter));
						}
						break;
					case '&': // and and
						for (int i = operatorNumber - 1; i >= 0; i--) {
							push(new NoOp(fCounter));
						}
						break;
					default:
						unrecognized= true;
						break;
				}
				break;
			default:
				unrecognized= true;
				break;
		}

		if (unrecognized) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Unrecognized_infix_operator____13 + opToken); 
		}

		if (hasErrors()) {
			return false;
		}

		iterator = extendedOperands.iterator();

		if ((char0 == '&' && char1 == '&') || (char0 == '|' && char1 == '|')) { // and and operator

			boolean isOrOr= char0 == '|';

			ConditionalJump[] conditionalJumps= new ConditionalJump[operatorNumber];
			int[] conditionalJumpAddresses = new int[operatorNumber];

			boolean storeRequired= unBoxing(leftBinding);
			leftOperand.accept(this);
			if (storeRequired) {
				storeInstruction();
			}

			ConditionalJump conditionalJump= new ConditionalJump(isOrOr);
			conditionalJumps[0]= conditionalJump;
			conditionalJumpAddresses[0] = fCounter;
			push(conditionalJump);
			storeInstruction();

			storeRequired= unBoxing(rightBinding);
			rightOperand.accept(this);
			if (storeRequired) {
				storeInstruction();
			}

			for (int i= 1; i < operatorNumber; i ++) {
				conditionalJump= new ConditionalJump(isOrOr);
				conditionalJumps[i]= conditionalJump;
				conditionalJumpAddresses[i] = fCounter;
				push(conditionalJump);
				storeInstruction();
				Expression operand= (Expression) iterator.next();
				ITypeBinding typeBinding = resolveTypeBinding(operand);
				if (typeBinding == null) {
					return false;
				}
				storeRequired= unBoxing(typeBinding);
				operand.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}

			Jump jump = new Jump();
			jump.setOffset(1);
			push(jump);
			storeInstruction();

			for (int i= 0; i < operatorNumber; i ++) {
				conditionalJumps[i].setOffset(fCounter - conditionalJumpAddresses[i] - 1);
			}

			push(new PushBoolean(isOrOr));
			storeInstruction();

			// store the no-op
			storeInstruction();

		} else { // other operators

			boolean storeRequired= false;
			if (unbox) {
				storeRequired= unBoxing(leftBinding);
			}
			leftOperand.accept(this);
			if (storeRequired) {
				storeInstruction();
			}
			if (unbox) {
				storeRequired= unBoxing(rightBinding);
			}
			rightOperand.accept(this);
			if (storeRequired) {
				storeInstruction();
			}

			storeInstruction();
			for (int i= 1; i < operatorNumber; i ++) {
				Expression operand= (Expression) iterator.next();
				if (unbox) {
					ITypeBinding typeBinding = resolveTypeBinding(operand);
					if (typeBinding == null) {
						return false;
					}
					storeRequired= unBoxing(typeBinding);
				}
				operand.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
				storeInstruction();
			}
		}



		return false;
	}

	/**
	 * @see ASTVisitor#visit(Initializer)
	 */
	public boolean visit(Initializer node) {
		return true;
	}

	/**
	 * @see ASTVisitor#visit(InstanceofExpression)
	 */
	public boolean visit(InstanceofExpression node) {
		if (!isActive()) {
			return false;
		}
		push(new InstanceOfOperator(fCounter));
		return true;
	}

	/**
	 * @see ASTVisitor#visit(Javadoc)
	 */
	public boolean visit(Javadoc node) {
		return false;
	}

	/**
	 * @see ASTVisitor#visit(LabeledStatement)
	 * return <code>false</code>, don't use the standard accept order.
	 */
	public boolean visit(LabeledStatement node) {
		node.getBody().accept(this);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LineComment)
	 */
	public boolean visit(LineComment node) {
		return false;
	}


	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
	 */
	public boolean visit(MarkerAnnotation node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef)
	 */
	public boolean visit(MemberRef node) {
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberValuePair)
	 */
	public boolean visit(MemberValuePair node) {
		return false;
	}
	
	/**
	 * @see ASTVisitor#visit(MethodDeclaration)
	 */
	public boolean visit(MethodDeclaration node) {
		int start= node.getStartPosition();
		int end= start + node.getLength();
		if (start < fStartPosition && end > fStartPosition) {
			return true;
		}
		return false;
	}

	/**
	 * return false, don't visit name, visit expression & arguments
	 *
	 * @see ASTVisitor#visit(MethodInvocation)
	 */
	public boolean visit(MethodInvocation node) {
		if (!isActive()) {
			return false;
		}

		IMethodBinding methodBinding= (IMethodBinding) node.getName().resolveBinding();
		if (methodBinding == null) {
			// could be the receiver is not visible - for example a private field access from super class
			ASTNode root = node.getRoot();
			if (root instanceof CompilationUnit) {
				CompilationUnit cu = (CompilationUnit) root;
				IProblem[] problems = cu.getProblems();
				for (int i = 0; i < problems.length; i++) {
					IProblem problem = problems[i];
					setHasError(true);
					addErrorMessage(problem.getMessage());
				}
			}
		}
		
		if (hasErrors()) {
			return false;
		}

		if (containsALocalType(methodBinding)) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Method_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_32);
			return false;
		}

		int paramCount = methodBinding.getParameterTypes().length;
		String selector= methodBinding.getName();

		String signature= getMethodSignature(methodBinding, null).replace('.','/');

		boolean isStatic= Flags.isStatic(methodBinding.getModifiers());
		Expression expression= node.getExpression();

		if (isStatic) {
			String typeName= getTypeName(methodBinding.getDeclaringClass());
			push(new SendStaticMessage(typeName, selector, signature, paramCount, fCounter));
			if (expression != null) {
				node.getExpression().accept(this);
				addPopInstruction();
			}
		} else {
			push(new SendMessage(selector, signature, paramCount, null, fCounter));
			if (expression == null) {
				push(new PushThis(getEnclosingLevel(node, methodBinding.getDeclaringClass())));
				storeInstruction();
			} else {
				node.getExpression().accept(this);
			}
		}

		List arguments = node.arguments();
		pushMethodArguments(methodBinding, arguments);

		return false;
	}
	
	/**
	 * Pushes method arguments onto the stack for a method or constructor invocation taking
	 * variable arguments and auto-boxing into consideration.
	 * 
	 * @param methodBinding method or constructor being called
	 * @param arguments argument list
	 */
	private void pushMethodArguments(IMethodBinding methodBinding, List arguments) {
		int argCount = arguments.size();
		ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
		int paramCount = parameterTypes.length;
		ITypeBinding lastArgBinding = null;
		if (methodBinding.isVarargs()) {
			Expression lastArg = (Expression)arguments.get(argCount - 1);
			lastArgBinding = resolveTypeBinding(lastArg);
			if (lastArgBinding == null) {
				return;
			}
		}
		if (methodBinding.isVarargs() && !(paramCount == argCount && parameterTypes[paramCount - 1].getDimensions() == lastArgBinding.getDimensions())) {
			// if this method is a varargs, and if the method is invoked using the varargs syntax
			// (multiple arguments) and not an array
			Iterator iterator= arguments.iterator();
			// process the first arguments (no part of the variable argument)
			for (int i= 0; i < paramCount - 1; i++) {
				Expression argument= (Expression)iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i]);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
			// create a array of the remainder arguments
			ITypeBinding varargsParameterType= parameterTypes[paramCount - 1];
			ITypeBinding varargsElementType= varargsParameterType.getElementType();
			push(new ArrayInitializerInstruction(getTypeSignature(varargsElementType), argCount - paramCount + 1, varargsParameterType.getDimensions(), fCounter));
			while (iterator.hasNext()) {
				Expression argument= (Expression) iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), varargsElementType);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
			storeInstruction();
		} else {
			Iterator iterator= arguments.iterator();
			int i= 0;
			while (iterator.hasNext()) {
				Expression argument= (Expression) iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i++]);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
		} 
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef)
	 */
	public boolean visit(MethodRef node) {
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter)
	 */
	public boolean visit(MethodRefParameter node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Modifier)
	 */
	public boolean visit(Modifier node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NormalAnnotation)
	 */
	public boolean visit(NormalAnnotation node) {
		return false;
	}

	/**
	 * @see ASTVisitor#visit(NullLiteral)
	 */
	public boolean visit(NullLiteral node) {
		if (!isActive()) {
			return false;
		}

		push(new PushNull());

		return true;
	}

	/**
	 * @see ASTVisitor#visit(NumberLiteral)
	 */
	public boolean visit(NumberLiteral node) {
		if (!isActive()) {
			return false;
		}

		int literalType= getTypeId(node);
		String token= node.getToken();
		int tokenLastCharOffset= token.length() - 1;
		char lastChar= token.charAt(tokenLastCharOffset);
		String subToken= token.substring(0, tokenLastCharOffset);


		switch (literalType) {
			case Instruction.T_int:
				push(new PushInt(parseIntValue(token)));
				break;
			case Instruction.T_long:
				push(new PushLong(parseLongValue(subToken)));
				break;
			case Instruction.T_float:
				push(new PushFloat(Float.parseFloat(subToken)));
				break;
			case Instruction.T_double:
				if (lastChar == 'D' || lastChar == 'd') {
					push(new PushDouble(Double.parseDouble(subToken)));
				} else {
					push(new PushDouble(Double.parseDouble(token)));
				}
				break;
		}

		return true;
	}

	/**
	 * Method parseIntValue.
	 * @param token
	 */
	private int parseIntValue(String token) {
		int tokenLength= token.length();
		if (tokenLength < 10) {
			// Integer.decode can handle tokens with less than 10 digits
			return Integer.decode(token).intValue();
		} 
		switch (getBase(token)) {
			case 8:
				return (Integer.decode(token.substring(0, tokenLength - 1)).intValue() << 3) | Integer.decode("0" + token.charAt(tokenLength - 1)).intValue(); //$NON-NLS-1$
			case 10:
				return Integer.decode(token).intValue();
			case 16:
				return (Integer.decode(token.substring(0, tokenLength - 1)).intValue() << 4) | Integer.decode("0x" + token.charAt(tokenLength - 1)).intValue(); //$NON-NLS-1$
			default:
				// getBase(String) only returns 8, 10, or 16. This code is unreachable
				return 0;
		}
	}


	/**
	 * Method parseLongValue.
	 * @param token
	 */
	private long parseLongValue(String token) {
		int tokenLength= token.length();
		if (tokenLength < 18) {
			// Long.decode can handle tokens with less than 18 digits
			return Long.decode(token).longValue();
		} 
		switch (getBase(token)) {
			case 8:
				return (Long.decode(token.substring(0, tokenLength - 1)).longValue() << 3) | Long.decode("0" + token.charAt(tokenLength - 1)).longValue(); //$NON-NLS-1$
			case 10:
				return Long.decode(token).longValue();
			case 16:
				return (Long.decode(token.substring(0, tokenLength - 1)).longValue() << 4) | Long.decode("0x" + token.charAt(tokenLength - 1)).longValue(); //$NON-NLS-1$
			default:
				// getBase(String) only returns 8, 10, or 16. This code is unreachable
				return 0;
		}
	}

	/**
	 * Returns the numeric base for the given token
	 * according to the Java specification. Returns
	 * 8, 10, or 16.
	 */
	private int getBase(String token) {
		if (token.charAt(0) == '0') {
			if (token.charAt(1) == 'x') {
				return 16; // "0x" prefix: Hexadecimal
			} 
			return 8; // "0" prefix: Octal
		} 
		return 10; // No prefix: Decimal
	}

	/**
	 * @see ASTVisitor#visit(PackageDeclaration)
	 */
	public boolean visit(PackageDeclaration node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParameterizedType)
	 */
	public boolean visit(ParameterizedType node) {
		if (!isActive()) {
			return false;
		}
		ITypeBinding typeBinding  = resolveTypeBinding(node);
		if (typeBinding != null) {
			push(new PushType(getTypeName(typeBinding)));
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ParenthesizedExpression)
	 */
	public boolean visit(ParenthesizedExpression node) {
		if (!isActive()) {
			return false;
		}
		return true;
	}

	/**
	 * @see ASTVisitor#visit(PostfixExpression)
	 */
	public boolean visit(PostfixExpression node) {
		if (!isActive()) {
			return false;
		}

		Expression operand= node.getOperand();
		int expressionTypeId = getTypeId(operand);

		String opToken = node.getOperator().toString();
		char char0 = opToken.charAt(0);
		
		if (expressionTypeId == Instruction.T_Object) {

			int expressionUnBoxedTypeId= getUnBoxedTypeId(operand);
			
			AssignmentOperator assignmentInstruction= new AssignmentOperator(Instruction.T_Object, Instruction.T_Object, fCounter);
			push(assignmentInstruction);
			operand.accept(this);
			switch (char0) {
				case '+': // plus plus
					push(new PlusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter));
					break;
				case '-': // minus minus
					push(new MinusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter));
					break;
				default:
					setHasError(true);
					addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_postfix_operator____15 + opToken); 
					return false;
			}
			push(new Value(fCounter));
			push(new Dup());
			storeInstruction(); // dupe
			storeInstruction(); // value
			push(new DupX1());
			storeInstruction(); // dup_x1
			ITypeBinding typeBinding = resolveTypeBinding(operand);
			if (typeBinding == null) {
				return false;
			}
			unBoxing(typeBinding);
			storeInstruction(); // un-boxing
			push(new PushInt(1));
			storeInstruction(); // push 1
			storeInstruction(); // operator
			boxing(typeBinding, null);
			storeInstruction(); // boxing
			storeInstruction(); // assignment
			push(new Pop(assignmentInstruction.getSize() + 1));
			
			
			return false;
		}

		switch (char0) {
			case '+': // plus plus
				push(new PostfixPlusPlusOperator(expressionTypeId, fCounter));
				break;
			case '-': // minus minus
				push(new PostfixMinusMinusOperator(expressionTypeId, fCounter));
				break;
			default:
				setHasError(true);
				addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_postfix_operator____15 + opToken); 
				return false;
		}

		return true;
	}

	/**
	 * @see ASTVisitor#visit(PrefixExpression)
	 */
	public boolean visit(PrefixExpression node) {
		if (!isActive()) {
			return false;
		}

		Expression operand= node.getOperand();
		int expressionTypeId = getTypeId(operand);

		String opToken = node.getOperator().toString();
		int opTokenLength = opToken.length();
		char char0 = opToken.charAt(0);
		char char1 = '\0';
		if (opTokenLength > 1) {
			char1 = opToken.charAt(1);
		}

		boolean unrecognized = false;
		
		if (expressionTypeId == Instruction.T_Object) {
			
			int expressionUnBoxedTypeId= getUnBoxedTypeId(operand);
			
			ITypeBinding typeBinding = resolveTypeBinding(operand);
			if (typeBinding == null) {
				return false;
			}
			if (char1 == '\0') {
				switch (char0) {
					case '+': // unary plus
						push(new UnaryPlusOperator(expressionUnBoxedTypeId, fCounter));
						break;
					case '-': // unary minus
						push(new UnaryMinusOperator(expressionUnBoxedTypeId, fCounter));
						break;
					case '~': // twiddle
						push(new TwiddleOperator(expressionUnBoxedTypeId, fCounter));
						break;
					case '!': // not
						push(new NotOperator(expressionUnBoxedTypeId, fCounter));
						break;
					default:
						setHasError(true);
						addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 
						return false;
				}
	
				unBoxing(typeBinding);
				operand.accept(this);
				storeInstruction(); // un-boxing
				
			} else {
				// plus plus and minus minus operators
				
				push(new AssignmentOperator(Instruction.T_Object, Instruction.T_Object, fCounter));
				
				operand.accept(this);
				
				boxing(typeBinding, null);
				
				switch (char1) {
					case '+':
						push(new PlusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter));
						break;
					case '-':
						push(new MinusOperator(expressionUnBoxedTypeId, expressionUnBoxedTypeId, expressionUnBoxedTypeId, fCounter));
						break;
					default:
						setHasError(true);
						addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 
						return false;
				}
				
				unBoxing(typeBinding);
				push(new Dup());
				storeInstruction(); // dupe
				storeInstruction(); // un-boxing
				push(new PushInt(1));
				storeInstruction(); // push 1
				
				storeInstruction(); // operator
				storeInstruction(); // boxing
				
			}
			
			return false;
		}
		
		switch (char0) {
			case '+': // plus plus or unary plus
				switch (char1) {
					case '\0': // unary plus
						push(new UnaryPlusOperator(expressionTypeId, fCounter));
						break;
					case '+': // plus plus
						push(new PrefixPlusPlusOperator(expressionTypeId, fCounter));
						break;
					default:
						unrecognized= true;
						break;
				}
				break;
			case '-': // minus minus or unary minus
				switch (char1) {
					case '\0': // unary minus
						push(new UnaryMinusOperator(expressionTypeId, fCounter));
					break;
					case '-': // minus minus
						push(new PrefixMinusMinusOperator(expressionTypeId, fCounter));
					break;
					default:
						unrecognized= true;
						break;
				}
				break;
			case '~': // twiddle
				push(new TwiddleOperator(expressionTypeId, fCounter));
				break;
			case '!': // not
				push(new NotOperator(expressionTypeId, fCounter));
				break;
			default:
				unrecognized= true;
				break;
		}


		if (unrecognized) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_unrecognized_prefix_operator____16 + opToken); 
			return false;
		}

		return true;
	}

	/**
	 * @see ASTVisitor#visit(PrimitiveType)
	 */
	public boolean visit(PrimitiveType node) {
		if (!isActive()) {
			return false;
		}
		ITypeBinding typeBinding  = resolveTypeBinding(node);
		if (typeBinding != null) {
			push(new PushPrimitiveType(getTypeName(typeBinding)));
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(QualifiedName)
	 */
	public boolean visit(QualifiedName node) {
		if (!isActive()) {
			return false;
		}

		if (hasErrors()) {
			return true;
		}

		IBinding binding = resolveBinding(node);
		if (binding == null) {
			return false;
		}
		switch (binding.getKind()) {
			case IBinding.TYPE:
				node.getName().accept(this);
				break;
			case IBinding.VARIABLE:
				SimpleName fieldName= node.getName();
				IVariableBinding fieldBinding= (IVariableBinding) resolveBinding(fieldName);
				if (fieldBinding == null) {
					return false;
				}
				ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass();
				String fieldId = fieldName.getIdentifier();

				if (Modifier.isStatic(fieldBinding.getModifiers())) {
					push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter));
				} else {
					if (declaringTypeBinding == null) {
						push(new PushArrayLength(fCounter));
					} else {
						push(new PushFieldVariable(fieldId, getTypeSignature(declaringTypeBinding), fCounter));
					}
					node.getQualifier().accept(this);
				}
				storeInstruction();
				break;
		}

		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedType)
	 */
	public boolean visit(QualifiedType node) {
		if (!isActive()) {
			return false;
		}
		ITypeBinding typeBinding  = resolveTypeBinding(node);
		if (typeBinding != null) {
			push(new PushType(getTypeName(typeBinding)));
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ReturnStatement)
	 */
	public boolean visit(ReturnStatement node) {
		if (!isActive()) {
			return false;
		}
		push(new ReturnInstruction(fCounter));
		return true;
	}

	/**
	 * @see ASTVisitor#visit(SimpleName)
	 */
	public boolean visit(SimpleName node) {
		if (!isActive()) {
			return false;
		}

		if (hasErrors()) {
			return true;
		}

		IBinding binding = resolveBinding(node);
		if (binding == null) {
			return true;
		}
		String variableId = node.getIdentifier();

		switch (binding.getKind()) {
			case IBinding.TYPE:
				ITypeBinding typeBinding= (ITypeBinding) binding;
				push(new PushType(getTypeName(typeBinding)));
				break;
			case IBinding.VARIABLE:
				IVariableBinding variableBinding= (IVariableBinding) binding;
				ITypeBinding declaringTypeBinding= variableBinding.getDeclaringClass();
				if (variableBinding.isField()) {
					if (Modifier.isStatic(variableBinding.getModifiers())) {
						push(new PushStaticFieldVariable(variableId, getTypeName(declaringTypeBinding), fCounter));
					} else {
						if (isALocalType(declaringTypeBinding)) {
							setHasError(true);
							addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_36); 
							return false;
						}
						push(new PushFieldVariable(variableId, getTypeSignature(declaringTypeBinding), fCounter));
						push(new PushThis(getEnclosingLevel(node, declaringTypeBinding)));
						storeInstruction();
					}
				} else {
					push(new PushLocalVariable(variableId));
				}
				break;
		}
		return true;
	}

	/**
	 * return false, don't visit child
	 *
	 * @see ASTVisitor#visit(SimpleType)
	 */
	public boolean visit(SimpleType node) {
		if (!isActive()) {
			return false;
		}

		ITypeBinding typeBinding  = resolveTypeBinding(node);
		if (typeBinding != null) {
			push(new PushType(getTypeName(typeBinding)));
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation)
	 */
	public boolean visit(SingleMemberAnnotation node) {
		return false;
	}
	
	/**
	 * @see ASTVisitor#visit(SingleVariableDeclaration)
	 * return <code>false</code>, don't use the standard accept order.
	 */
	public boolean visit(SingleVariableDeclaration node) {
		if (!isActive()) {
			return false;
		}
		ITypeBinding typeBinding= resolveTypeBinding(node.getType());
		if (typeBinding != null) {
			int typeDimension= typeBinding.getDimensions();
			if (typeDimension != 0) {
				typeBinding= typeBinding.getElementType();
			}
			Expression initializer= node.getInitializer();
			push(new LocalVariableCreation(node.getName().getIdentifier(), getTypeSignature(typeBinding), typeDimension, typeBinding.isPrimitive(), initializer != null, fCounter));
			if (initializer != null) {
				initializer.accept(this);
			}
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(StringLiteral)
	 */
	public boolean visit(StringLiteral node) {
		if (!isActive()) {
			return false;
		}

		push(new PushString(node.getLiteralValue()));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(SuperConstructorInvocation)
	 */
	public boolean visit(SuperConstructorInvocation node) {
		if (!isActive()) {
			return false;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_super_constructor_invocation_cannot_be_used_in_an_evaluation_expression_19); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(SuperFieldAccess)
	 */
	public boolean visit(SuperFieldAccess node) {
		if (!isActive()) {
			return false;
		}

		SimpleName fieldName= node.getName();
		IVariableBinding fieldBinding= (IVariableBinding) resolveBinding(fieldName);
		if (fieldBinding == null) {
			return false;
		}
		ITypeBinding declaringTypeBinding= fieldBinding.getDeclaringClass();
		String fieldId = fieldName.getIdentifier();

		if (Modifier.isStatic(fieldBinding.getModifiers())) {
			push(new PushStaticFieldVariable(fieldId, getTypeName(declaringTypeBinding), fCounter));
		} else {
			Name qualifier = node.getQualifier();
			int superLevel= 1;
			int enclosingLevel= 0;
			if (qualifier != null) {
				ITypeBinding typeBinding = resolveTypeBinding(qualifier);
				if (typeBinding == null) {
					return false;
				}
				superLevel= getSuperLevel(typeBinding, declaringTypeBinding);
				ITypeBinding binding = (ITypeBinding)resolveBinding(qualifier);
				if (binding == null) {
					return false;
				}
				enclosingLevel= getEnclosingLevel(node, binding);
			}
			push(new PushFieldVariable(fieldId, superLevel, fCounter));
			push(new PushThis(enclosingLevel));
			storeInstruction();
		}

		return false;
	}

	/**
	 * return false, don't visit name, visit arguments
	 *
	 * @see ASTVisitor#visit(SuperMethodInvocation)
	 */
	public boolean visit(SuperMethodInvocation node) {
		if (!isActive()) {
			return false;
		}

		IMethodBinding methodBinding = (IMethodBinding) resolveBinding(node.getName());
		if (methodBinding == null) {
			return false;
		}

		if (containsALocalType(methodBinding)) {
			setHasError(true);
			addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Method_which_contains_a_local_type_as_parameter_cannot_be_used_in_an_evaluation_expression_32);
			return false;
		}

		ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
		int paramCount = parameterTypes.length;
		String selector = methodBinding.getName();
		String signature = getMethodSignature(methodBinding, null);

		Name qualifier= node.getQualifier();
		if (Modifier.isStatic(methodBinding.getModifiers())) {
			push(new SendStaticMessage(getTypeName(methodBinding.getDeclaringClass()), selector, signature, paramCount, fCounter));
		} else {
			push(new SendMessage(selector, signature, paramCount, getTypeSignature(methodBinding.getDeclaringClass()), fCounter));
			int enclosingLevel= 0;
			if (qualifier != null) {
				ITypeBinding typeBinding = (ITypeBinding)resolveBinding(qualifier);
				if (typeBinding == null) {
					return false;
				}
				enclosingLevel= getEnclosingLevel(node, typeBinding);
			}
			push(new PushThis(enclosingLevel));
			storeInstruction();
		}

		List arguments = node.arguments();
		int argCount = arguments.size();
		ITypeBinding lastArgBinding = null;
		if (methodBinding.isVarargs()) {
			lastArgBinding = resolveTypeBinding((Expression)arguments.get(argCount - 1));
			if (lastArgBinding == null) {
				return false;
			}
		}
		if (methodBinding.isVarargs() && !(paramCount == argCount && parameterTypes[paramCount - 1].getDimensions() == lastArgBinding.getDimensions())) {
			// if this method is a varargs, and if the method is invoked using the varargs syntax
			// (multiple arguments) and not an array
			Iterator iterator= arguments.iterator();
			// process the first arguments (no part of the variable argument)
			for (int i= 0; i < paramCount - 1; i++) {
				Expression argument= (Expression) iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i]);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
			// create a array of the remainder arguments
			ITypeBinding varargsParameterType= parameterTypes[paramCount - 1];
			ITypeBinding varargsElementType= varargsParameterType.getElementType();
			push(new ArrayInitializerInstruction(getTypeSignature(varargsElementType), argCount - paramCount + 1, varargsParameterType.getDimensions(), fCounter));
			while (iterator.hasNext()) {
				Expression argument= (Expression) iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), varargsElementType);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
			storeInstruction();
		} else {
			Iterator iterator= arguments.iterator();
			int i= 0;
			while (iterator.hasNext()) {
				Expression argument= (Expression) iterator.next();
				boolean storeRequired= checkAutoBoxing(argument.resolveTypeBinding(), parameterTypes[i++]);
				argument.accept(this);
				if (storeRequired) {
					storeInstruction();
				}
			}
		} 

		return false;
	}

	/**
	 * @see ASTVisitor#visit(SwitchCase)
	 */
	public boolean visit(SwitchCase node) {
		// never called
		return false;
	}

	/**
	 * @see ASTVisitor#visit(SwitchStatement)
	 */
	public boolean visit(SwitchStatement node) {
		if (!isActive()) {
			return false;
		}
		push(new NoOp(fCounter));
		int switchStart= fCounter;
		node.getExpression().accept(this);
		
		ArrayList statementsDefault= null;
		Jump jumpDefault= null;
		ArrayList jumpsStatements= new ArrayList();
		ArrayList[] currentJumpsStatements= new ArrayList[] {new ArrayList(), null};
		jumpsStatements.add(currentJumpsStatements);
		
		for (Iterator iter= node.statements().iterator(); iter.hasNext();) {
			Statement statement= (Statement) iter.next();
			if (statement instanceof SwitchCase) {
				SwitchCase switchCase= (SwitchCase) statement;
				if (switchCase.isDefault()) {
					jumpDefault= new Jump();
					push(jumpDefault);
					storeInstruction(); // jump
					statementsDefault= new ArrayList();
				} else {
					if(switchCase.getExpression() instanceof StringLiteral) {
						push(new SendMessage("equals", "(Ljava/lang/Object;)Z", 1, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					else {
						push(new EqualEqualOperator(Instruction.T_int, Instruction.T_int, true, fCounter));
					}
					push(new Dup());
					storeInstruction(); // dupe
					switchCase.getExpression().accept(this);
					storeInstruction(); // equal-equal
					ConditionalJump condJump= new ConditionalJump(true);
					push(condJump);
					storeInstruction(); // conditional jump
					if (currentJumpsStatements[1] != null) {
						currentJumpsStatements= new ArrayList[] {new ArrayList(), null};
						jumpsStatements.add(currentJumpsStatements);
					}
					currentJumpsStatements[0].add(condJump);
				}
			} else {
				if (statementsDefault != null) {
					statementsDefault.add(statement);
				} else {
					if (currentJumpsStatements[1] == null) {
						currentJumpsStatements[1]= new ArrayList();
					}
					currentJumpsStatements[1].add(statement);
				}
			}
		}
		
		Jump jumpEnd= null;
		if (jumpDefault == null) {
			push(new Pop(0));
			storeInstruction(); // pop
			jumpEnd= new Jump();
			push(jumpEnd);
			storeInstruction(); // jump
		}
		
		for (Iterator iter= jumpsStatements.iterator(); iter.hasNext();) {
			currentJumpsStatements= (ArrayList[]) iter.next();
			for (Iterator iterator= currentJumpsStatements[0].iterator(); iterator.hasNext();) {
				ConditionalJump condJump= (ConditionalJump) iterator.next();
				condJump.setOffset((fCounter - fInstructions.indexOf(condJump)) - 1);
			}
			if (currentJumpsStatements[1] != null) {
				push(new Pop(0));
				storeInstruction(); // pop
				for (Iterator iterator= currentJumpsStatements[1].iterator(); iterator.hasNext();) {
					((Statement) iterator.next()).accept(this);
				}
			}
		}
		
		// default case
		if (jumpDefault != null) {
			jumpDefault.setOffset((fCounter - fInstructions.indexOf(jumpDefault)) - 1);
			push(new Pop(0));
			storeInstruction(); // pop
			for (Iterator iterator= statementsDefault.iterator(); iterator.hasNext();) {
				((Statement) iterator.next()).accept(this);
			}
		} else {
			jumpEnd.setOffset((fCounter - fInstructions.indexOf(jumpEnd)) - 1);
		}
		
		// for each pending break or continue instruction which are related to
		// this loop, set the offset of the corresponding jump.
		String label= getLabel(node);
		for (Iterator iter= fCompleteInstructions.iterator(); iter.hasNext();) {
			CompleteInstruction instruction= (CompleteInstruction) iter.next();
			Jump jumpInstruction= instruction.fInstruction;
			int instructionAddress= fInstructions.indexOf(jumpInstruction);
			if (instructionAddress > switchStart && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
				iter.remove();
				if (instruction.fIsBreak) {
					// jump to the instruction after the last instruction of the switch
					jumpInstruction.setOffset((fCounter - instructionAddress) - 1);
				}
			}
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(SynchronizedStatement)
	 */
	public boolean visit(SynchronizedStatement node) {
		if (!isActive()) {
			return false;
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement)
	 */
	public boolean visit(TagElement node) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement)
	 */
	public boolean visit(TextElement node) {
		return false;
	}

	/**
	 * @see ASTVisitor#visit(ThisExpression)
	 */
	public boolean visit(ThisExpression node) {
		if (!isActive()) {
			return false;
		}

		Name qualifier= node.getQualifier();
		int enclosingLevel= 0;
		if (qualifier != null) {
			ITypeBinding binding = (ITypeBinding)resolveBinding(qualifier);
			if (binding == null) {
				return false;
			}
			enclosingLevel= getEnclosingLevel(node, binding);
		}
		push(new PushThis(enclosingLevel));

		return false;
	}

	/**
	 * @see ASTVisitor#visit(ThrowStatement)
	 */
	public boolean visit(ThrowStatement node) {
		if (!isActive()) {
			return false;
		}
		push(new ThrowInstruction(fCounter));
		return true;
	}

	/**
	 * @see ASTVisitor#visit(TryStatement)
	 */
	public boolean visit(TryStatement node) {
		if (!isActive()) {
			return false;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Try_statement_cannot_be_used_in_an_evaluation_expression_23); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(TypeDeclaration)
	 */
	public boolean visit(TypeDeclaration node) {
		if (!isActive()) {
			return true;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Type_declaration_cannot_be_used_in_an_evaluation_expression_24); 
		return false;
	}

	/**
	 * @see ASTVisitor#visit(TypeDeclarationStatement)
	 */
	public boolean visit(TypeDeclarationStatement node) {
		if (!isActive()) {
			return true;
		}
		setHasError(true);
		addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Type_declaration_statement_cannot_be_used_in_an_evaluation_expression_25); 
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
	 */
	public boolean visit(TypeParameter node) {
		return false;
	}

	/**
	 * @see ASTVisitor#visit(TypeLiteral)
	 */
	public boolean visit(TypeLiteral node) {
		if (!isActive()) {
			return false;
		}

		push(new PushClassLiteralValue(fCounter));

		return true;
	}

	/**
	 * @see ASTVisitor#visit(VariableDeclarationExpression)
	 */
	public boolean visit(VariableDeclarationExpression node) {
		/* if it is in the code to execute, return <code>false</code>,
		 * we don't use the standard accept order.
		 * Otherwise, return true. We want to search the code to execute
		 * in variable declarations (in case of inner classes).
		 */
		if (!isActive()) {
			return true;
		}
		for (Iterator iter= node.fragments().iterator(); iter.hasNext();) {
			((VariableDeclarationFragment) iter.next()).accept(this);
		}
		return false;
	}

	/**
	 * @see ASTVisitor#visit(VariableDeclarationFragment)
	 */
	public boolean visit(VariableDeclarationFragment node) {
		/* if it is in the code to execute, return <code>false</code>,
		 * we don't use the standard accept order.
		 * Otherwise, return true. We want to search the code to execute
		 * in variable declarations (in case of inner classes).
		 */
		if (!isActive()) {
			return true;
		}
		// get the type of the variable
		ITypeBinding varTypeBinding;
		ASTNode parent= node.getParent();
		switch (parent.getNodeType()) {
			case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
				varTypeBinding= resolveTypeBinding(((VariableDeclarationExpression)parent).getType());
				break;
			case ASTNode.VARIABLE_DECLARATION_STATEMENT:
				varTypeBinding= resolveTypeBinding(((VariableDeclarationStatement)parent).getType());
				break;
			default:
				setHasError(true);
				addErrorMessage(EvaluationEngineMessages.ASTInstructionCompiler_Error_in_type_declaration_statement); 
				return false;
		}
		if (varTypeBinding == null) {
			return false;
		}
		int typeDimension= varTypeBinding.getDimensions();
		ITypeBinding elementBinding = varTypeBinding;
		if (typeDimension != 0) {
			elementBinding= elementBinding.getElementType();
		}

		Expression initializer= node.getInitializer();
		push(new LocalVariableCreation(node.getName().getIdentifier(), getTypeSignature(elementBinding), typeDimension, elementBinding.isPrimitive(), initializer != null, fCounter));
		if (initializer != null) {
			initializer.accept(this);
			ITypeBinding expBindnig = initializer.resolveTypeBinding();
			if (expBindnig != null) {
				if (checkAutoBoxing(expBindnig, varTypeBinding)) {
					storeInstruction();
				}
			}
		}

		return false;
	}

	/**
	 * @see ASTVisitor#visit(VariableDeclarationStatement)
	 */
	public boolean visit(VariableDeclarationStatement node) {
		/* if it is in the code to execute, return <code>false</code>,
		 * we don't use the standard accept order.
		 * Otherwise, return true. We want to search the code to execute
		 * in variable declarations (in case of inner classes).
		 */
		if (!isActive()) {
			return true;
		}
		for (Iterator iter= node.fragments().iterator(); iter.hasNext();) {
			((VariableDeclarationFragment) iter.next()).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WildcardType)
	 */
	public boolean visit(WildcardType node) {
		// we shouldn't have to do anything
		return false;
	}

	/**
	 * @see ASTVisitor#visit(WhileStatement)
	 */
	public boolean visit(WhileStatement node) {
		if (!isActive()) {
			return false;
		}

		push(new NoOp(fCounter));
		return true;
	}

	//--------------------------

	private int getTypeId(Expression expression) {
		ITypeBinding typeBinding = expression.resolveTypeBinding();
		if (typeBinding == null) {
			return Instruction.T_undefined;
		}
		String typeName = typeBinding.getQualifiedName();
		if (typeBinding.isPrimitive()) {
			return getPrimitiveTypeId(typeName);
		} else if ("java.lang.String".equals(typeName)){ //$NON-NLS-1$
			return Instruction.T_String;
		} else {
			return Instruction.T_Object;
		}
	}

	private int getUnBoxedTypeId(Expression expression) {
		ITypeBinding typeBinding = expression.resolveTypeBinding();
		if (typeBinding == null) {
			return Instruction.T_undefined;
		}
		String typeName = typeBinding.getQualifiedName();
		if (typeBinding.isPrimitive()) {
			return getPrimitiveTypeId(typeName);
		} else if ("java.lang.String".equals(typeName)){ //$NON-NLS-1$
			return Instruction.T_String;
		} else {
			// un-boxing
			if ("java.lang.Integer".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_int;
			} else if ("java.lang.Character".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_char;
			} else if ("java.lang.Byte".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_byte;
			} else if ("java.lang.Short".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_short;
			} else if ("java.lang.Long".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_long;
			} else if ("java.lang.Float".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_float;
			} else if ("java.lang.Double".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_double;
			} else if ("java.lang.Boolean".equals(typeName)) { //$NON-NLS-1$
				return Instruction.T_boolean;
			}
			return Instruction.T_Object;
		}
	}

	private int getTypeId(Type type) {
		if (type.isPrimitiveType()) {
			return getPrimitiveTypeId(((PrimitiveType)type).getPrimitiveTypeCode().toString());
		} else if (type.isSimpleType()) {
			SimpleType simpleType = (SimpleType) type;
			if ("java.lang.String".equals(simpleType.getName().getFullyQualifiedName())){ //$NON-NLS-1$
				return Instruction.T_String;
			} 
			return Instruction.T_Object;
		} else if (type.isArrayType()) {
			return Instruction.T_Object;
		} else {
			return Instruction.T_undefined;
		}

	}

	/**
	 * Returns the method signature given the binding and the enclosing type signature (if there is one)
	 * @param methodBinding the binding to get the signature for
	 * @param enclosingTypeSignature the enclosing type signature or <code>null</code>
	 * @return the method signature for the given binding and enclosing type signature
	 */
	private String getMethodSignature(IMethodBinding methodBinding, String enclosingTypeSignature) {
		methodBinding= methodBinding.getMethodDeclaration();
		ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
		int offset = 0;
		int argCount;
		String[] parameterSignatures;
		if (enclosingTypeSignature == null) {
			argCount= parameterTypes.length;
			parameterSignatures= new String[argCount];
		} else {
			offset = 1;
			argCount= parameterTypes.length + 1;
			parameterSignatures= new String[argCount];
			parameterSignatures[0]= enclosingTypeSignature;
		}
		for (int i = 0; i < parameterTypes.length; i++) {
			parameterSignatures[i+offset]= getTypeSignature(parameterTypes[i]);
		}
		String signature= Signature.createMethodSignature(parameterSignatures, getTypeSignature(methodBinding.getReturnType()));
		return signature;
	}

	private int getPrimitiveTypeId(String typeName) {
		switch (typeName.charAt(0)) {
			case 'b': // byte or boolean
				switch (typeName.charAt(1)) {
					case 'o': // boolean;
						return Instruction.T_boolean;
					case 'y': // byte
						return Instruction.T_byte;
				}
				break;
			case 'c': // char
				return Instruction.T_char;
			case 'd': // double
				return Instruction.T_double;
			case 'f': // float
				return Instruction.T_float;
			case 'i': // int
				return Instruction.T_int;
			case 'l': // long
				return Instruction.T_long;
			case 'n':
				return Instruction.T_null;
			case 's': // short
				return Instruction.T_short;
			case 'v': // void
				return Instruction.T_void;
		}
		return Instruction.T_undefined;
	}
	
	/**
	 * Resolves and returns the type binding from the given expression reporting an error
	 * if the binding is <code>null</code>.
	 *  
	 * @param expression expression to resolve type binding for
	 * @return type binding or <code>null</code> if not available
	 */
	private ITypeBinding resolveTypeBinding(Expression expression) {
		ITypeBinding typeBinding = expression.resolveTypeBinding();
		if (typeBinding == null) {
			setHasError(true);
			addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_3, new String[]{expression.toString()}));
		}
		return typeBinding;
	}
	
	/**
	 * Resolves and returns the type binding for the give type reporting an error
	 * if the binding is <code>null</code>.
	 * 
	 * @param type type to resolve binding for
	 * @return type binding or <code>null</code> if not available
	 */
	private ITypeBinding resolveTypeBinding(Type type) {
		ITypeBinding typeBinding = type.resolveBinding();
		if (typeBinding == null) {
			setHasError(true);
			addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_3, new String[]{type.toString()}));
		}
		return typeBinding;
	}
	
	/**
	 * Resolves and returns the binding for the given name reporting an error
	 * if the binding is <code>null</code>.
	 * 
	 * @param name name to resolve binding for
	 * @return binding or <code>null</code> if not available
	 */
	private IBinding resolveBinding(Name name) {
		IBinding binding = name.resolveBinding();
		if (binding == null) {
			setHasError(true);
			addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_5, new String[]{name.getFullyQualifiedName()}));
		}
		return binding;
	}	
	
	/**
	 * Resolves and returns the type binding for the given name reporting an error
	 * if the binding is <code>null</code>.
	 * 
	 * @param name name to resolve type binding for
	 * @return type binding or <code>null</code> if not available
	 */
	private ITypeBinding resolveTypeBinding(Name name) {
		ITypeBinding typeBinding = name.resolveTypeBinding();
		if (typeBinding == null) {
			setHasError(true);
			addErrorMessage(MessageFormat.format(EvaluationEngineMessages.ASTInstructionCompiler_3, new String[]{name.getFullyQualifiedName()}));
		}
		return typeBinding;
	}
}
