*** empty log message ***
diff --git a/changes.txt b/changes.txt
index 3f2aaa3..3a886ff 100644
--- a/changes.txt
+++ b/changes.txt
@@ -94,7 +94,7 @@
   1GK7FHB: ITPJCORE:WIN2000 - JCK 1.4 - class from outer and static class from superclass in top-level nested class

   1GK7FCN: ITPJCORE:WIN2000 - JCK 1.4 - class from outer and public static class from superclass in top-level nested class

   1GK7F8L: ITPJCORE:WIN2000 - JCK 1.4 - class from outer and protected static class from superclass in top-level nested class

-  1GK7F4S: ITPJCORE:WIN2000 - JCK 1.4 -static class from outer and class from superclass in nested class

+  1GK7F4S: ITPJCORE:WIN2000 - JCK 1.4 - static class from outer and class from superclass in nested class

   1GK7EZB: ITPJCORE:WIN2000 - JCK 1.4 - static class from outer and public class from superclass in nested class

   1GK7EVB: ITPJCORE:WIN2000 - JCK 1.4 - static class from outer and protected class from superclass in nested class

   1GK7ERE: ITPJCORE:WIN2000 - JCK 1.4 - static class from outer and static class from superclass in nested class

diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
index d58afc7..5b31a4d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -10,265 +10,282 @@
 import org.eclipse.jdt.internal.compiler.flow.*;

 import org.eclipse.jdt.internal.compiler.lookup.*;

 

+//dedicated treatment for the &&

 public class AND_AND_Expression extends BinaryExpression {

-	//dedicated treatment for the &&

+

 	int rightInitStateIndex = -1;

 	int mergedInitStateIndex = -1;

 

-public AND_AND_Expression(Expression left, Expression right,int operator) {

-	super(left,right,operator);

-}

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

+	public AND_AND_Expression(Expression left, Expression right, int operator) {

+		super(left, right, operator);

+	}

 

-	Constant opConstant;

-	if ((opConstant = left.constant) != NotAConstant) {

-		if (opConstant.booleanValue() == true) { 

-			// TRUE && anything

-			FlowInfo mergedInfo = right.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			return mergedInfo;

-		} else { 

-			// FALSE && anything

-			return flowInfo;

-		}

-	}

-	if ((opConstant = right.constant) != NotAConstant) {

-		if (opConstant.booleanValue() == true) { 

-			// anything && TRUE

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			return mergedInfo;

-		} else { 

-			// anything && FALSE

-			// whatever is on the left, we will fail, so the result must merge the left inits when answering

-			// initsWhenFalse. the initsWhenTrue are undetermined, since this path will be fake reachable...

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			return mergedInfo;			

-		}

-	}

-	if ((opConstant = left.conditionalConstant()) != NotAConstant){

-		if (opConstant.booleanValue() == false){ 

-			// something eq. FALSE && anything

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			right.analyseCode(currentScope, flowContext, mergedInfo.copy().markAsFakeReachable(true));

-			return mergedInfo;

-		} 

-	}

-	FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-	FlowInfo rightInfo = leftInfo.initsWhenTrue().copy();

-	rightInitStateIndex = currentScope.methodScope().recordInitializationStates(rightInfo);

-	rightInfo = right.analyseCode(currentScope, flowContext, rightInfo);

-	FlowInfo mergedInfo = FlowInfo.conditional(

-													rightInfo.initsWhenTrue(), 

-													leftInfo.initsWhenFalse().unconditionalInits().mergedWith(rightInfo.initsWhenFalse().copy().unconditionalInits()));

-	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-	return mergedInfo;

-}

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

-	//the TC has been done so leftId and rightId are both equal to T_boolean

+	public FlowInfo analyseCode(

+		BlockScope currentScope,

+		FlowContext flowContext,

+		FlowInfo flowInfo) {

 

-	Constant cst;

-	if ((cst = left.constant) != NotAConstant) {

-		if (cst.booleanValue() == false) { // false && x --> false

-			constant = cst; // inlined to constant(false)

-		} else { // true && x --> x

-			if ((constant = right.constant) == NotAConstant) {

-				// compute conditionalConstant

-				optimizedBooleanConstant(leftId, (bits & OperatorMASK) >> OperatorSHIFT, rightId);

+		Constant opConstant = left.conditionalConstant();

+		if (opConstant != NotAConstant) {

+			if (opConstant.booleanValue() == true) {

+				// TRUE && anything

+				 // need to be careful of scenario:

+				//		(x && y) && !z, if passing the left info to the right, it would be swapped by the !

+				FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); 

+				mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo);

+				mergedInitStateIndex =

+					currentScope.methodScope().recordInitializationStates(mergedInfo);

+				return mergedInfo;

 			}

 		}

-	} else {

-		constant = NotAConstant;

-		// compute conditionalConstant

-		optimizedBooleanConstant(leftId, (bits & OperatorMASK) >> OperatorSHIFT, rightId);

+		FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo);

+		 // need to be careful of scenario:

+		//		(x && y) && !z, if passing the left info to the right, it would be swapped by the !

+		FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalInits().copy();

+		if (opConstant != NotAConstant && opConstant.booleanValue() == false) rightInfo.markAsFakeReachable(true);

+

+		rightInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(rightInfo);

+		rightInfo = right.analyseCode(currentScope, flowContext, rightInfo);

+		FlowInfo mergedInfo =

+			FlowInfo.conditional(

+				rightInfo.initsWhenTrue().copy(),

+				leftInfo.initsWhenFalse().copy().unconditionalInits().mergedWith(

+					rightInfo.initsWhenFalse().copy().unconditionalInits()));

+		mergedInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(mergedInfo);

+		return mergedInfo;

 	}

-}

-/**

- * 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) {

-		// inlined value

-		if (valueRequired)

-			codeStream.generateConstant(constant, implicitConversion);

-		codeStream.recordPositionsFrom(pc, this);

-		return;

-	}

-	bits |= OnlyValueRequiredMASK;

-	generateOptimizedConditionalAnd(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();

-		}

-	}

-	if (valueRequired) {

-		codeStream.generateImplicitConversion(implicitConversion);

-	}

-	codeStream.recordPositionsFrom(pc, this);

-}

-/**

- * 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)) {

+

+	/**

+	 * Code generation for a binary operation

+	 */

