/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contribution for
 *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
 *								bug 383368 - [compiler][null] syntactic null analysis for field references
 *******************************************************************************/
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.classfmt.ClassFileConstants;
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 {

/* Tracking helpers
 * The following are used to elaborate realistic statistics about binary
 * expressions. This must be neutralized in the released code.
 * Search the keyword BE_INSTRUMENTATION to reenable.
 * An external device must install a suitable probe so as to monitor the
 * emission of events and publish the results.
	public interface Probe {
		public void ping(int depth);
	}
	public int depthTracker;
	public static Probe probe;
 */

	public Expression left, right;
	public Constant optimizedBooleanConstant;

public BinaryExpression(Expression left, Expression right, int operator) {
	this.left = left;
	this.right = right;
	this.bits |= operator << ASTNode.OperatorSHIFT; // encode operator
	this.sourceStart = left.sourceStart;
	this.sourceEnd = right.sourceEnd;
	// BE_INSTRUMENTATION: neutralized in the released code
//	if (left instanceof BinaryExpression &&
//			((left.bits & OperatorMASK) ^ (this.bits & OperatorMASK)) == 0) {
//		this.depthTracker = ((BinaryExpression)left).depthTracker + 1;
//	} else {
//		this.depthTracker = 1;
//	}
}
public BinaryExpression(BinaryExpression expression) {
	this.left = expression.left;
	this.right = expression.right;
	this.bits = expression.bits;
	this.sourceStart = expression.sourceStart;
	this.sourceEnd = expression.sourceEnd;
}
@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	// keep implementation in sync with CombinedBinaryExpression#analyseCode
	try {
		if (this.resolvedType.id == TypeIds.T_JavaLangString) {
			return this.right.analyseCode(
								currentScope, flowContext,
								this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
							.unconditionalInits();
		} else {
			flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
			this.left.checkNPE(currentScope, flowContext, flowInfo);
			if (((this.bits & OperatorMASK) >> OperatorSHIFT) != AND) {
				flowContext.expireNullCheckedFieldInfo();
			}
			flowInfo = this.right.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
			this.right.checkNPE(currentScope, flowContext, flowInfo);
			if (((this.bits & OperatorMASK) >> OperatorSHIFT) != AND) {
				flowContext.expireNullCheckedFieldInfo();
			}
			return flowInfo;
		}
	} finally {
		// account for exception possibly thrown by arithmetics
		flowContext.recordAbruptExit();
	}
}

@Override
protected void updateFlowOnBooleanResult(FlowInfo flowInfo, boolean result) {
	int operator = (this.bits & OperatorMASK) >> OperatorSHIFT;
	if (result ? operator == AND_AND : operator == OR_OR) {
		this.left.updateFlowOnBooleanResult(flowInfo, result);
		this.right.updateFlowOnBooleanResult(flowInfo, result);
	}
}

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 & ASTNode.OperatorMASK) >> ASTNode.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 & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT,
			rightId);
	}
}

@Override
public Constant optimizedBooleanConstant() {
	return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant;
}

/**
 * Code generation for a binary operation
 */
// given the current focus of CombinedBinaryExpression on strings concatenation,
// we do not provide a general, non-recursive implementation of generateCode,
// but rely upon generateOptimizedStringConcatenationCreation instead
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	int pc = codeStream.position;
	if (this.constant != Constant.NotAConstant) {
		if (valueRequired)
			codeStream.generateConstant(this.constant, this.implicitConversion);
		codeStream.recordPositionsFrom(pc, this.sourceStart);
		return;
	}
	switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
		case PLUS :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_JavaLangString :
					// BE_INSTRUMENTATION: neutralized in the released code
