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

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;

public class BinaryExpression extends OperatorExpression {

	public Expression left, right;
	public Constant optimizedBooleanConstant;

	public BinaryExpression(Expression left, Expression right, int operator) {

		this.left = left;
		this.right = right;
		this.bits |= operator << OperatorSHIFT; // encode operator
		this.sourceStart = left.sourceStart;
		this.sourceEnd = right.sourceEnd;
	}

	public FlowInfo analyseCode(
		BlockScope currentScope,
		FlowContext flowContext,
		FlowInfo flowInfo) {

		return right
			.analyseCode(
				currentScope,
				flowContext,
				left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
			.unconditionalInits();
	}

	public void computeConstant(BlockScope scope, int leftId, int rightId) {

		//compute the constant when valid
		if ((this.left.constant != Constant.NotAConstant)
			&& (this.right.constant != Constant.NotAConstant)) {
			try {
				this.constant =
					Constant.computeConstantOperation(
						this.left.constant,
						leftId,
						(this.bits & OperatorMASK) >> OperatorSHIFT,
						this.right.constant,
						rightId);
			} catch (ArithmeticException e) {
				this.constant = Constant.NotAConstant;
				// 1.2 no longer throws an exception at compile-time
				//scope.problemReporter().compileTimeConstantThrowsArithmeticException(this);
			}
		} else {
			this.constant = Constant.NotAConstant;
			//add some work for the boolean operators & |  
			this.optimizedBooleanConstant(
				leftId,
				(this.bits & OperatorMASK) >> OperatorSHIFT,
				rightId);
		}
	}

	public Constant optimizedBooleanConstant() {

		return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant;
	}

	/**
	 * Code generation for a binary operation
	 */
	public void generateCode(
		BlockScope currentScope,
		CodeStream codeStream,
		boolean valueRequired) {

		int pc = codeStream.position;
		Label falseLabel, endLabel;
		if (constant != Constant.NotAConstant) {
			if (valueRequired)
				codeStream.generateConstant(constant, implicitConversion);
			codeStream.recordPositionsFrom(pc, this.sourceStart);
			return;
		}
		bits |= OnlyValueRequiredMASK;
		switch ((bits & OperatorMASK) >> OperatorSHIFT) {
			case PLUS :
				switch (bits & ReturnTypeIDMASK) {
					case T_JavaLangString :
						codeStream.generateStringConcatenationAppend(currentScope, left, right);
						if (!valueRequired)
							codeStream.pop();
						break;
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.iadd();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.ladd();
						break;
					case T_double :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.dadd();
						break;
					case T_float :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.fadd();
						break;
				}
				break;
			case MINUS :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.isub();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.lsub();
						break;
					case T_double :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.dsub();
						break;
					case T_float :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.fsub();
						break;
				}
				break;
			case MULTIPLY :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.imul();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.lmul();
						break;
					case T_double :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.dmul();
						break;
					case T_float :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.fmul();
						break;
				}
				break;
			case DIVIDE :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, true);
						right.generateCode(currentScope, codeStream, true);
						codeStream.idiv();
						if (!valueRequired)
							codeStream.pop();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, true);
						right.generateCode(currentScope, codeStream, true);
						codeStream.ldiv();
						if (!valueRequired)
							codeStream.pop2();
						break;
					case T_double :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.ddiv();
						break;
					case T_float :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.fdiv();
						break;
				}
				break;
			case REMAINDER :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, true);
						right.generateCode(currentScope, codeStream, true);
						codeStream.irem();
						if (!valueRequired)
							codeStream.pop();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, true);
						right.generateCode(currentScope, codeStream, true);
						codeStream.lrem();
						if (!valueRequired)
							codeStream.pop2();
						break;
					case T_double :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.drem();
						break;
					case T_float :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.frem();
						break;
				}
				break;
			case AND :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						// 0 & x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_int)
							&& (left.constant.intValue() == 0)) {
							right.generateCode(currentScope, codeStream, false);
							if (valueRequired)
								codeStream.iconst_0();
						} else {
							// x & 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_int)
								&& (right.constant.intValue() == 0)) {
								left.generateCode(currentScope, codeStream, false);
								if (valueRequired)
									codeStream.iconst_0();
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.iand();
							}
						}
						break;
					case T_long :
						// 0 & x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_long)
							&& (left.constant.longValue() == 0L)) {
							right.generateCode(currentScope, codeStream, false);
							if (valueRequired)
								codeStream.lconst_0();
						} else {
							// x & 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_long)
								&& (right.constant.longValue() == 0L)) {
								left.generateCode(currentScope, codeStream, false);
								if (valueRequired)
									codeStream.lconst_0();
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.land();
							}
						}
						break;
					case T_boolean : // logical and
						generateOptimizedLogicalAnd(
							currentScope,
							codeStream,
							null,
							(falseLabel = new Label(codeStream)),
							valueRequired);
						/* improving code gen for such a case: boolean b = i < 0 && false;
						 * since the label has never been used, we have the inlined value on the stack. */
						if (falseLabel.hasForwardReferences()) {
							if (valueRequired) {
								codeStream.iconst_1();
								if ((bits & ValueForReturnMASK) != 0) {
									codeStream.ireturn();
									falseLabel.place();
									codeStream.iconst_0();
								} else {
									codeStream.goto_(endLabel = new Label(codeStream));
									codeStream.decrStackSize(1);
									falseLabel.place();
									codeStream.iconst_0();
									endLabel.place();
								}
							} else {
								falseLabel.place();
							}
						}
				}
				break;
			case OR :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						// 0 | x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_int)
							&& (left.constant.intValue() == 0)) {
							right.generateCode(currentScope, codeStream, valueRequired);
						} else {
							// x | 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_int)
								&& (right.constant.intValue() == 0)) {
								left.generateCode(currentScope, codeStream, valueRequired);
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.ior();
							}
						}
						break;
					case T_long :
						// 0 | x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_long)
							&& (left.constant.longValue() == 0L)) {
							right.generateCode(currentScope, codeStream, valueRequired);
						} else {
							// x | 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_long)
								&& (right.constant.longValue() == 0L)) {
								left.generateCode(currentScope, codeStream, valueRequired);
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.lor();
							}
						}
						break;
					case T_boolean : // logical or
						generateOptimizedLogicalOr(
							currentScope,
							codeStream,
							null,
							(falseLabel = new Label(codeStream)),
							valueRequired);
						/* improving code gen for such a case: boolean b = i < 0 || true;
						 * since the label has never been used, we have the inlined value on the stack. */
						if (falseLabel.hasForwardReferences()) {
							if (valueRequired) {
								codeStream.iconst_1();
								if ((bits & ValueForReturnMASK) != 0) {
									codeStream.ireturn();
									falseLabel.place();
									codeStream.iconst_0();
								} else {
									codeStream.goto_(endLabel = new Label(codeStream));
									codeStream.decrStackSize(1);
									falseLabel.place();
									codeStream.iconst_0();
									endLabel.place();
								}
							} else {
								falseLabel.place();
							}
						}
				}
				break;
			case XOR :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						// 0 ^ x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_int)
							&& (left.constant.intValue() == 0)) {
							right.generateCode(currentScope, codeStream, valueRequired);
						} else {
							// x ^ 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_int)
								&& (right.constant.intValue() == 0)) {
								left.generateCode(currentScope, codeStream, valueRequired);
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.ixor();
							}
						}
						break;
					case T_long :
						// 0 ^ x
						if ((left.constant != Constant.NotAConstant)
							&& (left.constant.typeID() == T_long)
							&& (left.constant.longValue() == 0L)) {
							right.generateCode(currentScope, codeStream, valueRequired);
						} else {
							// x ^ 0
							if ((right.constant != Constant.NotAConstant)
								&& (right.constant.typeID() == T_long)
								&& (right.constant.longValue() == 0L)) {
								left.generateCode(currentScope, codeStream, valueRequired);
							} else {
								left.generateCode(currentScope, codeStream, valueRequired);
								right.generateCode(currentScope, codeStream, valueRequired);
								if (valueRequired)
									codeStream.lxor();
							}
						}
						break;
					case T_boolean :
						generateOptimizedLogicalXor(
							currentScope,
							codeStream,
							null,
							(falseLabel = new Label(codeStream)),
							valueRequired);
						/* improving code gen for such a case: boolean b = i < 0 ^ bool;
						 * since the label has never been used, we have the inlined value on the stack. */
						if (falseLabel.hasForwardReferences()) {
							if (valueRequired) {
								codeStream.iconst_1();
								if ((bits & ValueForReturnMASK) != 0) {
									codeStream.ireturn();
									falseLabel.place();
									codeStream.iconst_0();
								} else {
									codeStream.goto_(endLabel = new Label(codeStream));
									codeStream.decrStackSize(1);
									falseLabel.place();
									codeStream.iconst_0();
									endLabel.place();
								}
							} else {
								falseLabel.place();
							}
						}
				}
				break;
			case LEFT_SHIFT :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.ishl();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.lshl();
				}
				break;
			case RIGHT_SHIFT :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.ishr();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.lshr();
				}
				break;
			case UNSIGNED_RIGHT_SHIFT :
				switch (bits & ReturnTypeIDMASK) {
					case T_int :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.iushr();
						break;
					case T_long :
						left.generateCode(currentScope, codeStream, valueRequired);
						right.generateCode(currentScope, codeStream, valueRequired);
						if (valueRequired)
							codeStream.lushr();
				}
				break;
			case GREATER :
				generateOptimizedGreaterThan(
					currentScope,
					codeStream,
					null,
					(falseLabel = new Label(codeStream)),
					valueRequired);
				if (valueRequired) {
					codeStream.iconst_1();
					if ((bits & ValueForReturnMASK) != 0) {
						codeStream.ireturn();
						falseLabel.place();
						codeStream.iconst_0();
					} else {
						codeStream.goto_(endLabel = new Label(codeStream));
						codeStream.decrStackSize(1);
						falseLabel.place();
						codeStream.iconst_0();
						endLabel.place();
					}
				}
				break;
			case GREATER_EQUAL :
				generateOptimizedGreaterThanOrEqual(
					currentScope,
					codeStream,
					null,
					(falseLabel = new Label(codeStream)),
					valueRequired);
				if (valueRequired) {
					codeStream.iconst_1();
					if ((bits & ValueForReturnMASK) != 0) {
						codeStream.ireturn();
						falseLabel.place();
						codeStream.iconst_0();
					} else {
						codeStream.goto_(endLabel = new Label(codeStream));
						codeStream.decrStackSize(1);
						falseLabel.place();
						codeStream.iconst_0();
						endLabel.place();
					}
				}
				break;
			case LESS :
				generateOptimizedLessThan(
					currentScope,
					codeStream,
					null,
					(falseLabel = new Label(codeStream)),
					valueRequired);
				if (valueRequired) {
					codeStream.iconst_1();
					if ((bits & ValueForReturnMASK) != 0) {
						codeStream.ireturn();
						falseLabel.place();
						codeStream.iconst_0();
					} else {
						codeStream.goto_(endLabel = new Label(codeStream));
						codeStream.decrStackSize(1);
						falseLabel.place();
						codeStream.iconst_0();
						endLabel.place();
					}
				}
				break;
			case LESS_EQUAL :
				generateOptimizedLessThanOrEqual(
					currentScope,
					codeStream,
					null,
					(falseLabel = new Label(codeStream)),
					valueRequired);
				if (valueRequired) {
					codeStream.iconst_1();
					if ((bits & ValueForReturnMASK) != 0) {
						codeStream.ireturn();
						falseLabel.place();
						codeStream.iconst_0();
					} else {
						codeStream.goto_(endLabel = new Label(codeStream));
						codeStream.decrStackSize(1);
						falseLabel.place();
						codeStream.iconst_0();
						endLabel.place();
					}
				}
		}
		if (valueRequired) {
			codeStream.generateImplicitConversion(implicitConversion);
		}
		codeStream.recordPositionsFrom(pc, this.sourceStart);
	}

	/**
	 * Boolean operator code generation
	 *	Optimized operations are: <, <=, >, >=, &, |, ^
	 */
	public void generateOptimizedBoolean(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {

		if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
			super.generateOptimizedBoolean(
				currentScope,
				codeStream,
				trueLabel,
				falseLabel,
				valueRequired);
			return;
		}
		switch ((bits & OperatorMASK) >> OperatorSHIFT) {
			case LESS :
				generateOptimizedLessThan(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case LESS_EQUAL :
				generateOptimizedLessThanOrEqual(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case GREATER :
				generateOptimizedGreaterThan(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case GREATER_EQUAL :
				generateOptimizedGreaterThanOrEqual(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case AND :
				generateOptimizedLogicalAnd(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case OR :
				generateOptimizedLogicalOr(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
			case XOR :
				generateOptimizedLogicalXor(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				return;
		}
		super.generateOptimizedBoolean(
			currentScope,
			codeStream,
			trueLabel,
			falseLabel,
			valueRequired);
	}

	/**
	 * Boolean generation for >
	 */
	public void generateOptimizedGreaterThan(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {

		int promotedTypeID = (left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
		// both sides got promoted in the same way
		if (promotedTypeID == T_int) {
			// 0 > x
			if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
				right.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.iflt(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifge(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
			// x > 0
			if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
				left.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifgt(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifle(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
		}
		// default comparison
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			if (falseLabel == null) {
				if (trueLabel != null) {
					// implicit falling through the FALSE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmpgt(trueLabel);
							break;
						case T_float :
							codeStream.fcmpl();
							codeStream.ifgt(trueLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifgt(trueLabel);
							break;
						case T_double :
							codeStream.dcmpl();
							codeStream.ifgt(trueLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				}
			} else {
				if (trueLabel == null) {
					// implicit falling through the TRUE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmple(falseLabel);
							break;
						case T_float :
							codeStream.fcmpl();
							codeStream.ifle(falseLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifle(falseLabel);
							break;
						case T_double :
							codeStream.dcmpl();
							codeStream.ifle(falseLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				} else {
					// no implicit fall through TRUE/FALSE --> should never occur
				}
			}
		}
	}

	/**
	 * Boolean generation for >=
	 */
	public void generateOptimizedGreaterThanOrEqual(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {

		int promotedTypeID = (left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
		// both sides got promoted in the same way
		if (promotedTypeID == T_int) {
			// 0 >= x
			if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
				right.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifle(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifgt(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
			// x >= 0
			if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
				left.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifge(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.iflt(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
		}
		// default comparison
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			if (falseLabel == null) {
				if (trueLabel != null) {
					// implicit falling through the FALSE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmpge(trueLabel);
							break;
						case T_float :
							codeStream.fcmpl();
							codeStream.ifge(trueLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifge(trueLabel);
							break;
						case T_double :
							codeStream.dcmpl();
							codeStream.ifge(trueLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				}
			} else {
				if (trueLabel == null) {
					// implicit falling through the TRUE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmplt(falseLabel);
							break;
						case T_float :
							codeStream.fcmpl();
							codeStream.iflt(falseLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.iflt(falseLabel);
							break;
						case T_double :
							codeStream.dcmpl();
							codeStream.iflt(falseLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				} else {
					// no implicit fall through TRUE/FALSE --> should never occur
				}
			}
		}
	}

	/**
	 * Boolean generation for <
	 */
	public void generateOptimizedLessThan(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {

		int promotedTypeID = (left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
		// both sides got promoted in the same way
		if (promotedTypeID == T_int) {
			// 0 < x
			if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
				right.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifgt(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifle(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				codeStream.updateLastRecordedEndPC(codeStream.position);
				return;
			}
			// x < 0
			if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
				left.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.iflt(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifge(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				codeStream.updateLastRecordedEndPC(codeStream.position);
				return;
			}
		}
		// default comparison
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			if (falseLabel == null) {
				if (trueLabel != null) {
					// implicit falling through the FALSE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmplt(trueLabel);
							break;
						case T_float :
							codeStream.fcmpg();
							codeStream.iflt(trueLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.iflt(trueLabel);
							break;
						case T_double :
							codeStream.dcmpg();
							codeStream.iflt(trueLabel);
					}
					codeStream.updateLastRecordedEndPC(codeStream.position);
					return;
				}
			} else {
				if (trueLabel == null) {
					// implicit falling through the TRUE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmpge(falseLabel);
							break;
						case T_float :
							codeStream.fcmpg();
							codeStream.ifge(falseLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifge(falseLabel);
							break;
						case T_double :
							codeStream.dcmpg();
							codeStream.ifge(falseLabel);
					}
					codeStream.updateLastRecordedEndPC(codeStream.position);
					return;
				} else {
					// no implicit fall through TRUE/FALSE --> should never occur
				}
			}
		}
	}
	
	/**
	 * Boolean generation for <=
	 */
	public void generateOptimizedLessThanOrEqual(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {

		int promotedTypeID = (left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
		// both sides got promoted in the same way
		if (promotedTypeID == T_int) {
			// 0 <= x
			if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
				right.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifge(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.iflt(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
			// x <= 0
			if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
				left.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					if (falseLabel == null) {
						if (trueLabel != null) {
							// implicitly falling through the FALSE case
							codeStream.ifle(trueLabel);
						}
					} else {
						if (trueLabel == null) {
							// implicitly falling through the TRUE case
							codeStream.ifgt(falseLabel);
						} else {
							// no implicit fall through TRUE/FALSE --> should never occur
						}
					}
				}
				// reposition the endPC
				codeStream.updateLastRecordedEndPC(codeStream.position);					
				return;
			}
		}
		// default comparison
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			if (falseLabel == null) {
				if (trueLabel != null) {
					// implicit falling through the FALSE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmple(trueLabel);
							break;
						case T_float :
							codeStream.fcmpg();
							codeStream.ifle(trueLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifle(trueLabel);
							break;
						case T_double :
							codeStream.dcmpg();
							codeStream.ifle(trueLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				}
			} else {
				if (trueLabel == null) {
					// implicit falling through the TRUE case
					switch (promotedTypeID) {
						case T_int :
							codeStream.if_icmpgt(falseLabel);
							break;
						case T_float :
							codeStream.fcmpg();
							codeStream.ifgt(falseLabel);
							break;
						case T_long :
							codeStream.lcmp();
							codeStream.ifgt(falseLabel);
							break;
						case T_double :
							codeStream.dcmpg();
							codeStream.ifgt(falseLabel);
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
					return;
				} else {
					// no implicit fall through TRUE/FALSE --> should never occur
				}
			}
		}
	}
	
	/**
	 * Boolean generation for &
	 */
	public void generateOptimizedLogicalAnd(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {
			
		Constant condConst;
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
			if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// <something equivalent to true> & x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					if ((bits & OnlyValueRequiredMASK) != 0) {
						right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						right.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
				} else {
					// <something equivalent to false> & x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					Label internalTrueLabel = new Label(codeStream);
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					internalTrueLabel.place();
					if (valueRequired) {
						if ((bits & OnlyValueRequiredMASK) != 0) {
							codeStream.iconst_0();
						} else {
							if (falseLabel != null) {
								// implicit falling through the TRUE case
								codeStream.goto_(falseLabel);
							}
						}
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
				}
				return;
			}
			if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// x & <something equivalent to true>
					if ((bits & OnlyValueRequiredMASK) != 0) {
						left.generateCode(currentScope, codeStream, valueRequired);
					} else {
						left.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
				} else {
					// x & <something equivalent to false>
					Label internalTrueLabel = new Label(codeStream);
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						internalTrueLabel,
						falseLabel,
						false);
					internalTrueLabel.place();
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					if (valueRequired) {
						if ((bits & OnlyValueRequiredMASK) != 0) {
							codeStream.iconst_0();
						} else {
							if (falseLabel != null) {
								// implicit falling through the TRUE case
								codeStream.goto_(falseLabel);
							}
						}
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
				}
				return;
			}
		}
		// default case
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			codeStream.iand();
			if ((bits & OnlyValueRequiredMASK) == 0) {
				if (falseLabel == null) {
					if (trueLabel != null) {
						// implicit falling through the FALSE case
						codeStream.ifne(trueLabel);
					}
				} else {
					// implicit falling through the TRUE case
					if (trueLabel == null) {
						codeStream.ifeq(falseLabel);
					} else {
						// no implicit fall through TRUE/FALSE --> should never occur
					}
				}
			}
		}
		// reposition the endPC
		codeStream.updateLastRecordedEndPC(codeStream.position);					
	}
	
	/**
	 * Boolean generation for |
	 */
	public void generateOptimizedLogicalOr(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {
			
		Constant condConst;
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
			if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// <something equivalent to true> | x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					Label internalFalseLabel = new Label(codeStream);
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						internalFalseLabel,
						false);
					internalFalseLabel.place();
					if (valueRequired) {
						if ((bits & OnlyValueRequiredMASK) != 0) {
							codeStream.iconst_1();
						} else {
							if (trueLabel != null) {
								codeStream.goto_(trueLabel);
							}
						}
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
				} else {
					// <something equivalent to false> | x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					if ((bits & OnlyValueRequiredMASK) != 0) {
						right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						right.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
				}
				return;
			}
			if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// x | <something equivalent to true>
					Label internalFalseLabel = new Label(codeStream);
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						internalFalseLabel,
						false);
					internalFalseLabel.place();
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					if (valueRequired) {
						if ((bits & OnlyValueRequiredMASK) != 0) {
							codeStream.iconst_1();
						} else {
							if (trueLabel != null) {
								codeStream.goto_(trueLabel);
							}
						}
					}
					// reposition the endPC
					codeStream.updateLastRecordedEndPC(codeStream.position);					
				} else {
					// x | <something equivalent to false>
					if ((bits & OnlyValueRequiredMASK) != 0) {
						left.generateCode(currentScope, codeStream, valueRequired);
					} else {
						left.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
				}
				return;
			}
		}
		// default case
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			codeStream.ior();
			if ((bits & OnlyValueRequiredMASK) == 0) {
				if (falseLabel == null) {
					if (trueLabel != null) {
						// implicit falling through the FALSE case
						codeStream.ifne(trueLabel);
					}
				} else {
					// implicit falling through the TRUE case
					if (trueLabel == null) {
						codeStream.ifeq(falseLabel);
					} else {
						// no implicit fall through TRUE/FALSE --> should never occur
					}
				}
			}
		}
		// reposition the endPC
		codeStream.updateLastRecordedEndPC(codeStream.position);					
	}
	
	/**
	 * Boolean generation for ^
	 */
	public void generateOptimizedLogicalXor(
		BlockScope currentScope,
		CodeStream codeStream,
		Label trueLabel,
		Label falseLabel,
		boolean valueRequired) {
			
		Constant condConst;
		if ((left.implicitConversion & COMPILE_TYPE_MASK) == T_boolean) {
			if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// <something equivalent to true> ^ x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						falseLabel,
						trueLabel,
						valueRequired);
				} else {
					// <something equivalent to false> ^ x
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
					if ((bits & OnlyValueRequiredMASK) != 0) {
						right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						right.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
				}
				return;
			}
			if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
				if (condConst.booleanValue() == true) {
					// x ^ <something equivalent to true>
					left.generateOptimizedBoolean(
						currentScope,
						codeStream,
						falseLabel,
						trueLabel,
						valueRequired);
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
				} else {
					// x ^ <something equivalent to false>
					if ((bits & OnlyValueRequiredMASK) != 0) {
						left.generateCode(currentScope, codeStream, valueRequired);
					} else {
						left.generateOptimizedBoolean(
							currentScope,
							codeStream,
							trueLabel,
							falseLabel,
							valueRequired);
					}
					right.generateOptimizedBoolean(
						currentScope,
						codeStream,
						trueLabel,
						falseLabel,
						false);
				}
				return;
			}
		}
		// default case
		left.generateCode(currentScope, codeStream, valueRequired);
		right.generateCode(currentScope, codeStream, valueRequired);
		if (valueRequired) {
			codeStream.ixor();
			if ((bits & OnlyValueRequiredMASK) == 0) {
				if (falseLabel == null) {
					if (trueLabel != null) {
						// implicit falling through the FALSE case
						codeStream.ifne(trueLabel);
					}
				} else {
					// implicit falling through the TRUE case
					if (trueLabel == null) {
						codeStream.ifeq(falseLabel);
					} else {
						// no implicit fall through TRUE/FALSE --> should never occur
					}
				}
			}
		}
		// reposition the endPC
		codeStream.updateLastRecordedEndPC(codeStream.position);					
	}
	
	public void generateOptimizedStringConcatenation(
		BlockScope blockScope,
		CodeStream codeStream,
		int typeID) {
			
		/* In the case trying to make a string concatenation, there is no need to create a new
		 * string buffer, thus use a lower-level API for code generation involving only the
		 * appending of arguments to the existing StringBuffer
		 */

		if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS)
			&& ((bits & ReturnTypeIDMASK) == T_JavaLangString)) {
			if (constant != NotAConstant) {
				codeStream.generateConstant(constant, implicitConversion);
				codeStream.invokeStringConcatenationAppendForType(implicitConversion & COMPILE_TYPE_MASK);
			} else {
				int pc = codeStream.position;
				left.generateOptimizedStringConcatenation(
					blockScope,
					codeStream,
					left.implicitConversion & COMPILE_TYPE_MASK);
				codeStream.recordPositionsFrom(pc, left.sourceStart);
				pc = codeStream.position;
				right.generateOptimizedStringConcatenation(
					blockScope,
					codeStream,
					right.implicitConversion & COMPILE_TYPE_MASK);
				codeStream.recordPositionsFrom(pc, right.sourceStart);
			}
		} else {
			super.generateOptimizedStringConcatenation(blockScope, codeStream, typeID);
		}
	}
	
	public void generateOptimizedStringConcatenationCreation(
		BlockScope blockScope,
		CodeStream codeStream,
		int typeID) {
			
		/* In the case trying to make a string concatenation, there is no need to create a new
		 * string buffer, thus use a lower-level API for code generation involving only the 
		 * appending of arguments to the existing StringBuffer
		 */

		if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS)
			&& ((bits & ReturnTypeIDMASK) == T_JavaLangString)) {
			if (constant != NotAConstant) {
				codeStream.newStringContatenation(); // new: java.lang.StringBuffer
				codeStream.dup();
				codeStream.ldc(constant.stringValue());
				codeStream.invokeStringConcatenationStringConstructor();
				// invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
			} else {
				int pc = codeStream.position;
				left.generateOptimizedStringConcatenationCreation(
					blockScope,
					codeStream,
					left.implicitConversion & COMPILE_TYPE_MASK);
				codeStream.recordPositionsFrom(pc, left.sourceStart);
				pc = codeStream.position;
				right.generateOptimizedStringConcatenation(
					blockScope,
					codeStream,
					right.implicitConversion & COMPILE_TYPE_MASK);
				codeStream.recordPositionsFrom(pc, right.sourceStart);
			}
		} else {
			super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
		}
	}
	
	public boolean isCompactableOperation() {
		
		return true;
	}
	
	public void optimizedBooleanConstant(int leftId, int operator, int rightId) {

		switch (operator) {
			case AND :
				if ((leftId != T_boolean) || (rightId != T_boolean))
					return;
			case AND_AND :
				Constant cst;
				if ((cst = left.optimizedBooleanConstant()) != NotAConstant) {
					if (cst.booleanValue() == false) { // left is equivalent to false
						optimizedBooleanConstant = cst; // constant(false)
						return;
					} else { //left is equivalent to true
						if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
							optimizedBooleanConstant = cst;
							// the conditional result is equivalent to the right conditional value
						}
						return;
					}
				}
				if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
					if (cst.booleanValue() == false) { // right is equivalent to false
						optimizedBooleanConstant = cst; // constant(false)
					}
				}
				return;
			case OR :
				if ((leftId != T_boolean) || (rightId != T_boolean))
					return;
			case OR_OR :
				if ((cst = left.optimizedBooleanConstant()) != NotAConstant) {
					if (cst.booleanValue() == true) { // left is equivalent to true
						optimizedBooleanConstant = cst; // constant(true)
						return;
					} else { //left is equivalent to false
						if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
							optimizedBooleanConstant = cst;
						}
						return;
					}
				}
				if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
					if (cst.booleanValue() == true) { // right is equivalent to true
						optimizedBooleanConstant = cst; // constant(true)
					}
				}
		}
	}

	public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {

		left.printExpression(indent, output).append(' ').append(operatorToString()).append(' ');
		return right.printExpression(0, output);
	}
		
	public TypeBinding resolveType(BlockScope scope) {

		boolean leftIsCast, rightIsCast;
		if ((leftIsCast = left instanceof CastExpression) == true) left.bits |= IgnoreNeedForCastCheckMASK; // will check later on
		TypeBinding leftType = left.resolveType(scope);

		if ((rightIsCast = right instanceof CastExpression) == true) right.bits |= IgnoreNeedForCastCheckMASK; // will check later on
		TypeBinding rightType = right.resolveType(scope);

		// use the id of the type to navigate into the table
		if (leftType == null || rightType == null) {
			constant = Constant.NotAConstant;
			return null;
		}

		int leftTypeID = leftType.id;
		int rightTypeID = rightType.id;

		// autoboxing support
		LookupEnvironment env = scope.environment();
		boolean use15specifics = env.options.sourceLevel >= JDK1_5;
		if (use15specifics) {
			if (!leftType.isBaseType() && rightTypeID != T_JavaLangString && rightTypeID != T_null) {
				leftTypeID = env.computeBoxingType(leftType).id;
			}
			if (!rightType.isBaseType() && leftTypeID != T_JavaLangString && leftTypeID != T_null) {
				rightTypeID = env.computeBoxingType(rightType).id;
			}
		}
		if (leftTypeID > 15
			|| rightTypeID > 15) { // must convert String + Object || Object + String
			if (leftTypeID == T_JavaLangString) {
				rightTypeID = T_JavaLangObject;
			} else if (rightTypeID == T_JavaLangString) {
				leftTypeID = T_JavaLangObject;
			} else {
				constant = Constant.NotAConstant;
				scope.problemReporter().invalidOperator(this, leftType, rightType);
				return null;
			}
		}
		if (((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) {
			if (leftTypeID == T_JavaLangString) {
				this.left.computeConversion(scope, leftType, leftType);
				if (rightType.isArrayType() && ((ArrayBinding) rightType).elementsType() == CharBinding) {
					scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(right);
				}
			}
			if (rightTypeID == T_JavaLangString) {
				this.right.computeConversion(scope, rightType, rightType);
				if (leftType.isArrayType() && ((ArrayBinding) leftType).elementsType() == CharBinding) {
					scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(left);
				}
			}
		}

		// the code is an int
		// (cast)  left   Op (cast)  right --> result
		//  0000   0000       0000   0000      0000
		//  <<16   <<12       <<8    <<4       <<0

		// Don't test for result = 0. If it is zero, some more work is done.
		// On the one hand when it is not zero (correct code) we avoid doing the test	
		int operator = (bits & OperatorMASK) >> OperatorSHIFT;
		int operatorSignature = OperatorSignatures[operator][(leftTypeID << 4) + rightTypeID];

		left.computeConversion(	scope, 	TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), leftType);
		right.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), rightType);
		bits |= operatorSignature & 0xF;
		switch (operatorSignature & 0xF) { // record the current ReturnTypeID
			// only switch on possible result type.....
			case T_boolean :
				this.resolvedType = BooleanBinding;
				break;
			case T_byte :
				this.resolvedType = ByteBinding;
				break;
			case T_char :
				this.resolvedType = CharBinding;
				break;
			case T_double :
				this.resolvedType = DoubleBinding;
				break;
			case T_float :
				this.resolvedType = FloatBinding;
				break;
			case T_int :
				this.resolvedType = IntBinding;
				break;
			case T_long :
				this.resolvedType = LongBinding;
				break;
			case T_JavaLangString :
				this.resolvedType = scope.getJavaLangString();
				break;
			default : //error........
				constant = Constant.NotAConstant;
				scope.problemReporter().invalidOperator(this, leftType, rightType);
				return null;
		}

		// check need for operand cast
		if (leftIsCast || rightIsCast) {
			CastExpression.checkNeedForArgumentCasts(scope, operator, operatorSignature, left, leftTypeID, leftIsCast, right, rightTypeID, rightIsCast);
		}
		// compute the constant when valid
		computeConstant(scope, leftTypeID, rightTypeID);
		return this.resolvedType;
	}

	public void traverse(ASTVisitor visitor, BlockScope scope) {
		
		if (visitor.visit(this, scope)) {
			left.traverse(visitor, scope);
			right.traverse(visitor, scope);
		}
		visitor.endVisit(this, scope);
	}
}