+	public void generateCode(

+		BlockScope currentScope,

+		CodeStream codeStream,

+		boolean valueRequired) {

+			

 		int pc = codeStream.position;

-		if (constant.booleanValue() == true) {

-			// constant == true

+		Label falseLabel, endLabel;

+		if (constant != Constant.NotAConstant) {

+			// inlined value

+			if (valueRequired)

+				codeStream.generateConstant(constant, implicitConversion);

+			codeStream.recordPositionsFrom(pc, this);

+			return;

+		}

+		bits |= OnlyValueRequiredMASK;

+		generateOptimizedBoolean(

+			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) {

-				if (falseLabel == null) {

-					// implicit falling through the FALSE case

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

+				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 {

-			if (valueRequired) {

-				if (falseLabel != null) {

-					// implicit falling through the TRUE case

-					if (trueLabel == null) {

-						codeStream.goto_(falseLabel);

-					}

-				}

+			} else {

+				falseLabel.place();

 			}

 		}

+		if (valueRequired) {

+			codeStream.generateImplicitConversion(implicitConversion);

+		}

 		codeStream.recordPositionsFrom(pc, this);

-		return;

 	}

-	generateOptimizedConditionalAnd(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

-}

-/**

- * Boolean generation for &&

- */

-public void generateOptimizedConditionalAnd(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {

 

-	int pc = codeStream.position;

-	Constant condConst;

-	if ((condConst = left.conditionalConstant()) != NotAConstant) {

-		if (condConst.booleanValue() == true) {

-			// <something equivalent to true> && x

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

-			}

-			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);

-			if (valueRequired) {

+	/**

+	 * 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;

+		}

+		int pc = codeStream.position;

+		Constant condConst;

+		if ((condConst = left.conditionalConstant()) != NotAConstant) {

+			if (condConst.booleanValue() == true) {

+				// <something equivalent to true> && x

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

 				if ((bits & OnlyValueRequiredMASK) != 0) {

-					codeStream.iconst_0();

+					right.generateCode(currentScope, codeStream, valueRequired);

 				} else {

-					if (falseLabel != null) {

-						// implicit falling through the TRUE case

-						codeStream.goto_(falseLabel);

+					right.generateOptimizedBoolean(

+						currentScope,

+						codeStream,

+						trueLabel,

+						falseLabel,

+						valueRequired);

+				}

+			} else {

+				// <something equivalent to false> && x

+				left.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);

+						}

 					}

 				}

 			}

+			codeStream.recordPositionsFrom(pc, this);

+			if (mergedInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					mergedInitStateIndex);

+			}

+			return;

 		}

-		codeStream.recordPositionsFrom(pc, this);

-		if (mergedInitStateIndex != -1){

-			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

-		}

-		return;

-	}

-	if ((condConst = right.conditionalConstant()) != 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);

-			}

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-		} else {

-			// x && <something equivalent to false>

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (valueRequired) {

+		if ((condConst = right.conditionalConstant()) != NotAConstant) {

+			if (condConst.booleanValue() == true) {

+				// x && <something equivalent to true>

 				if ((bits & OnlyValueRequiredMASK) != 0) {

-					codeStream.iconst_0();

+					left.generateCode(currentScope, codeStream, valueRequired);

 				} else {

-					if (falseLabel != null) {

-						// implicit falling through the TRUE case

-						codeStream.goto_(falseLabel);

+					left.generateOptimizedBoolean(

+						currentScope,

+						codeStream,

+						trueLabel,

+						falseLabel,

+						valueRequired);

+				}

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+			} else {

+				// x && <something equivalent to false>

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				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);

+						}

 					}

 				}

 			}

+			codeStream.recordPositionsFrom(pc, this);

+			if (mergedInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					mergedInitStateIndex);

+			}

+			return;

+		}

+		// default case

+		if (falseLabel == null) {

+			if (trueLabel != null) {

+				// implicit falling through the FALSE case

+				Label internalFalseLabel = new Label(codeStream);

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					null,

+					internalFalseLabel,

+					true);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					null,

+					valueRequired);

+				internalFalseLabel.place();

+			}

+		} else {

+			// implicit falling through the TRUE case

+			if (trueLabel == null) {

+				left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, true);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					null,

+					falseLabel,

+					valueRequired);

+			} else {

+				// no implicit fall through TRUE/FALSE --> should never occur

+			}

 		}

 		codeStream.recordPositionsFrom(pc, this);

-		if (mergedInitStateIndex != -1){

-			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

-		}

-		return;

-	}

-	// default case

-	if (falseLabel == null) {

-		if (trueLabel != null) {

-			// implicit falling through the FALSE case

-			Label internalFalseLabel = new Label(codeStream);

-			left.generateOptimizedBoolean(currentScope, codeStream, null, internalFalseLabel, true);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired);

-			internalFalseLabel.place();

-		}

-	} else {

-		// implicit falling through the TRUE case

-		if (trueLabel == null) {

-			left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, true);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);

-		} else {

-			// no implicit fall through TRUE/FALSE --> should never occur

+		if (mergedInitStateIndex != -1) {

+			codeStream.removeNotDefinitelyAssignedVariables(

+				currentScope,

+				mergedInitStateIndex);

 		}

 	}

-	codeStream.recordPositionsFrom(pc, this);

-	if (mergedInitStateIndex != -1){

-		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

+

+	public boolean isCompactableOperation() {

+		return false;

 	}

-}

-public boolean isCompactableOperation() {

-	return false;

-}

-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

-	if (visitor.visit(this, scope)) {

-		left.traverse(visitor, scope);

-		right.traverse(visitor, scope);

+

+	public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

+		if (visitor.visit(this, scope)) {

+			left.traverse(visitor, scope);

+			right.traverse(visitor, scope);

+		}

+		visitor.endVisit(this, scope);

 	}

-	visitor.endVisit(this, scope);

-}

-}

+}
\ No newline at end of file
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
index 94d69a8..57aae22 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
@@ -519,28 +519,7 @@
 public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {

 

 	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {

-		int pc = codeStream.position;

-		if (constant.booleanValue() == true) {

-			// constant == true

-			if (valueRequired) {

-				if (falseLabel == null) {

-					// implicit falling through the FALSE case

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

-				}

-			}

-		} else {

-			if (valueRequired) {

-				if (falseLabel != null) {

-					// implicit falling through the TRUE case

-					if (trueLabel == null) {

-						codeStream.goto_(falseLabel);

-					}

-				}

-			}

-		}

-		codeStream.recordPositionsFrom(pc, this);

+		super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

 		return;

 	}

 	switch((bits & OperatorMASK) >> OperatorSHIFT){

@@ -1309,7 +1288,7 @@
 					return;

 				} else { //left is equivalent to false

 					if ((cst = right.conditionalConstant()) != NotAConstant) {

-						optimizedBooleanConstant = Constant.fromValue(!cst.booleanValue()); // the conditional result is equivalent to the opposite of the right conditional value

+						optimizedBooleanConstant = cst;

 					}

 					return;

 				}

diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index 279d0bf..228624d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -11,6 +11,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.*;

 

 public class ConditionalExpression extends OperatorExpression {

+

 	public Expression condition, valueIfTrue, valueIfFalse;

 	private int returnTypeSlotSize = 1;

 

@@ -18,266 +19,378 @@
 	int thenInitStateIndex = -1;

 	int elseInitStateIndex = -1;

 	int mergedInitStateIndex = -1;

-public ConditionalExpression(Expression condition, Expression valueIfTrue, Expression valueIfFalse) {

-	this.condition = condition;

-	this.valueIfTrue = valueIfTrue;

-	this.valueIfFalse = valueIfFalse;

-	sourceStart = condition.sourceStart ;

-	sourceEnd = valueIfFalse.sourceEnd;

-}

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

-	Constant inlinedCondition = condition.constant;

-	if (inlinedCondition == NotAConstant) inlinedCondition = condition.conditionalConstant();

-	if (inlinedCondition != NotAConstant) {

-		if (inlinedCondition.booleanValue() == true) {

-			FlowInfo resultInfo = valueIfTrue.analyseCode(currentScope, flowContext, flowInfo);

-			// analyse valueIfFalse, but do not take into account any of its infos

-			valueIfFalse.analyseCode(currentScope, flowContext, flowInfo.copy().markAsFakeReachable(true));

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(resultInfo);

-			return resultInfo;

-		} else {

-			// analyse valueIfTrue, but do not take into account any of its infos			

-			valueIfTrue.analyseCode(currentScope, flowContext, flowInfo.copy().markAsFakeReachable(true));

-			FlowInfo mergeInfo = valueIfFalse.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergeInfo);

-			return mergeInfo;

-		}

-	}

-	// notice that the receiver investigation is not performed in the previous case, since there is

-	// not a chance it is worth trying to check anything on a constant expression.

-	flowInfo = condition.analyseCode(currentScope, flowContext, flowInfo);

-

-	// store a copy of the merged info, so as to compute the local variable attributes afterwards

-	FlowInfo trueInfo = flowInfo.initsWhenTrue();

-	thenInitStateIndex = currentScope.methodScope().recordInitializationStates(trueInfo);

-	FlowInfo falseInfo = flowInfo.initsWhenFalse();

-	elseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseInfo);

 	

-	// propagate analysis

-	trueInfo = valueIfTrue.analyseCode(currentScope, flowContext, trueInfo.copy());

-	falseInfo = valueIfFalse.analyseCode(currentScope, flowContext, falseInfo.copy());

-	

-	// merge back using a conditional info -  1GK2BLM

-	// if ((t && (v = t)) ? t : t && (v = f)) r = v;  -- ok

-	FlowInfo mergedInfo = FlowInfo.conditional(

-		trueInfo.initsWhenTrue().unconditionalInits().mergedWith(

-			falseInfo.initsWhenTrue().unconditionalInits()),

-		falseInfo.initsWhenFalse().unconditionalInits().mergedWith(

-			falseInfo.initsWhenFalse().unconditionalInits()));

-/*			

-	FlowInfo mergedInfo = valueIfTrue.analyseCode(

-		currentScope,

-		flowContext,

-		flowInfo.initsWhenTrue().copy()).

-			unconditionalInits().

-				mergedWith(

-					valueIfFalse.analyseCode(

-						currentScope,

-						flowContext,

-						flowInfo.initsWhenFalse().copy()).

-							unconditionalInits());

-*/							

-	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-	return mergedInfo;

-}

-/**

- * Code generation for the conditional operator ?:

- *

- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

- * @param valueRequired boolean

-*/

-public void generateCode(

-	BlockScope currentScope, 

-	CodeStream codeStream, 

-	boolean valueRequired) {

-

-	/* Reset the selector of the message pattern to use the optimized selectors,

-	 * when compiling full Java messages, if compiling macroexpanded controls, then

-	 * the selector is supposed correctly positionned.

-	 */

-

-	int pc = codeStream.position, divergePC;

-	Label endifLabel, falseLabel;

-	if (constant != NotAConstant) {

-		if (valueRequired)

-			codeStream.generateConstant(constant, implicitConversion);

-		codeStream.recordPositionsFrom(pc, this);

-		return;

+	public ConditionalExpression(

+		Expression condition,

+		Expression valueIfTrue,

+		Expression valueIfFalse) {

+		this.condition = condition;

+		this.valueIfTrue = valueIfTrue;

+		this.valueIfFalse = valueIfFalse;

+		sourceStart = condition.sourceStart;

+		sourceEnd = valueIfFalse.sourceEnd;

 	}

 

-	Constant cst = condition.constant;

-	Constant condCst = condition.conditionalConstant();

-	boolean needTruePart = 

-		!(((cst != NotAConstant) && (cst.booleanValue() == false))

-			|| ((condCst != NotAConstant) && (condCst.booleanValue() == false))); 

-	boolean needFalsePart = 

-		!(((cst != NotAConstant) && (cst.booleanValue() == true))

-			|| ((condCst != NotAConstant) && (condCst.booleanValue() == true))); 

-

-	endifLabel = new Label(codeStream);

-

-	// Generate code for the condition

-	boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant); 

-	condition.generateOptimizedBoolean(

-		currentScope, 

-		codeStream, 

-		null, 

-		(falseLabel = new Label(codeStream)), 

-		needConditionValue); 

-

-	if (thenInitStateIndex != -1) {

-		codeStream.removeNotDefinitelyAssignedVariables(

-			currentScope, 

-			thenInitStateIndex); 

-		codeStream.addDefinitelyAssignedVariables(currentScope, thenInitStateIndex);

-	}

-

-	// Then code generation

-	if (needTruePart) {

-		valueIfTrue.generateCode(currentScope, codeStream, valueRequired);

-

-		if (needFalsePart) {

-			// Jump over the else part

-			int position = codeStream.position;

-			codeStream.goto_(endifLabel);

-			codeStream.updateLastRecordedEndPC(position);

-			// Tune codestream stack size

-			if (valueRequired) {

-				codeStream.decrStackSize(returnTypeSlotSize);

+	public FlowInfo analyseCode(

+		BlockScope currentScope,

+		FlowContext flowContext,

+		FlowInfo flowInfo) {

+		Constant conditionConstant = condition.conditionalConstant();

+		if (conditionConstant != NotAConstant) {

+			if (conditionConstant.booleanValue() == true) {

+				// TRUE ? left : right

+				FlowInfo resultInfo =

+					valueIfTrue.analyseCode(currentScope, flowContext, flowInfo);

+				// analyse valueIfFalse, but do not take into account any of its infos

+				valueIfFalse.analyseCode(

+					currentScope,

+					flowContext,

+					flowInfo.copy().markAsFakeReachable(true));

+				mergedInitStateIndex =

+					currentScope.methodScope().recordInitializationStates(resultInfo);

+				return resultInfo;

+			} else {

+				// FALSE ? left : right

+				// analyse valueIfTrue, but do not take into account any of its infos			

+				valueIfTrue.analyseCode(

+					currentScope,

+					flowContext,

+					flowInfo.copy().markAsFakeReachable(true));

+				FlowInfo mergeInfo =

+					valueIfFalse.analyseCode(currentScope, flowContext, flowInfo);

+				mergedInitStateIndex =

+					currentScope.methodScope().recordInitializationStates(mergeInfo);

+				return mergeInfo;

 			}

 		}

+		// notice that the receiver investigation is not performed in the previous case, since there is

+		// not a chance it is worth trying to check anything on a constant expression.

+		flowInfo = condition.analyseCode(currentScope, flowContext, flowInfo);

 

+		// store a copy of the merged info, so as to compute the local variable attributes afterwards

+		FlowInfo trueInfo = flowInfo.initsWhenTrue();

+		thenInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(trueInfo);

+		FlowInfo falseInfo = flowInfo.initsWhenFalse();

+		elseInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(falseInfo);

+

+		// propagate analysis

+		trueInfo = valueIfTrue.analyseCode(currentScope, flowContext, trueInfo.copy());

+		falseInfo =

+			valueIfFalse.analyseCode(currentScope, flowContext, falseInfo.copy());

+

+		// merge back using a conditional info -  1GK2BLM

+		// if ((t && (v = t)) ? t : t && (v = f)) r = v;  -- ok

+		FlowInfo mergedInfo =

+			FlowInfo.conditional(

+				trueInfo.initsWhenTrue().copy().unconditionalInits().mergedWith( // must copy, since could be shared with trueInfo.initsWhenFalse()...

+					falseInfo.initsWhenTrue().copy().unconditionalInits()),

+				trueInfo.initsWhenFalse().unconditionalInits().mergedWith(

+					falseInfo.initsWhenFalse().unconditionalInits()));

+		/*			

+			FlowInfo mergedInfo = valueIfTrue.analyseCode(

+				currentScope,

+				flowContext,

+				flowInfo.initsWhenTrue().copy()).

+					unconditionalInits().

+						mergedWith(

+							valueIfFalse.analyseCode(

+								currentScope,

+								flowContext,

+								flowInfo.initsWhenFalse().copy()).

+									unconditionalInits());

+		*/

+		mergedInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(mergedInfo);

+		return mergedInfo;

 	}

-	if (needFalsePart) {

-		falseLabel.place();

-		if (elseInitStateIndex != -1) {

+

+	/**

+	 * Code generation for the conditional operator ?:

+	 *

+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

+	 * @param valueRequired boolean

+	*/

+	public void generateCode(

+		BlockScope currentScope,

+		CodeStream codeStream,

+		boolean valueRequired) {

+

+		int pc = codeStream.position;

+		Label endifLabel, falseLabel;

+		if (constant != NotAConstant) {

+			if (valueRequired)

+				codeStream.generateConstant(constant, implicitConversion);

+			codeStream.recordPositionsFrom(pc, this);

+			return;

+		}

+		Constant cst = condition.constant;

+		Constant condCst = condition.conditionalConstant();

+		boolean needTruePart =

+			!(((cst != NotAConstant) && (cst.booleanValue() == false))

+				|| ((condCst != NotAConstant) && (condCst.booleanValue() == false)));

+		boolean needFalsePart =

+			!(((cst != NotAConstant) && (cst.booleanValue() == true))

+				|| ((condCst != NotAConstant) && (condCst.booleanValue() == true)));

+		endifLabel = new Label(codeStream);

+

+		// Generate code for the condition

+		boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant);

+		condition.generateOptimizedBoolean(

+			currentScope,

+			codeStream,

+			null,

+			(falseLabel = new Label(codeStream)),

+			needConditionValue);

+

+		if (thenInitStateIndex != -1) {

 			codeStream.removeNotDefinitelyAssignedVariables(

-				currentScope, 

-				elseInitStateIndex); 

-			codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex);

+				currentScope,

+				thenInitStateIndex);

+			codeStream.addDefinitelyAssignedVariables(currentScope, thenInitStateIndex);

 		}

-		valueIfFalse.generateCode(currentScope, codeStream, valueRequired);

+		// Then code generation

+		if (needTruePart) {

+			valueIfTrue.generateCode(currentScope, codeStream, valueRequired);

+			if (needFalsePart) {

+				// Jump over the else part

+				int position = codeStream.position;

+				codeStream.goto_(endifLabel);

+				codeStream.updateLastRecordedEndPC(position);

+				// Tune codestream stack size

+				if (valueRequired) {

+					codeStream.decrStackSize(returnTypeSlotSize);

+				}

+			}

+		}

+		if (needFalsePart) {

+			falseLabel.place();

+			if (elseInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					elseInitStateIndex);

+				codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex);

+			}

+			valueIfFalse.generateCode(currentScope, codeStream, valueRequired);

+			// End of if statement

+			endifLabel.place();

+		}

+		// May loose some local variable initializations : affecting the local variable attributes

+		if (mergedInitStateIndex != -1) {

+			codeStream.removeNotDefinitelyAssignedVariables(

+				currentScope,

+				mergedInitStateIndex);

+		}

+		// implicit conversion

+		if (valueRequired)

+			codeStream.generateImplicitConversion(implicitConversion);

+		codeStream.recordPositionsFrom(pc, this);

+	}

 

-		// End of if statement

-		endifLabel.place();

-	}

-	// May loose some local variable initializations : affecting the local variable attributes

-	if (mergedInitStateIndex != -1) {

-		codeStream.removeNotDefinitelyAssignedVariables(

-			currentScope, 

-			mergedInitStateIndex); 

-	}

-	// implicit conversion

-	if (valueRequired)

-		codeStream.generateImplicitConversion(implicitConversion);

-	codeStream.recordPositionsFrom(pc, this);

-}

-public TypeBinding resolveType(BlockScope scope) {

-	// specs p.368

-	constant = NotAConstant;

-	TypeBinding condTb = condition.resolveTypeExpecting(scope, BooleanBinding);

-	TypeBinding trueTb = valueIfTrue.resolveType(scope);

-	TypeBinding falseTb = valueIfFalse.resolveType(scope);

-	if (condTb == null || trueTb == null || falseTb == null)

-		return null;

+	/**

+	 * Optimized boolean code generation for the conditional operator ?:

+	*/

+	public void generateOptimizedBoolean(

+		BlockScope currentScope,

+		CodeStream codeStream,

+		Label trueLabel,

+		Label falseLabel,

+		boolean valueRequired) {

 

-	// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible

-	if (condition.constant != NotAConstant && valueIfTrue.constant != NotAConstant && valueIfFalse.constant != NotAConstant) {

-		// all terms are constant expression so we can propagate the constant

-		// from valueIFTrue or valueIfFalse to teh receiver constant

-		constant = (condition.constant.booleanValue()) ? valueIfTrue.constant : valueIfFalse.constant;

+		if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean) // constant

+			|| (valueIfTrue.implicitConversion >> 4) != T_boolean) { // non boolean values

+			super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

+			return;

+		}

+		int pc = codeStream.position;

+		Constant cst = condition.constant;

+		Constant condCst = condition.conditionalConstant();

+		boolean needTruePart =

+			!(((cst != NotAConstant) && (cst.booleanValue() == false))

+				|| ((condCst != NotAConstant) && (condCst.booleanValue() == false)));

+		boolean needFalsePart =

+			!(((cst != NotAConstant) && (cst.booleanValue() == true))

+				|| ((condCst != NotAConstant) && (condCst.booleanValue() == true)));

+

+		Label internalFalseLabel, endifLabel = new Label(codeStream);

+

+		// Generate code for the condition

+		boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant);

+		condition.generateOptimizedBoolean(

+				currentScope,

+				codeStream,

+				null,

+				internalFalseLabel = new Label(codeStream),

+				needConditionValue);

+

+		if (thenInitStateIndex != -1) {

+			codeStream.removeNotDefinitelyAssignedVariables(

+				currentScope,

+				thenInitStateIndex);

+			codeStream.addDefinitelyAssignedVariables(currentScope, thenInitStateIndex);

+		}

+		// Then code generation

+		if (needTruePart) {

+			valueIfTrue.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

+			

+			if (needFalsePart) {

+				// Jump over the else part

+				int position = codeStream.position;

+				codeStream.goto_(endifLabel);

+				codeStream.updateLastRecordedEndPC(position);

+				// Tune codestream stack size

+				//if (valueRequired) {

+				//	codeStream.decrStackSize(returnTypeSlotSize);

+				//}

+			}

+		}

+		if (needFalsePart) {

+			internalFalseLabel.place();

+			if (elseInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					elseInitStateIndex);

+				codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex);

+			}

+			valueIfFalse.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

+

+			// End of if statement

+			endifLabel.place();

+		}

+		// May loose some local variable initializations : affecting the local variable attributes

+		if (mergedInitStateIndex != -1) {

+			codeStream.removeNotDefinitelyAssignedVariables(

+				currentScope,

+				mergedInitStateIndex);

+		}

+		// no implicit conversion for boolean values

+		codeStream.recordPositionsFrom(pc, this);

 	}

-	if (trueTb == falseTb) { // harmed the implicit conversion 

-		valueIfTrue.implicitWidening(trueTb, trueTb);

-		valueIfFalse.implicitConversion = valueIfTrue.implicitConversion;

-		if (trueTb == LongBinding || trueTb == DoubleBinding) {

+

+	public TypeBinding resolveType(BlockScope scope) {

+		// specs p.368

+		constant = NotAConstant;

+		TypeBinding conditionType = condition.resolveTypeExpecting(scope, BooleanBinding);

+		TypeBinding valueIfTrueType = valueIfTrue.resolveType(scope);

+		TypeBinding valueIfFalseType = valueIfFalse.resolveType(scope);

+		if (conditionType == null || valueIfTrueType == null || valueIfFalseType == null)

+			return null;

+

+		// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible

+		if (condition.constant != NotAConstant

+			&& valueIfTrue.constant != NotAConstant

+			&& valueIfFalse.constant != NotAConstant) {

+			// all terms are constant expression so we can propagate the constant

+			// from valueIFTrue or valueIfFalse to teh receiver constant

+			constant =

+				(condition.constant.booleanValue())

+					? valueIfTrue.constant

+					: valueIfFalse.constant;

+		}

+		if (valueIfTrueType == valueIfFalseType) { // harmed the implicit conversion 

+			valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType);

+			valueIfFalse.implicitConversion = valueIfTrue.implicitConversion;

+			if (valueIfTrueType == LongBinding || valueIfTrueType == DoubleBinding) {

+				returnTypeSlotSize = 2;

+			}

+			return valueIfTrueType;

+		}

+		// Determine the return type depending on argument types

+		// Numeric types

+		if (valueIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) {

+			// (Short x Byte) or (Byte x Short)"

+			if ((valueIfTrueType == ByteBinding && valueIfFalseType == ShortBinding)

+				|| (valueIfTrueType == ShortBinding && valueIfFalseType == ByteBinding)) {

+				valueIfTrue.implicitWidening(ShortBinding, valueIfTrueType);

+				valueIfFalse.implicitWidening(ShortBinding, valueIfFalseType);

+				return ShortBinding;

+			}

+			// <Byte|Short|Char> x constant(Int)  ---> <Byte|Short|Char>   and reciprocally

+			if ((valueIfTrueType == ByteBinding || valueIfTrueType == ShortBinding || valueIfTrueType == CharBinding)

+				&& (valueIfFalseType == IntBinding

+					&& valueIfFalse.isConstantValueOfTypeAssignableToType(valueIfFalseType, valueIfTrueType))) {

+				valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType);

+				valueIfFalse.implicitWidening(valueIfTrueType, valueIfFalseType);

+				return valueIfTrueType;

+			}

+			if ((valueIfFalseType == ByteBinding

+				|| valueIfFalseType == ShortBinding

+				|| valueIfFalseType == CharBinding)

+				&& (valueIfTrueType == IntBinding

+					&& valueIfTrue.isConstantValueOfTypeAssignableToType(valueIfTrueType, valueIfFalseType))) {

+				valueIfTrue.implicitWidening(valueIfFalseType, valueIfTrueType);

+				valueIfFalse.implicitWidening(valueIfFalseType, valueIfFalseType);

+				return valueIfFalseType;

+			}

+			// Manual binary numeric promotion

+			// int

+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_int)

+				&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_int)) {

+				valueIfTrue.implicitWidening(IntBinding, valueIfTrueType);

+				valueIfFalse.implicitWidening(IntBinding, valueIfFalseType);

+				return IntBinding;

+			}