//					if (probe != null) {
//						probe.ping(this.depthTracker);
//					}
					codeStream.generateStringConcatenationAppend(currentScope, this.left, this.right);
					if (!valueRequired)
						codeStream.pop();
					break;
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.iadd();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.ladd();
					break;
				case T_double :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.dadd();
					break;
				case T_float :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.fadd();
					break;
			}
			break;
		case MINUS :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.isub();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.lsub();
					break;
				case T_double :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.dsub();
					break;
				case T_float :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.fsub();
					break;
			}
			break;
		case MULTIPLY :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.imul();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.lmul();
					break;
				case T_double :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.dmul();
					break;
				case T_float :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.fmul();
					break;
			}
			break;
		case DIVIDE :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, true);
					this.right.generateCode(currentScope, codeStream, true);
					codeStream.idiv();
					if (!valueRequired)
						codeStream.pop();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, true);
					this.right.generateCode(currentScope, codeStream, true);
					codeStream.ldiv();
					if (!valueRequired)
						codeStream.pop2();
					break;
				case T_double :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.ddiv();
					break;
				case T_float :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.fdiv();
					break;
			}
			break;
		case REMAINDER :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, true);
					this.right.generateCode(currentScope, codeStream, true);
					codeStream.irem();
					if (!valueRequired)
						codeStream.pop();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, true);
					this.right.generateCode(currentScope, codeStream, true);
					codeStream.lrem();
					if (!valueRequired)
						codeStream.pop2();
					break;
				case T_double :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.drem();
					break;
				case T_float :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.frem();
					break;
			}
			break;
		case AND :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					// 0 & x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_int)
						&& (this.left.constant.intValue() == 0)) {
						this.right.generateCode(currentScope, codeStream, false);
						if (valueRequired)
							codeStream.iconst_0();
					} else {
						// x & 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_int)
							&& (this.right.constant.intValue() == 0)) {
							this.left.generateCode(currentScope, codeStream, false);
							if (valueRequired)
								codeStream.iconst_0();
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.iand();
						}
					}
					break;
				case T_long :
					// 0 & x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_long)
						&& (this.left.constant.longValue() == 0L)) {
						this.right.generateCode(currentScope, codeStream, false);
						if (valueRequired)
							codeStream.lconst_0();
					} else {
						// x & 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_long)
							&& (this.right.constant.longValue() == 0L)) {
							this.left.generateCode(currentScope, codeStream, false);
							if (valueRequired)
								codeStream.lconst_0();
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.land();
						}
					}
					break;
				case T_boolean : // logical and
					generateLogicalAnd(currentScope, codeStream, valueRequired);
					break;
			}
			break;
		case OR :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					// 0 | x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_int)
						&& (this.left.constant.intValue() == 0)) {
						this.right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						// x | 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_int)
							&& (this.right.constant.intValue() == 0)) {
							this.left.generateCode(currentScope, codeStream, valueRequired);
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.ior();
						}
					}
					break;
				case T_long :
					// 0 | x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_long)
						&& (this.left.constant.longValue() == 0L)) {
						this.right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						// x | 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_long)
							&& (this.right.constant.longValue() == 0L)) {
							this.left.generateCode(currentScope, codeStream, valueRequired);
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.lor();
						}
					}
					break;
				case T_boolean : // logical or
					generateLogicalOr(currentScope, codeStream, valueRequired);
					break;
			}
			break;
		case XOR :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					// 0 ^ x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_int)
						&& (this.left.constant.intValue() == 0)) {
						this.right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						// x ^ 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_int)
							&& (this.right.constant.intValue() == 0)) {
							this.left.generateCode(currentScope, codeStream, valueRequired);
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.ixor();
						}
					}
					break;
				case T_long :
					// 0 ^ x
					if ((this.left.constant != Constant.NotAConstant)
						&& (this.left.constant.typeID() == TypeIds.T_long)
						&& (this.left.constant.longValue() == 0L)) {
						this.right.generateCode(currentScope, codeStream, valueRequired);
					} else {
						// x ^ 0
						if ((this.right.constant != Constant.NotAConstant)
							&& (this.right.constant.typeID() == TypeIds.T_long)
							&& (this.right.constant.longValue() == 0L)) {
							this.left.generateCode(currentScope, codeStream, valueRequired);
						} else {
							this.left.generateCode(currentScope, codeStream, valueRequired);
							this.right.generateCode(currentScope, codeStream, valueRequired);
							if (valueRequired)
								codeStream.lxor();
						}
					}
					break;
				case T_boolean :
					generateLogicalXor(currentScope, 	codeStream, valueRequired);
					break;
			}
			break;
		case LEFT_SHIFT :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.ishl();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.lshl();
			}
			break;
		case RIGHT_SHIFT :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.ishr();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.lshr();
			}
			break;
		case UNSIGNED_RIGHT_SHIFT :
			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
				case T_int :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.iushr();
					break;
				case T_long :
					this.left.generateCode(currentScope, codeStream, valueRequired);
					this.right.generateCode(currentScope, codeStream, valueRequired);
					if (valueRequired)
						codeStream.lushr();
			}
			break;
		case GREATER :
			BranchLabel falseLabel, endLabel;
			generateOptimizedGreaterThan(
				currentScope,
				codeStream,
				null,
				(falseLabel = new BranchLabel(codeStream)),
				valueRequired);
			if (valueRequired) {
				codeStream.iconst_1();
				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
					codeStream.generateImplicitConversion(this.implicitConversion);
					codeStream.generateReturnBytecode(this);
					falseLabel.place();
					codeStream.iconst_0();
				} else {
					codeStream.goto_(endLabel = new BranchLabel(codeStream));
					codeStream.decrStackSize(1);
					falseLabel.place();
					codeStream.iconst_0();
					endLabel.place();
				}
			}
			break;
		case GREATER_EQUAL :
			generateOptimizedGreaterThanOrEqual(
				currentScope,
				codeStream,
				null,
				(falseLabel = new BranchLabel(codeStream)),
				valueRequired);
			if (valueRequired) {
				codeStream.iconst_1();
				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
					codeStream.generateImplicitConversion(this.implicitConversion);
					codeStream.generateReturnBytecode(this);
					falseLabel.place();
					codeStream.iconst_0();
				} else {
					codeStream.goto_(endLabel = new BranchLabel(codeStream));
					codeStream.decrStackSize(1);
					falseLabel.place();
					codeStream.iconst_0();
					endLabel.place();
				}
			}
			break;
		case LESS :
			generateOptimizedLessThan(
				currentScope,
				codeStream,
				null,
				(falseLabel = new BranchLabel(codeStream)),
				valueRequired);
			if (valueRequired) {
				codeStream.iconst_1();
				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
					codeStream.generateImplicitConversion(this.implicitConversion);
					codeStream.generateReturnBytecode(this);
					falseLabel.place();
					codeStream.iconst_0();
				} else {
					codeStream.goto_(endLabel = new BranchLabel(codeStream));
					codeStream.decrStackSize(1);
					falseLabel.place();
					codeStream.iconst_0();
					endLabel.place();
				}
			}
			break;
		case LESS_EQUAL :
			generateOptimizedLessThanOrEqual(
				currentScope,
				codeStream,
				null,
				(falseLabel = new BranchLabel(codeStream)),
				valueRequired);
			if (valueRequired) {
				codeStream.iconst_1();
				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
					codeStream.generateImplicitConversion(this.implicitConversion);
					codeStream.generateReturnBytecode(this);
					falseLabel.place();
					codeStream.iconst_0();
				} else {
					codeStream.goto_(endLabel = new BranchLabel(codeStream));
					codeStream.decrStackSize(1);
					falseLabel.place();
					codeStream.iconst_0();
					endLabel.place();
				}
			}
	}
	if (valueRequired) {
		codeStream.generateImplicitConversion(this.implicitConversion);
	}
	codeStream.recordPositionsFrom(pc, this.sourceStart);
}

/**
 * Boolean operator code generation
 *	Optimized operations are: <, <=, >, >=, &, |, ^
 */
@Override
public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	if ((this.constant != Constant.NotAConstant) && (this.constant.typeID() == TypeIds.T_boolean)) {
		super.generateOptimizedBoolean(
			currentScope,
			codeStream,
			trueLabel,
			falseLabel,
			valueRequired);
		return;
	}
	switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.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, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
	// both sides got promoted in the same way
	if (promotedTypeID == TypeIds.T_int) {
		// 0 > x
		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
		// x > 0
		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
	}
	// default comparison
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				return;
			} else {
				// no implicit fall through TRUE/FALSE --> should never occur
			}
		}
	}
}

/**
 * Boolean generation for >=
 */
public void generateOptimizedGreaterThanOrEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
	// both sides got promoted in the same way
	if (promotedTypeID == TypeIds.T_int) {
		// 0 >= x
		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
		// x >= 0
		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
	}
	// default comparison
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				return;
			} else {
				// no implicit fall through TRUE/FALSE --> should never occur
			}
		}
	}
}

/**
 * Boolean generation for <
 */
public void generateOptimizedLessThan(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
	// both sides got promoted in the same way
	if (promotedTypeID == TypeIds.T_int) {
		// 0 < x
		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
		// x < 0
		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
	}
	// default comparison
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				return;
			} else {
				// no implicit fall through TRUE/FALSE --> should never occur
			}
		}
	}
}