+			// long

+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_long)

+				&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_long)) {

+				valueIfTrue.implicitWidening(LongBinding, valueIfTrueType);

+				valueIfFalse.implicitWidening(LongBinding, valueIfFalseType);

+				returnTypeSlotSize = 2;

+				return LongBinding;

+			}

+			// float

+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_float)

+				&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_float)) {

+				valueIfTrue.implicitWidening(FloatBinding, valueIfTrueType);

+				valueIfFalse.implicitWidening(FloatBinding, valueIfFalseType);

+				return FloatBinding;

+			}

+			// double

+			valueIfTrue.implicitWidening(DoubleBinding, valueIfTrueType);

+			valueIfFalse.implicitWidening(DoubleBinding, valueIfFalseType);

 			returnTypeSlotSize = 2;

+			return DoubleBinding;

 		}

-		return trueTb;

-	}

-

-	// Determine the return type depending on argument types

-	// Numeric types

-	if (trueTb.isNumericType() && falseTb.isNumericType()) {

-		// (Short x Byte) or (Byte x Short)"

-		if ((trueTb == ByteBinding && falseTb == ShortBinding) || (trueTb == ShortBinding && falseTb == ByteBinding)) {

-			valueIfTrue.implicitWidening(ShortBinding, trueTb);

-			valueIfFalse.implicitWidening(ShortBinding, falseTb);

-			return ShortBinding;

+		// Type references (null null is already tested)

+		if ((valueIfTrueType.isBaseType() && valueIfTrueType != NullBinding)

+			|| (valueIfFalseType.isBaseType() && valueIfFalseType != NullBinding)) {

+			scope.problemReporter().conditionalArgumentsIncompatibleTypes(

+				this,

+				valueIfTrueType,

+				valueIfFalseType);

+			return null;

 		}

-

-		// <Byte|Short|Char> x constant(Int)  ---> <Byte|Short|Char>   and reciprocally

-		if ((trueTb == ByteBinding || trueTb == ShortBinding || trueTb == CharBinding) &&

-			(falseTb == IntBinding && valueIfFalse.isConstantValueOfTypeAssignableToType(falseTb, trueTb))) {

-				valueIfTrue.implicitWidening(trueTb, trueTb);

-				valueIfFalse.implicitWidening(trueTb, falseTb);

-				return trueTb;

+		if (scope.areTypesCompatible(valueIfFalseType, valueIfTrueType)) {

+			valueIfTrue.implicitWidening(valueIfTrueType, valueIfTrueType);

+			valueIfFalse.implicitWidening(valueIfTrueType, valueIfFalseType);

+			return valueIfTrueType;

 		}

-		if ((falseTb == ByteBinding || falseTb == ShortBinding || falseTb == CharBinding) &&

-			(trueTb == IntBinding && valueIfTrue.isConstantValueOfTypeAssignableToType(trueTb, falseTb))) {

-				valueIfTrue.implicitWidening(falseTb, trueTb);

-				valueIfFalse.implicitWidening(falseTb, falseTb);

-				return falseTb;

+		if (scope.areTypesCompatible(valueIfTrueType, valueIfFalseType)) {

+			valueIfTrue.implicitWidening(valueIfFalseType, valueIfTrueType);

+			valueIfFalse.implicitWidening(valueIfFalseType, valueIfFalseType);

+			return valueIfFalseType;

 		}

-

-		// Manual binary numeric promotion

-		// int

-		if (BaseTypeBinding.isNarrowing(trueTb.id, T_int) && BaseTypeBinding.isNarrowing(falseTb.id, T_int)) {

-			valueIfTrue.implicitWidening(IntBinding, trueTb);

-			valueIfFalse.implicitWidening(IntBinding, falseTb);

-			return IntBinding;

-		}

-		// long

-		if (BaseTypeBinding.isNarrowing(trueTb.id, T_long) && BaseTypeBinding.isNarrowing(falseTb.id, T_long)) {

-			valueIfTrue.implicitWidening(LongBinding, trueTb);

-			valueIfFalse.implicitWidening(LongBinding, falseTb);

-			returnTypeSlotSize = 2;

-			return LongBinding;

-		}

-		// float

-		if (BaseTypeBinding.isNarrowing(trueTb.id, T_float) && BaseTypeBinding.isNarrowing(falseTb.id, T_float)) {

-			valueIfTrue.implicitWidening(FloatBinding, trueTb);

-			valueIfFalse.implicitWidening(FloatBinding, falseTb);

-			return FloatBinding;

-		}

-		// double

-		valueIfTrue.implicitWidening(DoubleBinding, trueTb);

-		valueIfFalse.implicitWidening(DoubleBinding, falseTb);

-		returnTypeSlotSize = 2;

-		return DoubleBinding;

-	}

-

-	// Type references (null null is already tested)

-	if ((trueTb.isBaseType() && trueTb != NullBinding) || (falseTb.isBaseType() && falseTb != NullBinding)) {

-		scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, trueTb, falseTb);

+		scope.problemReporter().conditionalArgumentsIncompatibleTypes(

+			this,

+			valueIfTrueType,

+			valueIfFalseType);

 		return null;

 	}

-	if (scope.areTypesCompatible(falseTb, trueTb)) {

-		valueIfTrue.implicitWidening(trueTb, trueTb);

-		valueIfFalse.implicitWidening(trueTb, falseTb);

-		return trueTb;

+	

+	public String toStringExpressionNoParenthesis() {

+		return condition.toStringExpression() + " ? " + //$NON-NLS-1$

+		valueIfTrue.toStringExpression() + " : " + //$NON-NLS-1$

+		valueIfFalse.toStringExpression();

 	}

-	if (scope.areTypesCompatible(trueTb, falseTb)) {

-		valueIfTrue.implicitWidening(falseTb, trueTb);

-		valueIfFalse.implicitWidening(falseTb, falseTb);

-		return falseTb;

-	}

-	scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, trueTb, falseTb);

-	return null;

-}

-public String toStringExpressionNoParenthesis(){

-	/* slow code*/

 

-	return	condition.toStringExpression() + " ? " + //$NON-NLS-1$

-			valueIfTrue.toStringExpression() + " : " + //$NON-NLS-1$

-			valueIfFalse.toStringExpression() ; }

-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

-	if (visitor.visit(this, scope)) {

-		condition.traverse(visitor, scope);

-		valueIfTrue.traverse(visitor, scope);

-		valueIfFalse.traverse(visitor, scope);

+	public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

+		if (visitor.visit(this, scope)) {

+			condition.traverse(visitor, scope);

+			valueIfTrue.traverse(visitor, scope);

+			valueIfFalse.traverse(visitor, scope);

+		}

+		visitor.endVisit(this, scope);

 	}

-	visitor.endVisit(this, scope);

-}

-}

+}
\ No newline at end of file
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 027cc07..978ba12 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -247,32 +247,11 @@
  *	Optimized operations are: == and !=

  */

 public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {

-	int pc = codeStream.position;

 	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {

-		if (constant.booleanValue() == true) {

-			// constant == true

-			if (valueRequired) {

-				if (falseLabel == null) {

-					// implicit falling through the FALSE case

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

-				}

-			}

-		} else {

-			// constant == false

-			if (valueRequired) {

-				if (falseLabel != null) {

-					// implicit falling through the TRUE case

-					if (trueLabel == null) {

-						codeStream.goto_(falseLabel);

-					}

-				}

-			}

-		}

-		codeStream.recordPositionsFrom(pc, this);

+		super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

 		return;

 	}

+	int pc = codeStream.position;

 	if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {

 		if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {

 			generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
index d46f5a7..cc1bb77 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -10,263 +10,281 @@
 import org.eclipse.jdt.internal.compiler.flow.*;

 import org.eclipse.jdt.internal.compiler.lookup.*;

 

+//dedicated treatment for the ||

 public class OR_OR_Expression extends BinaryExpression {

-	//dedicated treatment for the &&

+

 	int rightInitStateIndex = -1;

 	int mergedInitStateIndex = -1;

 

-public OR_OR_Expression(Expression left, Expression right,int operator) {

-	super(left,right,operator);

-}

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

+	public OR_OR_Expression(Expression left, Expression right, int operator) {

+		super(left, right, operator);

+	}

 

-	Constant opConstant;

-	if ((opConstant = left.constant) != NotAConstant) {

-		if (opConstant.booleanValue() == false) { 

-			// FALSE || anything

-			return right.analyseCode(currentScope, flowContext, flowInfo);

-		} else { 

-			// TRUE || anything

-			return flowInfo;

-		}

-	}

-	if ((opConstant = right.constant) != NotAConstant) {

-		if (opConstant.booleanValue() == true) { 

-			// anything || TRUE

-			// whatever is on the left, we will succeed, so the result must merge the left inits when answering

-			// initsWhenTrue.

-			// the initsWhenFalse are undetermined, since this path will be fake reachable...

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			return mergedInfo;			

-		} else { 

-			// anything || FALSE

-			// ignore the right part

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			return mergedInfo;			

-		}

-	}

-	if ((opConstant = left.conditionalConstant()) != NotAConstant) {

-		if (opConstant.booleanValue() == true){ 

-			// TRUE || anything

-			FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-			right.analyseCode(currentScope, flowContext, mergedInfo.copy().markAsFakeReachable(true));

-			return mergedInfo;

-		} 

-	}

-	FlowInfo leftInfo, rightInfo;	leftInfo = left.analyseCode(currentScope, flowContext, flowInfo);

-	rightInfo = leftInfo.initsWhenFalse().copy();

-	rightInitStateIndex = currentScope.methodScope().recordInitializationStates(rightInfo);

-	rightInfo = right.analyseCode(currentScope, flowContext, rightInfo);

-	FlowInfo mergedInfo = FlowInfo.conditional(

-		// merging two true initInfos for such a negative case: if ((t && (b = t)) || f) r = b; // b may not have been initialized

-		leftInfo.initsWhenTrue().unconditionalInits().mergedWith(rightInfo.initsWhenTrue().copy().unconditionalInits()), 

-		rightInfo.initsWhenFalse());

-	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);

-	return mergedInfo;

-}

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

-	//the TC has been done so leftId and rightId are both equal to T_boolean

+	public FlowInfo analyseCode(

+		BlockScope currentScope,

+		FlowContext flowContext,

+		FlowInfo flowInfo) {

 

-	Constant cst;

-	if ((cst = left.constant) != NotAConstant) {

-		if (cst.booleanValue() == true) { // true || x --> true

-			constant = cst; // inlined to constant(false)

-		} else { // false || x --> x

-			if ((constant = right.constant) == NotAConstant) {

-				// compute conditionalConstant

-				optimizedBooleanConstant(leftId, (bits & OperatorMASK) >> OperatorSHIFT, rightId);

+		Constant opConstant = left.conditionalConstant();

+		if (opConstant != NotAConstant) {

+			if (opConstant.booleanValue() == false) {

+				// FALSE || anything

+				 // need to be careful of scenario:

+				//		(x || y) || !z, if passing the left info to the right, it would be swapped by the !

+				FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();

+				mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo);

+				mergedInitStateIndex =

+					currentScope.methodScope().recordInitializationStates(mergedInfo);

+				return mergedInfo;

 			}

 		}

-	} else {

-		constant = NotAConstant;

-		// compute conditionalConstant

-		optimizedBooleanConstant(leftId, (bits & OperatorMASK) >> OperatorSHIFT, rightId);

+		FlowInfo leftInfo, rightInfo;

+		leftInfo = left.analyseCode(currentScope, flowContext, flowInfo);

+	

+		 // need to be careful of scenario:

+		//		(x || y) || !z, if passing the left info to the right, it would be swapped by the !

+		rightInfo = leftInfo.initsWhenFalse().unconditionalInits().copy();

+		if (opConstant != NotAConstant && opConstant.booleanValue() == true) rightInfo.markAsFakeReachable(true);

+

+		rightInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(rightInfo);

+		rightInfo = right.analyseCode(currentScope, flowContext, rightInfo);

+		FlowInfo mergedInfo = FlowInfo.conditional(

+					// merging two true initInfos for such a negative case: if ((t && (b = t)) || f) r = b; // b may not have been initialized

+					leftInfo.initsWhenTrue().copy().unconditionalInits().mergedWith(

+						rightInfo.initsWhenTrue().copy().unconditionalInits()),

+					rightInfo.initsWhenFalse().copy());

+		mergedInitStateIndex =

+			currentScope.methodScope().recordInitializationStates(mergedInfo);

+		return mergedInfo;

 	}

-}

-/**

- * Code generation for a binary operation

- *

- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

- * @param valueRequired boolean

- */

-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);

-		return;

-	}

-	bits |= OnlyValueRequiredMASK;

-	generateOptimizedConditionalOr(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();

-		}

-	}