/**
 * Boolean generation for <=
 */
public void generateOptimizedLessThanOrEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
	// both sides got promoted in the same way
	if (promotedTypeID == TypeIds.T_int) {
		// 0 <= x
		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
		// x <= 0
		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
			this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
			return;
		}
	}
	// default comparison
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				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.recordPositionsFrom(codeStream.position, this.sourceEnd);
				return;
			} else {
				// no implicit fall through TRUE/FALSE --> should never occur
			}
		}
	}
}

/**
 * Boolean generation for &
 */
public void generateLogicalAnd(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> & x
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, valueRequired);
			} else {
				// <something equivalent to false> & x
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_0();
				}
				// reposition the endPC
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x & <something equivalent to true>
				this.left.generateCode(currentScope, codeStream, valueRequired);
				this.right.generateCode(currentScope, codeStream, false);
			} else {
				// x & <something equivalent to false>
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_0();
				}
				// reposition the endPC
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.iand();
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

/**
 * Boolean generation for |
 */
public void generateLogicalOr(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> | x
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_1();
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			} else {
				// <something equivalent to false> | x
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, valueRequired);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x | <something equivalent to true>
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_1();
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			} else {
				// x | <something equivalent to false>
				this.left.generateCode(currentScope, codeStream, valueRequired);
				this.right.generateCode(currentScope, codeStream, false);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.ior();
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

/**
 * Boolean generation for ^
 */
public void generateLogicalXor(BlockScope currentScope,	CodeStream codeStream, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> ^ x
				this.left.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_1();
				}
				this.right.generateCode(currentScope, codeStream, valueRequired);
				if (valueRequired) {
					codeStream.ixor(); // negate
					codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
				}
			} else {
				// <something equivalent to false> ^ x
				this.left.generateCode(currentScope, codeStream, false);
				this.right.generateCode(currentScope, codeStream, valueRequired);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x ^ <something equivalent to true>
				this.left.generateCode(currentScope, codeStream, valueRequired);
				this.right.generateCode(currentScope, codeStream, false);
				if (valueRequired) {
					codeStream.iconst_1();
					codeStream.ixor(); // negate
					codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
				}
			} else {
				// x ^ <something equivalent to false>
				this.left.generateCode(currentScope, codeStream, valueRequired);
				this.right.generateCode(currentScope, codeStream, false);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.ixor();
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

/**
 * Boolean generation for &
 */
public void generateOptimizedLogicalAnd(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> & x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
			} else {
				// <something equivalent to false> & x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				if (valueRequired) {
					if (falseLabel != null) {
						// implicit falling through the TRUE case
						codeStream.goto_(falseLabel);
					}
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x & <something equivalent to true>
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
			} else {
				// x & <something equivalent to false>
				BranchLabel internalTrueLabel = new BranchLabel(codeStream);
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					internalTrueLabel,
					falseLabel,
					false);
				internalTrueLabel.place();
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				if (valueRequired) {
					if (falseLabel != null) {
						// implicit falling through the TRUE case
						codeStream.goto_(falseLabel);
					}
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.iand();
		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
			}
		}
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

/**
 * Boolean generation for |
 */
public void generateOptimizedLogicalOr(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> | x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				BranchLabel internalFalseLabel = new BranchLabel(codeStream);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					internalFalseLabel,
					false);
				internalFalseLabel.place();
				if (valueRequired) {
					if (trueLabel != null) {
						codeStream.goto_(trueLabel);
					}
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			} else {
				// <something equivalent to false> | x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x | <something equivalent to true>
				BranchLabel internalFalseLabel = new BranchLabel(codeStream);
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					internalFalseLabel,
					false);
				internalFalseLabel.place();
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				if (valueRequired) {
					if (trueLabel != null) {
						codeStream.goto_(trueLabel);
					}
				}
				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
			} else {
				// x | <something equivalent to false>
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.ior();
		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
			}
		}
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

/**
 * Boolean generation for ^
 */
public void generateOptimizedLogicalXor(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
	Constant condConst;
	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// <something equivalent to true> ^ x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					falseLabel, // negating
					trueLabel,
					valueRequired);
			} else {
				// <something equivalent to false> ^ x
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
			}
			return;
		}
		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
			if (condConst.booleanValue() == true) {
				// x ^ <something equivalent to true>
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					falseLabel, // negating
					trueLabel,
					valueRequired);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
			} else {
				// x ^ <something equivalent to false>
				this.left.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					valueRequired);
				this.right.generateOptimizedBoolean(
					currentScope,
					codeStream,
					trueLabel,
					falseLabel,
					false);
			}
			return;
		}
	}
	// default case
	this.left.generateCode(currentScope, codeStream, valueRequired);
	this.right.generateCode(currentScope, codeStream, valueRequired);
	if (valueRequired) {
		codeStream.ixor();
		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
			}
		}
	}
	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
}

@Override
public void generateOptimizedStringConcatenation(BlockScope blockScope, CodeStream codeStream, int typeID) {
	// keep implementation in sync with CombinedBinaryExpression
	// #generateOptimizedStringConcatenation
	/* 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 ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
		&& ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
		if (this.constant != Constant.NotAConstant) {
			codeStream.generateConstant(this.constant, this.implicitConversion);
			codeStream.invokeStringConcatenationAppendForType(this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
		} else {
			int pc = codeStream.position;
			this.left.generateOptimizedStringConcatenation(
				blockScope,
				codeStream,
				this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
			codeStream.recordPositionsFrom(pc, this.left.sourceStart);
			pc = codeStream.position;
			this.right.generateOptimizedStringConcatenation(
				blockScope,
				codeStream,
				this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
			codeStream.recordPositionsFrom(pc, this.right.sourceStart);
		}
	} else {
		super.generateOptimizedStringConcatenation(blockScope, codeStream, typeID);
	}
}

@Override
public void generateOptimizedStringConcatenationCreation(BlockScope blockScope, CodeStream codeStream, int typeID) {
	// keep implementation in sync with CombinedBinaryExpression
	// #generateOptimizedStringConcatenationCreation
	/* 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 ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
		&& ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
		if (this.constant != Constant.NotAConstant) {
			codeStream.newStringContatenation(); // new: java.lang.StringBuffer
			codeStream.dup();
			codeStream.ldc(this.constant.stringValue());
			codeStream.invokeStringConcatenationStringConstructor();
			// invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
		} else {
			int pc = codeStream.position;
			this.left.generateOptimizedStringConcatenationCreation(
				blockScope,
				codeStream,
				this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
			codeStream.recordPositionsFrom(pc, this.left.sourceStart);
			pc = codeStream.position;
			this.right.generateOptimizedStringConcatenation(
				blockScope,
				codeStream,
				this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
			codeStream.recordPositionsFrom(pc, this.right.sourceStart);
		}
	} else {
		super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
	}
}

@Override
public boolean isCompactableOperation() {
	return true;
}

/**
 * Separates into a reusable method the subpart of {@link
 * #resolveType(BlockScope)} that needs to be executed while climbing up the
 * chain of expressions of this' leftmost branch. For use by {@link
 * CombinedBinaryExpression#resolveType(BlockScope)}.
 * @param scope the scope within which the resolution occurs
 */
void nonRecursiveResolveTypeUpwards(BlockScope scope) {
	// keep implementation in sync with BinaryExpression#resolveType
	boolean leftIsCast, rightIsCast;
	TypeBinding leftType = this.left.resolvedType;

	if ((rightIsCast = this.right instanceof CastExpression) == true) {
		this.right.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
	}
	TypeBinding rightType = this.right.resolveType(scope);

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

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

	// autoboxing support
	boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
	if (use15specifics) {
		if (!leftType.isBaseType() && rightTypeID != TypeIds.T_JavaLangString && rightTypeID != TypeIds.T_null) {
			leftTypeID = scope.environment().computeBoxingType(leftType).id;
		}
		if (!rightType.isBaseType() && leftTypeID != TypeIds.T_JavaLangString && leftTypeID != TypeIds.T_null) {
			rightTypeID = scope.environment().computeBoxingType(rightType).id;
		}
	}
	if (leftTypeID > 15
		|| rightTypeID > 15) { // must convert String + Object || Object + String
		if (leftTypeID == TypeIds.T_JavaLangString) {
			rightTypeID = TypeIds.T_JavaLangObject;
		} else if (rightTypeID == TypeIds.T_JavaLangString) {
			leftTypeID = TypeIds.T_JavaLangObject;
		} else {
			this.constant = Constant.NotAConstant;
			scope.problemReporter().invalidOperator(this, leftType, rightType);
			return;
		}
	}
	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
		if (leftTypeID == TypeIds.T_JavaLangString) {
			this.left.computeConversion(scope, leftType, leftType);
			if (rightType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) rightType).elementsType(), TypeBinding.CHAR)) {
				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
			}
		}
		if (rightTypeID == TypeIds.T_JavaLangString) {
			this.right.computeConversion(scope, rightType, rightType);
			if (leftType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) leftType).elementsType(), TypeBinding.CHAR)) {
				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.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 = (this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
	int operatorSignature = OperatorExpression.OperatorSignatures[operator][(leftTypeID << 4) + rightTypeID];

	this.left.computeConversion(scope, 	TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), leftType);
	this.right.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), rightType);
	this.bits |= operatorSignature & 0xF;
	switch (operatorSignature & 0xF) { // record the current ReturnTypeID
		// only switch on possible result type.....
		case T_boolean :
			this.resolvedType = TypeBinding.BOOLEAN;
			break;
		case T_byte :
			this.resolvedType = TypeBinding.BYTE;
			break;
		case T_char :
			this.resolvedType = TypeBinding.CHAR;
			break;
		case T_double :
			this.resolvedType = TypeBinding.DOUBLE;
			break;
		case T_float :
			this.resolvedType = TypeBinding.FLOAT;
			break;
		case T_int :
			this.resolvedType = TypeBinding.INT;
			break;
		case T_long :
			this.resolvedType = TypeBinding.LONG;
			break;
		case T_JavaLangString :
			this.resolvedType = scope.getJavaLangString();
			break;
		default : //error........
			this.constant = Constant.NotAConstant;
			scope.problemReporter().invalidOperator(this, leftType, rightType);
			return;
	}

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

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