-	if (valueRequired) {

-		codeStream.generateImplicitConversion(implicitConversion);

-	}

-	codeStream.recordPositionsFrom(pc, this);

-}

-/**

- * 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)) {

+

+	/**

+	 * Code generation for a binary operation

+	 *

+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

+	 * @param valueRequired boolean

+	 */

+	public void generateCode(

+		BlockScope currentScope,

+		CodeStream codeStream,

+		boolean valueRequired) {

 		int pc = codeStream.position;

-		if (constant.booleanValue() == true) {

-			// constant == true

-			if (valueRequired) {

-				if (falseLabel == null) {

-					// implicit falling through the FALSE case

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

-				}

-			}

-		} else {

-			if (valueRequired) {

-				if (falseLabel != null) {

-					// implicit falling through the TRUE case

-					if (trueLabel == null) {

-						codeStream.goto_(falseLabel);

-					}

-				}

-			}

+		Label falseLabel, endLabel;

+		if (constant != Constant.NotAConstant) {

+			if (valueRequired)

+				codeStream.generateConstant(constant, implicitConversion);

+			codeStream.recordPositionsFrom(pc, this);

+			return;

 		}

-		codeStream.recordPositionsFrom(pc, this);

-		return;

-	}

-	generateOptimizedConditionalOr(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

-}

-/**

- * Boolean generation for ||

- */

-public void generateOptimizedConditionalOr(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {

-	int pc = codeStream.position;

-	Constant condConst;

-	if ((condConst = left.conditionalConstant()) != NotAConstant) {

-		if (condConst.booleanValue() == true) {

-			// <something equivalent to true> || x

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

+		bits |= OnlyValueRequiredMASK;

+		generateOptimizedBoolean(

+			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) {

-				if ((bits & OnlyValueRequiredMASK) != 0) {

-					codeStream.iconst_1();

+				codeStream.iconst_1();

+				if ((bits & ValueForReturnMASK) != 0) {

+					codeStream.ireturn();

+					falseLabel.place();

+					codeStream.iconst_0();

 				} else {

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

+					codeStream.goto_(endLabel = new Label(codeStream));

+					codeStream.decrStackSize(1);

+					falseLabel.place();

+					codeStream.iconst_0();

+					endLabel.place();

 				}

-			}

-		} else {

-			// <something equivalent to false> || x

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);				

-			}

-			if ((bits & OnlyValueRequiredMASK) != 0){

-				right.generateCode(currentScope, codeStream, valueRequired);

 			} else {

-				right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

+				falseLabel.place();

 			}

 		}

+		if (valueRequired) {

+			codeStream.generateImplicitConversion(implicitConversion);

+		}

 		codeStream.recordPositionsFrom(pc, this);

-		if (mergedInitStateIndex != -1){

-			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

-		}

-		return;

 	}

-	if ((condConst = right.conditionalConstant()) != NotAConstant) {

-		if (condConst.booleanValue() == true) {

-			// x || <something equivalent to true>

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);				

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

-			if (valueRequired) {

+

+	/**

+	 * 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;

+		}

+		int pc = codeStream.position;

+		Constant condConst;

+		if ((condConst = left.conditionalConstant()) != NotAConstant) {

+			if (condConst.booleanValue() == true) {

+				// <something equivalent to true> || x

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (valueRequired) {

+					if ((bits & OnlyValueRequiredMASK) != 0) {

+						codeStream.iconst_1();

+					} else {

+						if (trueLabel != null) {

+							codeStream.goto_(trueLabel);

+						}

+					}

+				}

+			} else {

+				// <something equivalent to false> || x

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

 				if ((bits & OnlyValueRequiredMASK) != 0) {

-					codeStream.iconst_1();

+					right.generateCode(currentScope, codeStream, valueRequired);

 				} else {

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

+					right.generateOptimizedBoolean(

+						currentScope,

+						codeStream,

+						trueLabel,

+						falseLabel,

+						valueRequired);

 				}

 			}

-		} else {

-			// x || <something equivalent to false>

-			if ((bits & OnlyValueRequiredMASK) != 0){

-				left.generateCode(currentScope, codeStream, valueRequired);

+			codeStream.recordPositionsFrom(pc, this);

+			if (mergedInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					mergedInitStateIndex);

+			}

+			return;

+		}

+		if ((condConst = right.conditionalConstant()) != NotAConstant) {

+			if (condConst.booleanValue() == true) {

+				// x || <something equivalent to true>

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

+				if (valueRequired) {

+					if ((bits & OnlyValueRequiredMASK) != 0) {

+						codeStream.iconst_1();

+					} else {

+						if (trueLabel != null) {

+							codeStream.goto_(trueLabel);

+						}

+					}

+				}

 			} else {

-				left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

+				// x || <something equivalent to false>

+				if ((bits & OnlyValueRequiredMASK) != 0) {

+					left.generateCode(currentScope, codeStream, valueRequired);

+				} else {

+					left.generateOptimizedBoolean(

+						currentScope,

+						codeStream,

+						trueLabel,

+						falseLabel,

+						valueRequired);

+				}

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					falseLabel,

+					false);

 			}

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);				

+			codeStream.recordPositionsFrom(pc, this);

+			if (mergedInitStateIndex != -1) {

+				codeStream.removeNotDefinitelyAssignedVariables(

+					currentScope,

+					mergedInitStateIndex);

 			}

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, false);

+			return;

+		}

+		// default case

+		if (falseLabel == null) {

+			if (trueLabel != null) {

+				// implicit falling through the FALSE case

+				left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, true);

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					trueLabel,

+					null,

+					valueRequired);

+			}

+		} else {

+			// implicit falling through the TRUE case

+			if (trueLabel == null) {

+				Label internalTrueLabel = new Label(codeStream);

+				left.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					internalTrueLabel,

+					null,

+					true);

+				if (rightInitStateIndex != -1) {

+					codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);

+				}

+				right.generateOptimizedBoolean(

+					currentScope,

+					codeStream,

+					null,

+					falseLabel,

+					valueRequired);

+				internalTrueLabel.place();

+			} else {

+				// no implicit fall through TRUE/FALSE --> should never occur

+			}

 		}

 		codeStream.recordPositionsFrom(pc, this);

-		if (mergedInitStateIndex != -1){

-			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

-		}

-		return;

-	}

-	// default case

-	if (falseLabel == null) {

-		if (trueLabel != null) {

-			// implicit falling through the FALSE case

-			left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, true);

-			right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired);

-		}

-	} else {

-		// implicit falling through the TRUE case

-		if (trueLabel == null) {

-			Label internalTrueLabel = new Label(codeStream);

-			left.generateOptimizedBoolean(currentScope, codeStream, internalTrueLabel, null, true);

-			if (rightInitStateIndex != -1){

-				codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex);				

-			}

-			right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);

-			internalTrueLabel.place();

-		} else {

-			// no implicit fall through TRUE/FALSE --> should never occur

+		if (mergedInitStateIndex != -1) {

+			codeStream.removeNotDefinitelyAssignedVariables(

+				currentScope,

+				mergedInitStateIndex);

 		}

 	}

-	codeStream.recordPositionsFrom(pc, this);

-	if (mergedInitStateIndex != -1){

-			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);

+

+	public boolean isCompactableOperation() {

+		return false;

 	}

-}

-public boolean isCompactableOperation() {

-	return false;

-}

-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

-	if (visitor.visit(this, scope)) {

-		left.traverse(visitor, scope);

-		right.traverse(visitor, scope);

+

+	public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {

+		if (visitor.visit(this, scope)) {

+			left.traverse(visitor, scope);

+			right.traverse(visitor, scope);

+		}

+		visitor.endVisit(this, scope);

 	}

-	visitor.endVisit(this, scope);

-}

-}

+}
\ No newline at end of file
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
index 3093dd5..6d0f336 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
@@ -10,246 +10,270 @@
 import org.eclipse.jdt.internal.compiler.flow.*;

 import org.eclipse.jdt.internal.compiler.lookup.*;

 

-

 public class UnaryExpression extends OperatorExpression {

+	

 	public Expression expression;

 	public Constant optimizedBooleanConstant;

 

-public UnaryExpression(Expression expression, int operator) {

-	this.expression = expression;

-	this.bits |= operator << OperatorSHIFT; // encode operator

-}

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

-	if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) {

-		return expression.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();

-	} else {

-		return expression.analyseCode(currentScope, flowContext, flowInfo);

-	}

-}

-public Constant conditionalConstant(){

-

-		return 	optimizedBooleanConstant == null ? 

-					constant : 

-					optimizedBooleanConstant ;}

-/**

- * Code generation for an unary operation

- *

- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

- * @param valueRequired boolean

- */ 

-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {

-	int pc = codeStream.position;

-	Label falseLabel, endifLabel;

-	if (constant != Constant.NotAConstant) {

-		// inlined value

-		if (valueRequired){

-			codeStream.generateConstant(constant, implicitConversion);

-		}

-		codeStream.recordPositionsFrom(pc, this);

-		return;

-	}

-	switch ((bits & OperatorMASK) >> OperatorSHIFT) {

-		case NOT :

-			switch (expression.implicitConversion >> 4 )/* runtime type */ {

-				case T_boolean :

-					// ! <boolean>

-					// Generate code for the condition

-					expression.generateOptimizedBoolean(currentScope, codeStream, null, (falseLabel = new Label(codeStream)), valueRequired);

-					if (valueRequired) {

-						codeStream.iconst_0();

-						codeStream.goto_(endifLabel = new Label(codeStream));

-						codeStream.decrStackSize(1);

-						falseLabel.place();

-						if (valueRequired)

-							codeStream.iconst_1();

-						endifLabel.place();

-					}

-					break;

-			}

-			break;

-		case TWIDDLE :

-			switch (expression.implicitConversion  >> 4 /* runtime */) {

-				case T_int :

-					// ~int

-					expression.generateCode(currentScope, codeStream, valueRequired);

-					if (valueRequired) {

-						codeStream.iconst_m1();

-						codeStream.ixor();

-					}

-					break;

-				case T_long :

-					expression.generateCode(currentScope, codeStream, valueRequired);

-					if (valueRequired) {

-						codeStream.ldc2_w(-1L);

-						codeStream.lxor();

-					}

-			}

-			break;

-		case MINUS :

-			// - <num>

-			if (constant != NotAConstant) {

-				if (valueRequired) {

-					switch (expression.implicitConversion >> 4 /* runtime */) {

-						case T_int :

-							codeStream.generateInlinedValue(constant.intValue() * -1);

-							break;

-						case T_float :

-							codeStream.generateInlinedValue(constant.floatValue() * -1.0f);

-							break;

-						case T_long :

-							codeStream.generateInlinedValue(constant.longValue() * -1L);

-							break;

-						case T_double :

-							codeStream.generateInlinedValue(constant.doubleValue() * -1.0);

-					}

-				}

-			} else {

-				expression.generateCode(currentScope, codeStream, valueRequired);

-				if (valueRequired) {

-					switch (expression.implicitConversion >> 4 /* runtime type */) {

-						case T_int :

-							codeStream.ineg();

-							break;

-						case T_float :

-							codeStream.fneg();

-							break;

-						case T_long :

-							codeStream.lneg();

-							break;

-						case T_double :

-							codeStream.dneg();

-					}

-				}

-			}

-			break;

-		case PLUS :

-			expression.generateCode(currentScope, codeStream, valueRequired);

-	}

-	if (valueRequired) {

-		codeStream.generateImplicitConversion(implicitConversion);

-	}

-	codeStream.recordPositionsFrom(pc, this);

-}

-/**

- * 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)) {

-		int pc = codeStream.position;

-		if (constant.booleanValue() == true) {

-			// constant == true

-			if (valueRequired) {

-				if (falseLabel == null) {

-					// implicit falling through the FALSE case

-					if (trueLabel != null) {

-						codeStream.goto_(trueLabel);

-					}

-				}

-			}

-		} else {

-			if (valueRequired) {

-				if (falseLabel != null) {

-					// implicit falling through the TRUE case

-					if (trueLabel == null) {

-						codeStream.goto_(falseLabel);

-					}

-				}

-			}

-		}

-		codeStream.recordPositionsFrom(pc, this);

-		return;

-	}

-	if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) {

-		expression.generateOptimizedBoolean(currentScope, codeStream, falseLabel, trueLabel, valueRequired);

-	} else {

-		super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);

-	}

-}

-public TypeBinding resolveType(BlockScope scope) {

-	TypeBinding expressionTb = expression.resolveType(scope);

-	if (expressionTb == null){

-		constant = NotAConstant;

-		return null;

-	}

-	int expressionId = expressionTb.id;

-	if (expressionId > 15) {

-		constant = NotAConstant;

-		scope.problemReporter().invalidOperator(this, expressionTb);

-		return null;

+	public UnaryExpression(Expression expression, int operator) {

+		this.expression = expression;

+		this.bits |= operator << OperatorSHIFT; // encode operator

 	}

 

-	int tableId;

-	switch ((bits & OperatorMASK) >> OperatorSHIFT) {

-		case NOT :

-			tableId = AND_AND;

-			break;

-		case TWIDDLE :

-			tableId = LEFT_SHIFT;

-			break;

-		default :

-			tableId = MINUS;

-	} //+ and - cases

-

-	// the code is an int

-	// (cast)  left   Op (cast)  rigth --> result

-	//  0000   0000       0000   0000      0000

-	//  <<16   <<12       <<8    <<4       <<0

-	int result = ResolveTypeTables[tableId][(expressionId << 4) + expressionId];

-	expression.implicitConversion = result >>> 12;

-	TypeBinding type;

-	switch (result & 0x0000F) { // only switch on possible result type.....

-		case T_boolean :

-			type = BooleanBinding;

-			break;

-		case T_byte :

-			type = ByteBinding;

-			break;

-		case T_char :

-			type = CharBinding;

-			break;

-		case T_double :

-			type = DoubleBinding;

-			break;

-		case T_float :

-			type = FloatBinding;

-			break;

-		case T_int :

-			type = IntBinding;

-			break;

-		case T_long :

-			type = LongBinding;

-			break;

-		default : //error........

-			constant = Constant.NotAConstant;

-			if (expressionId != T_undefined)

-				scope.problemReporter().invalidOperator(this, expressionTb);

-			return null;

-	}

-

-	// compute the constant when valid

-	if (expression.constant != Constant.NotAConstant) {

-		constant = Constant.computeConstantOperation(expression.constant, expressionId, (bits & OperatorMASK) >> OperatorSHIFT);

-	} else {

-		constant = Constant.NotAConstant;

+	public FlowInfo analyseCode(

+		BlockScope currentScope,

+		FlowContext flowContext,

+		FlowInfo flowInfo) {

 		if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) {

-			Constant cst = expression.conditionalConstant();

-			if (cst.typeID() == T_boolean)

-				optimizedBooleanConstant = Constant.fromValue(!cst.booleanValue());

+			return expression

+				.analyseCode(currentScope, flowContext, flowInfo)

+				.asNegatedCondition();

+		} else {

+			return expression.analyseCode(currentScope, flowContext, flowInfo);

 		}

 	}

-	return type;

-}

-public String toStringExpressionNoParenthesis(){

-	/* slow code*/

 

-	return	operatorToString() + " " + expression.toStringExpression() ; } //$NON-NLS-1$

-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {

-	if (visitor.visit(this, blockScope)) {

-		expression.traverse(visitor, blockScope);

+	public Constant conditionalConstant() {

+		return optimizedBooleanConstant == null ? constant : optimizedBooleanConstant;

 	}

-	visitor.endVisit(this, blockScope);

-}

-}

+

+	/**

+	 * Code generation for an unary operation

+	 *

+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope

+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream

+	 * @param valueRequired boolean

+	 */

+	public void generateCode(

+		BlockScope currentScope,

+		CodeStream codeStream,

+		boolean valueRequired) {

+		int pc = codeStream.position;

+		Label falseLabel, endifLabel;

+		if (constant != Constant.NotAConstant) {

+			// inlined value

+			if (valueRequired) {

+				codeStream.generateConstant(constant, implicitConversion);

+			}

+			codeStream.recordPositionsFrom(pc, this);

+			return;

+		}

+		switch ((bits & OperatorMASK) >> OperatorSHIFT) {

+			case NOT :

+				switch (expression.implicitConversion >> 4) /* runtime type */ {

+					case T_boolean :

+						// ! <boolean>

+						// Generate code for the condition

+						expression.generateOptimizedBoolean(

+							currentScope,

+							codeStream,

+							null,

+							(falseLabel = new Label(codeStream)),

+							valueRequired);

+						if (valueRequired) {

+							codeStream.iconst_0();

+							codeStream.goto_(endifLabel = new Label(codeStream));

+							codeStream.decrStackSize(1);

+							falseLabel.place();

+							if (valueRequired)

+								codeStream.iconst_1();

+							endifLabel.place();

+						}

+						break;

+				}

+				break;

+			case TWIDDLE :

+				switch (expression.implicitConversion >> 4 /* runtime */

+					) {

+					case T_int :

+						// ~int

+						expression.generateCode(currentScope, codeStream, valueRequired);

+						if (valueRequired) {

+							codeStream.iconst_m1();

+							codeStream.ixor();

+						}

+						break;

+					case T_long :

+						expression.generateCode(currentScope, codeStream, valueRequired);

+						if (valueRequired) {

+							codeStream.ldc2_w(-1L);

+							codeStream.lxor();

+						}

+				}

+				break;

+			case MINUS :

+				// - <num>

+				if (constant != NotAConstant) {

+					if (valueRequired) {

+						switch (expression.implicitConversion >> 4 /* runtime */

+							) {

+							case T_int :

+								codeStream.generateInlinedValue(constant.intValue() * -1);

+								break;

+							case T_float :

+								codeStream.generateInlinedValue(constant.floatValue() * -1.0f);

+								break;

+							case T_long :

+								codeStream.generateInlinedValue(constant.longValue() * -1L);

+								break;

+							case T_double :

+								codeStream.generateInlinedValue(constant.doubleValue() * -1.0);

+						}

+					}

+				} else {

+					expression.generateCode(currentScope, codeStream, valueRequired);

+					if (valueRequired) {

+						switch (expression.implicitConversion >> 4 /* runtime type */

+							) {

+							case T_int :

+								codeStream.ineg();

+								break;

+							case T_float :

+								codeStream.fneg();

+								break;

+							case T_long :

+								codeStream.lneg();

+								break;

+							case T_double :

+								codeStream.dneg();

+						}

+					}

+				}

+				break;

+			case PLUS :

+				expression.generateCode(currentScope, codeStream, valueRequired);

+		}

+		if (valueRequired) {

+			codeStream.generateImplicitConversion(implicitConversion);

+		}

+		codeStream.recordPositionsFrom(pc, this);

+	}

+

+	/**

+	 * 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;

+		}

+		if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) {

+			expression.generateOptimizedBoolean(

+				currentScope,

+				codeStream,

+				falseLabel,

+				trueLabel,

+				valueRequired);

+		} else {

+			super.generateOptimizedBoolean(

+				currentScope,

+				codeStream,

+				trueLabel,

+				falseLabel,

+				valueRequired);

+		}

+	}

+

+	public TypeBinding resolveType(BlockScope scope) {

+		TypeBinding expressionTb = expression.resolveType(scope);

+		if (expressionTb == null) {

+			constant = NotAConstant;

+			return null;

+		}

+		int expressionId = expressionTb.id;

+		if (expressionId > 15) {

+			constant = NotAConstant;

+			scope.problemReporter().invalidOperator(this, expressionTb);

+			return null;

+		}

+

+		int tableId;

+		switch ((bits & OperatorMASK) >> OperatorSHIFT) {

+			case NOT :

+				tableId = AND_AND;

+				break;

+			case TWIDDLE :

+				tableId = LEFT_SHIFT;

+				break;

+			default :

+				tableId = MINUS;

+		} //+ and - cases

+

+		// the code is an int

+		// (cast)  left   Op (cast)  rigth --> result

+		//  0000   0000       0000   0000      0000

+		//  <<16   <<12       <<8    <<4       <<0

+		int result = ResolveTypeTables[tableId][(expressionId << 4) + expressionId];

+		expression.implicitConversion = result >>> 12;

+		TypeBinding type;

+		switch (result & 0x0000F) { // only switch on possible result type.....

+			case T_boolean :

+				type = BooleanBinding;

+				break;

+			case T_byte :

+				type = ByteBinding;

+				break;

+			case T_char :

+				type = CharBinding;

+				break;

+			case T_double :

+				type = DoubleBinding;

+				break;

+			case T_float :

+				type = FloatBinding;

+				break;

+			case T_int :

+				type = IntBinding;

+				break;

+			case T_long :

+				type = LongBinding;

+				break;

+			default : //error........

+				constant = Constant.NotAConstant;

+				if (expressionId != T_undefined)

+					scope.problemReporter().invalidOperator(this, expressionTb);

+				return null;

+		}

+		// compute the constant when valid

+		if (expression.constant != Constant.NotAConstant) {

+			constant =

+				Constant.computeConstantOperation(

+					expression.constant,

+					expressionId,

+					(bits & OperatorMASK) >> OperatorSHIFT);

+		} else {

+			constant = Constant.NotAConstant;

+			if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT) {

+				Constant cst = expression.conditionalConstant();

+				if (cst.typeID() == T_boolean)

+					optimizedBooleanConstant = Constant.fromValue(!cst.booleanValue());

+			}

+		}

+		return type;

+	}

+

+	public String toStringExpressionNoParenthesis() {

+		return operatorToString() + " " + expression.toStringExpression(); //$NON-NLS-1$

+	} 

+	

+	public void traverse(

+		IAbstractSyntaxTreeVisitor visitor,

+		BlockScope blockScope) {

+		if (visitor.visit(this, blockScope)) {

+			expression.traverse(visitor, blockScope);

+		}

+		visitor.endVisit(this, blockScope);

+	}

+}
\ No newline at end of file
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 15dd6fe..929fd5e 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -21,6 +21,7 @@
 	return false;

 }

 public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){

+	// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined

 	return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);

 }

 abstract public FlowInfo copy();

diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index be27e6c..447b8b5 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -233,7 +233,7 @@
  */

 final public boolean isPotentiallyAssigned(FieldBinding field) {

 	// We do not want to complain in unreachable code

-	if (this == DeadEnd)

+	if ((this == DeadEnd) || (this.isFakeReachable))

 		return false;

 	return isPotentiallyAssigned(field.id); 

 }

diff --git a/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
index 8f05951..1237369 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
@@ -225,9 +225,9 @@
 	//the result should be availbale with not runtime error

 

 	switch (operator) {

-		case NOT	: 	if ( cst.booleanValue() == true ) return Constant.fromValue(false);

-						return Constant.fromValue(true);

-		case PLUS	:	return cst ; //apriori we do not need to clone it

+		case NOT	: 	

+						return Constant.fromValue(!cst.booleanValue());

+		case PLUS	:	return cst ; 

 		case MINUS	:	//the two special -9223372036854775808L and -2147483648 are inlined at parseTime

 						switch (id){

 							case T_float  :	float f ;