@Override
public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
	// keep implementation in sync with
	// CombinedBinaryExpression#printExpressionNoParenthesis
	this.left.printExpression(indent, output).append(' ').append(operatorToString()).append(' ');
	return this.right.printExpression(0, output);
}

@Override
public void addPatternVariables(BlockScope scope, CodeStream codeStream) {
	this.left.addPatternVariables(scope, codeStream);
	this.right.addPatternVariables(scope, codeStream);
}
@Override
public boolean containsPatternVariable() {
	return this.left.containsPatternVariable() || this.right.containsPatternVariable();
}
@Override
public TypeBinding resolveType(BlockScope scope) {
	// keep implementation in sync with CombinedBinaryExpression#resolveType
	// and nonRecursiveResolveTypeUpwards
	boolean leftIsCast, rightIsCast;
	if ((leftIsCast = this.left instanceof CastExpression) == true) this.left.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
	TypeBinding leftType = this.left.resolveType(scope);

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

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

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

	// autoboxing support
	boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
	if (use15specifics) {
		if (!leftType.isBaseType() && rightTypeID != TypeIds.T_JavaLangString && rightTypeID != TypeIds.T_null) {
			leftTypeID = scope.environment().computeBoxingType(leftType).id;
		}
		if (!rightType.isBaseType() && leftTypeID != TypeIds.T_JavaLangString && leftTypeID != TypeIds.T_null) {
			rightTypeID = scope.environment().computeBoxingType(rightType).id;
		}
	}
	if (leftTypeID > 15
		|| rightTypeID > 15) { // must convert String + Object || Object + String
		if (leftTypeID == TypeIds.T_JavaLangString) {
			rightTypeID = TypeIds.T_JavaLangObject;
		} else if (rightTypeID == TypeIds.T_JavaLangString) {
			leftTypeID = TypeIds.T_JavaLangObject;
		} else {
			this.constant = Constant.NotAConstant;
			scope.problemReporter().invalidOperator(this, leftType, rightType);
			return null;
		}
	}
	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
		if (leftTypeID == TypeIds.T_JavaLangString) {
			this.left.computeConversion(scope, leftType, leftType);
			if (rightType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) rightType).elementsType(), TypeBinding.CHAR)) {
				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
			}
		}
		if (rightTypeID == TypeIds.T_JavaLangString) {
			this.right.computeConversion(scope, rightType, rightType);
			if (leftType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) leftType).elementsType(), TypeBinding.CHAR)) {
				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.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 = (this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
	int operatorSignature = OperatorExpression.OperatorSignatures[operator][(leftTypeID << 4) + rightTypeID];

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

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

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