update to v_B42
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 9eee7ac..2f84dd9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -3404,7 +3404,7 @@
 			break;
 		case 'e' :
 			if (token.equals("enumSwitch") //$NON-NLS-1$
-					|| token.equals("incomplete-switch")) { //$NON-NLS-1$
+					|| token.equals("incomplete-switch") /*backward compatible*/) { //$NON-NLS-1$
 				setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
 				return;
 			} else if (token.equals("emptyBlock")) {//$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 81297f5..708afb8 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,7 +1,7 @@
 #Format: compiler.name = word1 word2 word3
 compiler.name = Eclipse Compiler for Java(TM)
 #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.B39, 3.7.0 M6
+compiler.version = 0.B42, 3.7.0 M6
 compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
 
 ###{ObjectTeams:
@@ -303,7 +303,6 @@
 \                           maskedCatchBlock\n\
 \      includeAssertNull    raise null warnings for variables\n\
 \                           that got tainted in an assert expression\n\
-\      incomplete-switch    same as enumSwitch\n\
 \      indirectStatic       indirect reference to static member\n\
 \      inferredcallout    + a callout binding has to be inferred (OTJLD 3.1(j))\n\
 \      intfAnnotation     + annotation type used as super interface\n\
@@ -338,6 +337,8 @@
 \      syntheticAccess      synthetic access for innerclass\n\
 \      tasks(<tags separated by |>) tasks identified by tags inside comments\n\
 \      typeHiding         + type parameter hiding another type\n\
+\      unavoidableGenericProblems + ignore unavoidable type safety problems\n\
+\                                   due to raw APIs\n\
 \      unchecked          + unchecked type operation\n\
 \      unnecessaryElse      unnecessary else clause\n\
 \      unqualifiedField     unqualified reference to field\n\
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index cf7c3ea..d0595dd 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -41,11 +41,62 @@
 	</td>
   </tr>
 </table>
+<a name="v_B42"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 9, 2011 - 3.7.0 M6
+<br>Project org.eclipse.jdt.core v_B42
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B42">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250">339250</a>
+[null] Incorrect redundant null check warning on a String
+
+<a name="v_B41"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 8, 2011
+<br>Project org.eclipse.jdt.core v_B41
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B41">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339139">339139</a>
+[compiler] HEAD contents of org.eclipse.wst.jsdt.core doesn't compile anymore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649">338649</a>
+[perfs] Regression on FullSourceWorkspaceModelTests#testInitJDTPlugin
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339128">339128</a>
+[Doc] Sort statements and expressions inside DOM documentation for both abstract classes org.eclipse.jdt.core.dom.Expressionn and org.eclipse.jdt.core.dom.Statement
+
+<a name="v_B40"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 6, 2011
+<br>Project org.eclipse.jdt.core v_B40
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B40">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=326950">326950</a>
+[compiler][null]Do not optimize code generation based on static analysis (dead code)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324178">324178</a>
+[null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006">338006</a>
+IJavaProject#getPackageFragmentRoots() should return roots in order
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234">338234</a>
+[compiler] Missing warning for uninitialized variable in dead code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336428">336428</a>
+[compiler][null] bogus warning &quot;redundant null check&quot; in condition of do {} while() loop
+
 <a name="v_B39"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M6 - March 1, 2011 - 3.7.0 M6
+Eclipse SDK 3.7M6 - March 1, 2011
 <br>Project org.eclipse.jdt.core v_B39
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B39">cvs</a>).
 <h2>What's new in this drop</h2>
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
index f1804a5..ce3da94 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -57,7 +57,7 @@
 		if (isLeftOptimizedFalse) {
 			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
 				currentScope.problemReporter().fakeReachable(this.right);
-				rightInfo.setReachMode(FlowInfo.UNREACHABLE);
+				rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 			}
 		}
 		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index efe1e15..9c4213f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -238,7 +238,7 @@
  * exact need.
  */
 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 	ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
 
 	// perform some emulation work in case there is some and we are inside a local type only
@@ -257,7 +257,7 @@
 }
 
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 	// if constructor from parameterized type got found, use the original constructor at codegen time
 	MethodBinding codegenBinding = this.binding.original();
 //{ObjectTeams: baseclass decapsulation:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index 12d989b..efef338 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -56,7 +56,7 @@
 	UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits();
 	FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse();
 	if (isOptimizedTrueAssertion) {
-		assertInfo.setReachMode(FlowInfo.UNREACHABLE);
+		assertInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 	}
 
 	if (this.exceptionArgument != null) {
@@ -174,7 +174,7 @@
 }
 
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 		// need assertion flag: $assertionsDisabled on outer most source clas
 		// (in case of static member of interface, will use the outermost static member - bug 22334)
 		SourceTypeBinding outerMostClass = currentScope.enclosingSourceType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index 17f0b30..f03028c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -69,7 +69,7 @@
 					FlowInfo.DEAD_END);
 
 			// check for missing returning path
-			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 				this.bits |= ASTNode.NeedFreeReturn;
 			}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index e323760..03ab69a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -42,7 +42,18 @@
 	if (this.resolvedType.id != T_JavaLangString) {
 		this.lhs.checkNPE(currentScope, flowContext, flowInfo);
 	}
-	return  ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+	flowInfo = ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+	if (this.resolvedType.id == T_JavaLangString) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250
+		LocalVariableBinding local = this.lhs.localVariableBinding();
+		if (local != null && this.resolvedType.id == T_JavaLangString) {
+			// compound assignment results in a definitely non null value for String
+			flowInfo.markAsDefinitelyNonNull(local);
+			if (flowContext.initsOnFinally != null)
+				flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
+		}
+	}
+	return flowInfo;
 }
 
 	public boolean checkCastCompatibility() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index a911720..ac2a48b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -8,7 +8,10 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for bugs 133125, 292478
+ *     Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for
+ *     						bug 133125 - [compiler][null] need to report the null status of expressions and analyze them simultaneously
+ *     						bug 292478 - Report potentially null across variable assignment
+ * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -40,6 +43,9 @@
 	int trueInitStateIndex = -1;
 	int falseInitStateIndex = -1;
 	int mergedInitStateIndex = -1;
+	
+	// we compute and store the null status during analyseCode (https://bugs.eclipse.org/324178):
+	private int nullStatus = FlowInfo.UNKNOWN;
 
 	public ConditionalExpression(
 		Expression condition,
@@ -66,7 +72,7 @@
 		FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy();
 		if (isConditionOptimizedFalse) {
 			if ((mode & FlowInfo.UNREACHABLE) == 0) {
-				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 			}
 			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
 				this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel);
@@ -79,7 +85,7 @@
 		FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy();
 		if (isConditionOptimizedTrue) {
 			if ((mode & FlowInfo.UNREACHABLE) == 0) {
-				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 			}
 			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
 				this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel);
@@ -92,10 +98,30 @@
 		FlowInfo mergedInfo;
 		if (isConditionOptimizedTrue){
 			mergedInfo = trueFlowInfo.addPotentialInitializationsFrom(falseFlowInfo);
+			this.nullStatus = this.valueIfTrue.nullStatus(trueFlowInfo);
 		} else if (isConditionOptimizedFalse) {
 			mergedInfo = falseFlowInfo.addPotentialInitializationsFrom(trueFlowInfo);
+			this.nullStatus = this.valueIfFalse.nullStatus(falseFlowInfo);
 		} else {
-			// if ((t && (v = t)) ? t : t && (v = f)) r = v;  -- ok
+			// this block must meet two conflicting requirements (see https://bugs.eclipse.org/324178):
+			// (1) For null analysis of "Object o2 = (o1 != null) ? o1 : new Object();" we need to distinguish
+			//     the paths *originating* from the evaluation of the condition to true/false respectively.
+			//     This is used to determine the possible null status of the entire conditional expression.
+			// (2) For definite assignment analysis (JLS 16.1.5) of boolean conditional expressions of the form
+			//     "if (c1 ? expr1 : expr2) use(v);" we need to check whether any variable v will be definitely
+			//     assigned whenever the entire conditional expression evaluates to true (to reach the then branch).
+			//     I.e., we need to collect flowInfo *towards* the overall outcome true/false 
+			//     (regardless of the evaluation of the condition).
+			
+			// to support (1) use the infos of both branches originating from the condition for computing the nullStatus:
+			computeNullStatus(trueFlowInfo, falseFlowInfo);
+			
+			// to support (2) we split the true/false branches according to their inner structure. Consider this:
+			// if (b ? false : (true && (v = false))) return v; -- ok
+			// - expr1 ("false") has no path towards true (mark as unreachable)
+			// - expr2 ("(true && (v = false))") has a branch towards true on which v is assigned.
+			//   -> merging these two branches yields: v is assigned
+			// - the paths towards false are irrelevant since the enclosing if has no else.
 			cst = this.optimizedIfTrueConstant;
 			boolean isValueIfTrueOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
 			boolean isValueIfTrueOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
@@ -104,26 +130,26 @@
 			boolean isValueIfFalseOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
 			boolean isValueIfFalseOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
 
-			UnconditionalFlowInfo trueInfoWhenTrue = trueFlowInfo.initsWhenTrue().unconditionalCopy();
-			UnconditionalFlowInfo falseInfoWhenTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
-			UnconditionalFlowInfo trueInfoWhenFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
-			UnconditionalFlowInfo falseInfoWhenFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
+			UnconditionalFlowInfo trueFlowTowardsTrue = trueFlowInfo.initsWhenTrue().unconditionalCopy();
+			UnconditionalFlowInfo falseFlowTowardsTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
+			UnconditionalFlowInfo trueFlowTowardsFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
+			UnconditionalFlowInfo falseFlowTowardsFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
 			if (isValueIfTrueOptimizedFalse) {
-				trueInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);				
+				trueFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);				
 			}
 			if (isValueIfFalseOptimizedFalse) {
-				falseInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);	
+				falseFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
 			}
 			if (isValueIfTrueOptimizedTrue) {
-				trueInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);	
+				trueFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
 			}
 			if (isValueIfFalseOptimizedTrue) {
-				falseInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);	
+				falseFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
 			}
 			mergedInfo =
 				FlowInfo.conditional(
-					trueInfoWhenTrue.mergedWith(falseInfoWhenTrue),
-					trueInfoWhenFalse.mergedWith(falseInfoWhenFalse));
+					trueFlowTowardsTrue.mergedWith(falseFlowTowardsTrue),
+					trueFlowTowardsFalse.mergedWith(falseFlowTowardsFalse));
 		}
 		this.mergedInitStateIndex =
 			currentScope.methodScope().recordInitializationStates(mergedInfo);
@@ -131,6 +157,30 @@
 		return mergedInfo;
 	}
 
+	private void computeNullStatus(FlowInfo trueBranchInfo, FlowInfo falseBranchInfo) {
+		// given that the condition cannot be optimized to a constant 
+		// we now merge the nullStatus from both branches:
+		int ifTrueNullStatus = this.valueIfTrue.nullStatus(trueBranchInfo);
+		int ifFalseNullStatus = this.valueIfFalse.nullStatus(falseBranchInfo);
+
+		if (ifTrueNullStatus == ifFalseNullStatus) {
+			this.nullStatus = ifTrueNullStatus;
+			return;
+		}
+		// is there a chance of null (or non-null)? -> potentially null etc.
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
+		int status = 0;
+		int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
+		if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
+			status |= FlowInfo.POTENTIALLY_NULL;
+		if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+			status |= FlowInfo.POTENTIALLY_NON_NULL;
+		if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
+			status |= FlowInfo.POTENTIALLY_UNKNOWN;
+		if (status > 0)
+			this.nullStatus = status;
+	}
+
 	/**
 	 * Code generation for the conditional operator ?:
 	 *
@@ -320,33 +370,9 @@
 		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 	}
 
-public int nullStatus(FlowInfo flowInfo) {
-	Constant cst = this.condition.optimizedBooleanConstant();
-	if (cst != Constant.NotAConstant) {
-		if (cst.booleanValue()) {
-			return this.valueIfTrue.nullStatus(flowInfo);
-		}
-		return this.valueIfFalse.nullStatus(flowInfo);
+	public int nullStatus(FlowInfo flowInfo) {
+		return this.nullStatus;
 	}
-	int ifTrueNullStatus = this.valueIfTrue.nullStatus(flowInfo),
-	    ifFalseNullStatus = this.valueIfFalse.nullStatus(flowInfo);
-	if (ifTrueNullStatus == ifFalseNullStatus) {
-		return ifTrueNullStatus;
-	}
-	// is there a chance of null (or non-null)? -> potentially null etc.
-	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
-	int status = 0;
-	int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
-	if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
-		status |= FlowInfo.POTENTIALLY_NULL;
-	if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
-		status |= FlowInfo.POTENTIALLY_NON_NULL;
-	if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
-		status |= FlowInfo.POTENTIALLY_UNKNOWN;
-	if (status > 0)
-		return status;
-	return FlowInfo.UNKNOWN;
-}
 
 	public Constant optimizedBooleanConstant() {
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index d01c4c4..d6e26ae 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -282,7 +282,7 @@
 			}
 		}
 		// check for missing returning path
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 			this.bits |= ASTNode.NeedFreeReturn;
 		}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
index cf09127..5806ce8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -72,7 +72,7 @@
 		// code generation can be optimized when no need to continue in the loop
 		if ((actionInfo.tagBits &
 				loopingContext.initsOnContinue.tagBits &
-				FlowInfo.UNREACHABLE) != 0) {
+				FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 			this.continueLabel = null;
 		}
 		if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 2036f58..80d7e35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -273,7 +273,7 @@
 	void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
 		ReferenceBinding superTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
 
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
 		// perform some emulation work in case there is some and we are inside a local type only
 		if (superTypeErasure.isNestedType()
 			&& currentScope.enclosingSourceType().isLocalType()) {
@@ -289,7 +289,7 @@
 	}
 
 	public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
 			// if constructor from parameterized type got found, use the original constructor at codegen time
 			MethodBinding codegenBinding = this.binding.original();
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index eba9092..6032875 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -490,7 +490,7 @@
  * No need to emulate access to protected fields since not implicitly accessed
  */
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)	return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
 	
 //{ObjectTeams: don't create (more) synthetics for base field accessed via callout:
 	if (   FieldModel.isCalloutAccessed(this.binding) 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index 86593c7..7f0b9b1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -136,7 +136,7 @@
 				} else {
 					actionInfo = initsWhenTrue.unconditionalCopy();
 					if (isConditionOptimizedFalse){
-						actionInfo.setReachMode(FlowInfo.UNREACHABLE);
+						actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 					}
 				}
 			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
@@ -146,7 +146,7 @@
 			// code generation can be optimized when no need to continue in the loop
 			if ((actionInfo.tagBits &
 					loopingContext.initsOnContinue.tagBits &
-					FlowInfo.UNREACHABLE) != 0) {
+					FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 				this.continueLabel = null;
 			}
 			else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 711fde8..3a7b16c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -121,7 +121,7 @@
 			addInitializationsFrom(condInfo.initsWhenFalse());
 			// TODO (maxime) no need to test when false: can optimize (same for action being unreachable above)
 			if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits &
-					FlowInfo.UNREACHABLE) != 0) {
+					FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 				this.continueLabel = null;
 			} else {
 				actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
index 3e996d6..7d0788e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -67,11 +67,11 @@
 	// process the THEN part
 	FlowInfo thenFlowInfo = conditionFlowInfo.safeInitsWhenTrue();
 	if (isConditionOptimizedFalse) {
-		thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+		thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 	}
 	FlowInfo elseFlowInfo = conditionFlowInfo.initsWhenFalse().copy();
 	if (isConditionOptimizedTrue) {
-		elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
+		elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 	}
 	if (((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) && 
 			((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)) {
@@ -99,7 +99,7 @@
 		thenFlowInfo = this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
 	}
 	// code gen: optimizing the jump around the ELSE part
-	if ((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) {
+	if ((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 		this.bits |= ASTNode.ThenExit;
 	}
 
@@ -167,10 +167,7 @@
 	if (hasThenPart) {
 		BranchLabel falseLabel = null;
 		// generate boolean condition only if needed
-		if (((this.bits & ASTNode.IsElseStatementUnreachable) != 0) ||
-				(cst != Constant.NotAConstant && cst.booleanValue() == true)) {
-			// No need to generate if condition statement when we know that only the then action
-			// will be executed
+		if (cst != Constant.NotAConstant && cst.booleanValue() == true) {
 			this.condition.generateCode(currentScope, codeStream, false);
 		} else {
 			this.condition.generateOptimizedBoolean(
@@ -209,10 +206,7 @@
 		}
 	} else if (hasElsePart) {
 		// generate boolean condition only if needed
-		if (((this.bits & ASTNode.IsThenStatementUnreachable) != 0) ||
-				(cst != Constant.NotAConstant && cst.booleanValue() == false)) {
-			// No need to generate if condition statement when we know that only the else action
-			// will be executed
+		if (cst != Constant.NotAConstant && cst.booleanValue() == false) {
 			this.condition.generateCode(currentScope, codeStream, false);
 		} else {
 			this.condition.generateOptimizedBoolean(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index c6c3bde..2ea7500 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -78,7 +78,7 @@
 
 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 	// record variable initialization if any
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 		this.bits |= ASTNode.IsLocalDeclarationReachable; // only set if actually reached
 	}
 	if (this.binding != null && this.type.resolvedType instanceof TypeVariableBinding) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index fcc3378..84e44b9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -390,7 +390,7 @@
 }
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo){
 
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)	return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
 
 	// if method from parameterized type got found, use the original method at codegen time
 	MethodBinding codegenBinding = this.binding.original();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 761df2b..bba3939 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -164,7 +164,7 @@
 			// check for missing returning path
 			TypeBinding returnTypeBinding = this.binding.returnType;
 			if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) {
-				if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+				if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 					this.bits |= ASTNode.NeedFreeReturn;
 				}
 			} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
index c041fee..4b3fca4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -59,7 +59,7 @@
 		if (isLeftOptimizedTrue){
 			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
 				currentScope.problemReporter().fakeReachable(this.right);
-				rightInfo.setReachMode(FlowInfo.UNREACHABLE);
+				rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 			}
 		}
 		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 48bea2c..18a692b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -266,7 +266,7 @@
 	 * exact need.
 	 */
 	public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
 		ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
 
 		// perform some extra emulation work in case there is some and we are inside a local type only
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 9b17a89..368c64a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -929,7 +929,7 @@
  * index is <0 to denote write access emulation
  */
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 	// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
 	if (fieldBinding.constant() != Constant.NotAConstant)
 		return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 3974bcf..392466e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -862,7 +862,7 @@
 }
 
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)	return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
 
 	//If inlinable field, forget the access emulation, the code gen will directly target it
 	if (this.constant != Constant.NotAConstant)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 1d36009..fdbd5a0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -83,7 +83,7 @@
 // Report an error if necessary (if even more unreachable than previously reported
 // complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
 public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) {
-	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
+	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 		this.bits &= ~ASTNode.IsReachable;
 //{ObjectTeams: ignore generated "return _OT$result" (generateCode will also ignore this statement):
 		boolean shouldReport = true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
index 1ce89ee..b2c6dfd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -64,7 +64,7 @@
 		currentScope.methodScope().recordInitializationStates(flowInfo);
 
 	// optimizing code gen
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
 		this.bits |= ASTNode.BlockExit;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 365cc44..aad2e5f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -116,7 +116,7 @@
 			tryInfo = flowInfo;
 		} else {
 			tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy());
-			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
 				this.bits |= ASTNode.IsTryBlockExiting;
 		}
 
@@ -165,7 +165,7 @@
 				ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
 				*/
 				if (this.tryBlock.statements == null) {
-					catchInfo.setReachMode(FlowInfo.UNREACHABLE);
+					catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 				catchInfo =
 					this.catchBlocks[i].analyseCode(
@@ -174,7 +174,7 @@
 						catchInfo);
 				this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
 				this.catchExits[i] =
-					(catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
+					(catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
 				tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
 			}
 		}
@@ -225,7 +225,7 @@
 			tryInfo = flowInfo;
 		} else {
 			tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy());
-			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
 				this.bits |= ASTNode.IsTryBlockExiting;
 		}
 
@@ -274,7 +274,7 @@
 				ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
 				*/
 				if (this.tryBlock.statements == null) {
-					catchInfo.setReachMode(FlowInfo.UNREACHABLE);
+					catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 				catchInfo =
 					this.catchBlocks[i].analyseCode(
@@ -283,7 +283,7 @@
 						catchInfo);
 				this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
 				this.catchExits[i] =
-					(catchInfo.tagBits & FlowInfo.UNREACHABLE) != 0;
+					(catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
 				tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 79408af..78d4769 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -524,7 +524,7 @@
 	if (this.ignoreFurtherInvestigation)
 		return flowInfo;
 	try {
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 			this.bits |= ASTNode.IsReachable;
 			LocalTypeBinding localType = (LocalTypeBinding) this.binding;
 //{ObjectTeams: constantPoolName is set in advance for copy-inherited local types:
@@ -565,7 +565,7 @@
 	if (this.ignoreFurtherInvestigation)
 		return;
 	try {
-		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 			this.bits |= ASTNode.IsReachable;
 			LocalTypeBinding localType = (LocalTypeBinding) this.binding;
 			localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
@@ -1174,7 +1174,7 @@
 		for (int i = 0, count = this.fields.length; i < count; i++) {
 			FieldDeclaration field = this.fields[i];
 			if (field.isStatic()) {
-				if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+				if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
 					field.bits &= ~ASTNode.IsReachable;
 
 				/*if (field.isField()){
@@ -1187,10 +1187,10 @@
 				// branch, since the previous initializer already got the blame.
 				if (staticFieldInfo == FlowInfo.DEAD_END) {
 					this.staticInitializerScope.problemReporter().initializerMustCompleteNormally(field);
-					staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE);
+					staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 			} else {
-				if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0)
+				if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
 					field.bits &= ~ASTNode.IsReachable;
 
 				/*if (field.isField()){
@@ -1203,7 +1203,7 @@
 				// branch, since the previous initializer already got the blame.
 				if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
 					this.initializerScope.problemReporter().initializerMustCompleteNormally(field);
-					nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE);
+					nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 			}
 		}
@@ -1331,7 +1331,7 @@
  * 15.9.2
  */
 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 	NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
 
 	MethodScope methodScope = currentScope.methodScope();
@@ -1382,7 +1382,7 @@
  * Local member cannot be static.
  */
 public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScope, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 	NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
 	nestedType.addSyntheticArgumentAndField(this.binding.enclosingType());
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
index 144e64e..c51042e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -82,7 +82,7 @@
 			} else {
 				FlowInfo mergedInfo = flowInfo.copy().addInitializationsFrom(condInfo.initsWhenFalse());
 				if (isConditionOptimizedTrue){
-					mergedInfo.setReachMode(FlowInfo.UNREACHABLE);
+					mergedInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 				this.mergedInitStateIndex =
 					currentScope.methodScope().recordInitializationStates(mergedInfo);
@@ -104,7 +104,7 @@
 			} else {
 				actionInfo = condInfo.initsWhenTrue().copy();
 				if (isConditionOptimizedFalse){
-					actionInfo.setReachMode(FlowInfo.UNREACHABLE);
+					actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 			}
 
@@ -120,11 +120,10 @@
 			// code generation can be optimized when no need to continue in the loop
 			exitBranch = flowInfo.copy();
 			// need to start over from flowInfo so as to get null inits
-
-			if ((actionInfo.tagBits &
-					loopingContext.initsOnContinue.tagBits &
-					FlowInfo.UNREACHABLE) != 0) {
-				this.continueLabel = null;
+            int combinedTagBits = actionInfo.tagBits & loopingContext.initsOnContinue.tagBits;
+			if ((combinedTagBits & FlowInfo.UNREACHABLE) != 0) {
+				if ((combinedTagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+					this.continueLabel = null;
 				exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
 			} else {
 				condLoopContext.complainOnDeferredFinalChecks(currentScope,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index c6c3348..c137b42 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -195,7 +195,7 @@
 		this.tagBits &= ~UNREACHABLE;
 	}
 	else {
-		this.tagBits |= UNREACHABLE;
+		this.tagBits |= reachMode;
 	}
 	this.initsWhenTrue.setReachMode(reachMode);
 	this.initsWhenFalse.setReachMode(reachMode);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index e82b26c..c6b591e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -231,8 +231,8 @@
 }
 
 public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
-		if ((this.initsOnReturn.tagBits & FlowInfo.UNREACHABLE) == 0) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		if ((this.initsOnReturn.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 			this.initsOnReturn = this.initsOnReturn.mergedWith(flowInfo);
 		}
 		else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
index 37bf18f..0590583 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -229,14 +229,14 @@
 									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
 								}
 								if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 								}
 							} else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
 								if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 									scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
 								}
 								if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 								}
 							}
 							return;
@@ -252,7 +252,7 @@
 										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
 									}
 									if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-										flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+										flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 									}
 									return;
 								case FlowContext.IN_COMPARISON_NON_NULL:
@@ -264,7 +264,7 @@
 										scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
 									}
 									if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-										flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+										flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 									}
 									return;
 								case FlowContext.IN_ASSIGNMENT:
@@ -314,14 +314,14 @@
 									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
 								}
 								if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 								}
 							} else {
 								if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 									scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
 								}
 								if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 								}
 							}
 							return;
@@ -342,7 +342,7 @@
 										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
 									}
 									if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-										flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+										flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 									}
 									return;
 								case FlowContext.IN_COMPARISON_NON_NULL:
@@ -354,7 +354,7 @@
 										scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
 									}
 									if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-										flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+										flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 									}
 									return;
 								case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 369d24e..2ce915a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -530,7 +530,7 @@
 }
 
 public void recordSettingFinal(VariableBinding variable, Reference finalReference, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
 	// for initialization inside looping statement that effectively loops
 	FlowContext context = this;
 	while (context != null) {
@@ -578,14 +578,14 @@
 						scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				} else {
 					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 						scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				}
 				return;
@@ -609,7 +609,7 @@
 							scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
 						}
 						if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-							flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+							flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 						}
 						return;
 					case FlowContext.IN_COMPARISON_NON_NULL:
@@ -621,7 +621,7 @@
 							scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
 						}
 						if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-							flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+							flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 						}
 						return;
 					case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index bcf1b83..4cd7135 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -36,9 +36,24 @@
 
 	public int tagBits; // REACHABLE by default
 	public final static int REACHABLE = 0;
-	public final static int UNREACHABLE = 1;
-	public final static int NULL_FLAG_MASK = 2;
-
+	/* unreachable code 
+	 * eg. while (true);
+	 *     i++;  --> unreachable code 
+	 */
+	public final static int UNREACHABLE_OR_DEAD = 1;
+	/* unreachable code as inferred by null analysis
+	 * eg. str = null;
+	 *     if (str != null) {
+	 *        // dead code
+	 *     }
+	 */
+	public final static int UNREACHABLE_BY_NULLANALYSIS = 2;
+	/*
+	 * code unreachable in any fashion
+	 */
+	public final static int UNREACHABLE = UNREACHABLE_OR_DEAD | UNREACHABLE_BY_NULLANALYSIS;
+	public final static int NULL_FLAG_MASK = 4;
+	
 	public final static int UNKNOWN = 1;
 	public final static int NULL = 2;
 	public final static int NON_NULL = 4;
@@ -369,7 +384,7 @@
 	UnconditionalFlowInfo mergedInfo;
 	if (isOptimizedTrue){
 		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
-			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE).
+			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
 				unconditionalInits();
 		}
 		else {
@@ -381,7 +396,7 @@
 	}
 	else if (isOptimizedFalse) {
 		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
-			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE).
+			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
 				unconditionalInits();
 		}
 		else {
@@ -408,7 +423,7 @@
 	UnconditionalFlowInfo mergedInfo;
 	if (isOptimizedTrue){
 		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
-			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE).
+			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
 				unconditionalInits();
 		}
 		else {
@@ -420,7 +435,7 @@
 	}
 	else if (isOptimizedFalse) {
 		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
-			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE).
+			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
 				unconditionalInits();
 		}
 		else {
@@ -470,10 +485,9 @@
 }
 
 /**
- * Return REACHABLE if this flow info is reachable, UNREACHABLE
- * else.
- * @return REACHABLE if this flow info is reachable, UNREACHABLE
- *         else
+ * Find out the reachability mode of this flowInfo.
+ * @return REACHABLE if this flow info is reachable, otherwise
+ *         either UNREACHABLE_OR_DEAD or UNREACHABLE_BY_NULLANALYSIS.
  */
 public int reachMode() {
 	return this.tagBits & UNREACHABLE;
@@ -490,7 +504,8 @@
 
 /**
  * Set this flow info reach mode and return this.
- * @param reachMode one of {@link #REACHABLE REACHABLE} or {@link #UNREACHABLE UNREACHABLE}
+ * @param reachMode one of {@link #REACHABLE REACHABLE}, {@link #UNREACHABLE_OR_DEAD UNREACHABLE_OR_DEAD},
+ * {@link #UNREACHABLE_BY_NULLANALYSIS UNREACHABLE_BY_NULLANALYSIS} or {@link #UNREACHABLE UNREACHABLE}
  * @return this, with the reach mode set to reachMode
  */
 abstract public FlowInfo setReachMode(int reachMode);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
index 4ffc764..4daa2c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -43,7 +43,7 @@
 }
 
 public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
 	if (this.initsOnReturn == FlowInfo.DEAD_END) {
 		this.initsOnReturn = (UnconditionalFlowInfo) flowInfo.copy();
 	} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
index 6606cbe..9355779 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -384,42 +385,42 @@
 }
 
 public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
-	if ((this.initsOnContinue.tagBits & FlowInfo.UNREACHABLE) == 0) {
-		this.initsOnContinue = this.initsOnContinue.
-			mergedWith(flowInfo.unconditionalInitsWithoutSideEffect());
-	}
-	else {
-		this.initsOnContinue = flowInfo.unconditionalCopy();
-	}
-	FlowContext inner = innerFlowContext;
-	while (inner != this && !(inner instanceof LoopingFlowContext)) {
-		inner = inner.parent;
-	}
-	if (inner == this) {
-		this.upstreamNullFlowInfo.
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+		if ((this.initsOnContinue.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.initsOnContinue = this.initsOnContinue.
+					mergedWith(flowInfo.unconditionalInitsWithoutSideEffect());
+		}
+		else {
+			this.initsOnContinue = flowInfo.unconditionalCopy();
+		}
+		FlowContext inner = innerFlowContext;
+		while (inner != this && !(inner instanceof LoopingFlowContext)) {
+			inner = inner.parent;
+		}
+		if (inner == this) {
+			this.upstreamNullFlowInfo.
 			addPotentialNullInfoFrom(
-				flowInfo.unconditionalInitsWithoutSideEffect());
-	}
-	else {
-		int length = 0;
-		if (this.innerFlowContexts == null) {
-			this.innerFlowContexts = new LoopingFlowContext[5];
-			this.innerFlowInfos = new UnconditionalFlowInfo[5];
+					flowInfo.unconditionalInitsWithoutSideEffect());
 		}
-		else if (this.innerFlowContextsCount ==
-				(length = this.innerFlowContexts.length) - 1) {
-			System.arraycopy(this.innerFlowContexts, 0,
-				(this.innerFlowContexts = new LoopingFlowContext[length + 5]),
-				0, length);
-			System.arraycopy(this.innerFlowInfos, 0,
-				(this.innerFlowInfos= new UnconditionalFlowInfo[length + 5]),
-				0, length);
+		else {
+			int length = 0;
+			if (this.innerFlowContexts == null) {
+				this.innerFlowContexts = new LoopingFlowContext[5];
+				this.innerFlowInfos = new UnconditionalFlowInfo[5];
+			}
+			else if (this.innerFlowContextsCount ==
+					(length = this.innerFlowContexts.length) - 1) {
+				System.arraycopy(this.innerFlowContexts, 0,
+						(this.innerFlowContexts = new LoopingFlowContext[length + 5]),
+						0, length);
+				System.arraycopy(this.innerFlowInfos, 0,
+						(this.innerFlowInfos= new UnconditionalFlowInfo[length + 5]),
+						0, length);
+			}
+			this.innerFlowContexts[this.innerFlowContextsCount] = (LoopingFlowContext) inner;
+			this.innerFlowInfos[this.innerFlowContextsCount++] =
+					flowInfo.unconditionalInitsWithoutSideEffect();
 		}
-		this.innerFlowContexts[this.innerFlowContextsCount] = (LoopingFlowContext) inner;
-		this.innerFlowInfos[this.innerFlowContextsCount++] =
-			flowInfo.unconditionalInitsWithoutSideEffect();
-	}
 	}
 }
 
@@ -493,14 +494,14 @@
 						scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				} else {
 					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 						scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				}
 			} else if (flowInfo.isDefinitelyNull(local)) {
@@ -509,14 +510,14 @@
 						scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				} else {
 					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 						scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
 					}
 					if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				}
 			} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {    
@@ -525,11 +526,18 @@
 				if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
 					recordNullReference(local, reference, checkType);
 				}
-			} else if (! flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
-				if (flowInfo.isPotentiallyNonNull(local)) {
-					recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK);
-				} else {
-					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+			} else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
+				return; // no reason to complain, since there is definitely some uncertainty making the comparison relevant.
+			} else {
+				if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+					// note: pot non-null & pot null is already captured by cannotBeDefinitelyNullOrNonNull()
+					if (flowInfo.isPotentiallyNonNull(local)) {
+						// knowing 'local' can be non-null, we're only interested in seeing whether it can *only* be non-null 
+						recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK);
+					} else if (flowInfo.isPotentiallyNull(local)) {
+						// knowing 'local' can be null, we're only interested in seeing whether it can *only* be null
+						recordNullReference(local, reference, CAN_ONLY_NULL | checkType & CONTEXT_MASK);
+					} else {
 						recordNullReference(local, reference, checkType);
 					}
 				}
@@ -554,7 +562,7 @@
 							scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
 						}
 						if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-							flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE);
+							flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 						}
 						return;
 					case FlowContext.IN_COMPARISON_NON_NULL:
@@ -566,7 +574,7 @@
 							scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
 						}
 						if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) {
-							flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE);
+							flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 						}
 						return;
 					case FlowContext.IN_ASSIGNMENT:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
index f0772c0..c17fa4e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -42,7 +42,7 @@
 }
 
 public void recordBreakFrom(FlowInfo flowInfo) {
-	if ((this.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) == 0) {
+	if ((this.initsOnBreak.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
 		this.initsOnBreak = this.initsOnBreak.mergedWith(flowInfo.unconditionalInits());
 	}
 	else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index cf23292..0de5fc4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -742,7 +742,7 @@
 final public boolean isDefinitelyAssigned(FieldBinding field) {
 	// Mirrored in CodeStream.isDefinitelyAssigned(..)
 	// do not want to complain in unreachable code
-	if ((this.tagBits & UNREACHABLE) != 0) {
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
 		return true;
 	}
 //{ObjectTeams: if it is copied don't require definite assignment again
@@ -754,7 +754,7 @@
 
 final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
 	// do not want to complain in unreachable code if local declared in reachable code
-	if ((this.tagBits & UNREACHABLE) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
 		return true;
 	}
 	return isDefinitelyAssigned(local.id + this.maxFieldCount);
@@ -1551,7 +1551,7 @@
 }
 
 public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
-	if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) {
+	if ((otherInits.tagBits & UNREACHABLE_OR_DEAD) != 0 && this != DEAD_END) {
 		if (COVERAGE_TEST_FLAG) {
 			if(CoverageTestId == 28) {
 				throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$
@@ -1560,7 +1560,7 @@
 		combineNullStatusChangeInAssertInfo(otherInits);
 		return this;
 	}
-	if ((this.tagBits & UNREACHABLE) != 0) {
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
 		if (COVERAGE_TEST_FLAG) {
 			if(CoverageTestId == 29) {
 				throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$
@@ -1585,7 +1585,17 @@
 		na1, na2, na3, na4,
 		nb1, nb2, nb3, nb4,
 		b1, b2, b3, b4;
-	if (thisHadNulls) {
+	if ((otherInits.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) {
+		otherHasNulls = false; // skip merging, otherInits is unreachable by null analysis
+	} else if ((this.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) { // directly copy if this is unreachable by null analysis
+		this.nullBit1 = otherInits.nullBit1;
+		this.nullBit2 = otherInits.nullBit2;
+		this.nullBit3 = otherInits.nullBit3;
+		this.nullBit4 = otherInits.nullBit4;
+		thisHadNulls = false;
+		thisHasNulls = otherHasNulls;
+		this.tagBits = otherInits.tagBits;
+	} else if (thisHadNulls) {
     	if (otherHasNulls) {
     		this.nullBit1 = (a2 = this.nullBit2) & (a3 = this.nullBit3)
     							& (a4 = this.nullBit4) & (b1 = otherInits.nullBit1)
@@ -1880,6 +1890,8 @@
 	}	
 	if (reachMode == REACHABLE ) {
 		this.tagBits &= ~UNREACHABLE;
+	} else if (reachMode == UNREACHABLE_BY_NULLANALYSIS ) {
+		this.tagBits |= UNREACHABLE_BY_NULLANALYSIS;	// do not interfere with definite assignment analysis
 	} else {
 		if ((this.tagBits & UNREACHABLE) == 0) {
 			// reset optional inits when becoming unreachable
@@ -1892,7 +1904,7 @@
 				}
 			}
 		}
-		this.tagBits |= UNREACHABLE;
+		this.tagBits |= reachMode;
 	}
 	return this;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index a5d01bf..becddb0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -508,7 +508,7 @@
 }
 
 public final int recordInitializationStates(FlowInfo flowInfo) {
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return -1;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return -1;
 	UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInitsWithoutSideEffect();
 	long[] extraInits = unconditionalFlowInfo.extra == null ?
 			null : unconditionalFlowInfo.extra[0];
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
index 6f0ad72..cc91b87 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -17,30 +17,31 @@
  * <p>
  * <pre>
  * Expression:
- *    Name
- *    NumberLiteral
- *    CharacterLiteral
- *    NullLiteral
- *    BooleanLiteral
- *    StringLiteral
- *    TypeLiteral
- *    ThisExpression
- *    SuperFieldAccess
- *    FieldAccess
- *    Assignment
- *    ParenthesizedExpression
- *    ClassInstanceCreation
- *    ArrayCreation
- *    ArrayInitializer
- *    MethodInvocation
- *    SuperMethodInvocation
- *    ArrayAccess
- *    InfixExpression
- *    InstanceofExpression
- *    ConditionalExpression
- *    PostfixExpression
- *    PrefixExpression
- *    CastExpression
+ *    Annotation,
+ *    ArrayAccess,
+ *    ArrayCreation,
+ *    ArrayInitializer,
+ *    Assignment,
+ *    BooleanLiteral,
+ *    CastExpression,
+ *    CharacterLiteral,
+ *    ClassInstanceCreation,
+ *    ConditionalExpression,
+ *    FieldAccess,
+ *    InfixExpression,
+ *    InstanceofExpression,
+ *    MethodInvocation,
+ *    Name,
+ *    NullLiteral,
+ *    NumberLiteral,
+ *    ParenthesizedExpression,
+ *    PostfixExpression,
+ *    PrefixExpression,
+ *    StringLiteral,
+ *    SuperFieldAccess,
+ *    SuperMethodInvocation,
+ *    ThisExpression,
+ *    TypeLiteral,
  *    VariableDeclarationExpression
  * </pre>
  * </p>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
index 84d426b..36d2268 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -23,51 +23,53 @@
  * For JLS2:
  * <pre>
  * Statement:
- *    Block
- *    IfStatement
- *    ForStatement
- *    WhileStatement
- *    DoStatement
- *    TryStatement
- *    SwitchStatement
- *    SynchronizedStatement
- *    ReturnStatement
- *    ThrowStatement
- *    BreakStatement
- *    ContinueStatement
- *    EmptyStatement
- *    ExpressionStatement
- *    LabeledStatement
- *    AssertStatement
- *    VariableDeclarationStatement
- *    TypeDeclarationStatement
- *    ConstructorInvocation
- *    SuperConstructorInvocation
+ *    AssertStatement,
+ *    Block,
+ *    BreakStatement,
+ *    ConstructorInvocation,
+ *    ContinueStatement,
+ *    DoStatement,
+ *    EmptyStatement,
+ *    ExpressionStatement,
+ *    ForStatement,
+ *    IfStatement,
+ *    LabeledStatement,
+ *    ReturnStatement,
+ *    SuperConstructorInvocation,
+ *    SwitchCase,
+ *    SwitchStatement,
+ *    SynchronizedStatement,
+ *    ThrowStatement,
+ *    TryStatement,
+ *    TypeDeclarationStatement,
+ *    VariableDeclarationStatement,
+ *    WhileStatement 
  * </pre>
  * For JLS3, an enhanced for node type was added:
  * <pre>
  * Statement:
- *    Block
- *    IfStatement
- *    ForStatement
- *    EnhancedForStatement
+ *    AssertStatement,
+ *    Block,
+ *    BreakStatement,
+ *    ConstructorInvocation,
+ *    ContinueStatement,
+ *    DoStatement,
+ *    EmptyStatement,
+ *    EnhancedForStatement,
+ *    ExpressionStatement,
+ *    ForStatement,
+ *    IfStatement,
+ *    LabeledStatement,
+ *    ReturnStatement,
+ *    SuperConstructorInvocation,
+ *    SwitchCase,
+ *    SwitchStatement,
+ *    SynchronizedStatement,
+ *    ThrowStatement,
+ *    TryStatement,
+ *    TypeDeclarationStatement,
+ *    VariableDeclarationStatement,
  *    WhileStatement
- *    DoStatement
- *    TryStatement
- *    SwitchStatement
- *    SynchronizedStatement
- *    ReturnStatement
- *    ThrowStatement
- *    BreakStatement
- *    ContinueStatement
- *    EmptyStatement
- *    ExpressionStatement
- *    LabeledStatement
- *    AssertStatement
- *    VariableDeclarationStatement
- *    TypeDeclarationStatement
- *    ConstructorInvocation
- *    SuperConstructorInvocation
  * </pre>
  * </p>
  *
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
index 71d12e0..4cd8083 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -278,7 +278,7 @@
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess){
 	// The private access will be managed through the code generation
 
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 }
 public TypeBinding resolveType(BlockScope scope) {
 	// Answer the signature type of the field.
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index feef879..439f8ed 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -172,8 +172,8 @@
 }
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
 
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
-	// if method from parameterized type got found, use the original method at codegen time
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		// if method from parameterized type got found, use the original method at codegen time
 		MethodBinding codegenBinding = this.binding.original();
 		if (codegenBinding != this.binding) {
 	    // extra cast needed if method return type was type variable
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
index 151a215..ea2877b 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -576,7 +576,7 @@
 		return;
 	}
 
-	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return;
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
 	//If inlinable field, forget the access emulation, the code gen will directly target it
 	if (this.constant != Constant.NotAConstant)
 		return;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
index 1ae3ff1..64935a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -49,7 +49,9 @@
  * Java project elements need to be opened before they can be navigated or manipulated.
  * The children of a Java project are the package fragment roots that are
  * defined by the classpath and contained in this project (in other words, it
- * does not include package fragment roots for other projects).
+ * does not include package fragment roots for other projects). The children
+ * (i.e. the package fragment roots) appear in the order they are defined by 
+ * the classpath.
  * </p>
  * <p>
  * An instance of one of these handles can be created via
@@ -518,7 +520,8 @@
 	 * Returns all of the  package fragment roots contained in this
 	 * project, identified on this project's resolved classpath. The result
 	 * does not include package fragment roots in other projects referenced
-	 * on this project's classpath.
+	 * on this project's classpath. The package fragment roots appear in the 
+	 * order they are defined by the classpath.
 	 *
 	 * <p>NOTE: This is equivalent to <code>getChildren()</code>.
 	 *
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 003f397..9d1aaf5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -282,12 +282,71 @@
 		if (parent != null && parent.isOpen()) {
 			try {
 				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
-				info.addChild(child);
-			} catch (JavaModelException e) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006
+				// Insert the package fragment roots in the same order as the classpath order.
+				if (child instanceof IPackageFragmentRoot)
+					addPackageFragmentRoot(info, (IPackageFragmentRoot) child);
+				else
+					info.addChild(child);
+ 			} catch (JavaModelException e) {
 				// do nothing - we already checked if open
 			}
 		}
 	}
+	
+	private void addPackageFragmentRoot(OpenableElementInfo parent, IPackageFragmentRoot child)
+			throws JavaModelException {
+
+		IJavaElement[] roots = parent.getChildren();
+		if (roots.length > 0) {
+			IClasspathEntry[] resolvedClasspath = ((JavaProject) child.getJavaProject()).getResolvedClasspath();
+			IPath currentEntryPath = child.getResolvedClasspathEntry().getPath();
+			int indexToInsert = -1;
+			int lastComparedIndex = -1;
+			int i = 0, j = 0;
+			for (; i < roots.length && j < resolvedClasspath.length;) {
+
+				IClasspathEntry classpathEntry = resolvedClasspath[j];
+				if (lastComparedIndex != j && currentEntryPath.equals(classpathEntry.getPath())) {
+					indexToInsert = i;
+					break;
+				}
+				lastComparedIndex = j;
+
+				IClasspathEntry rootEntry = ((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry();
+				if (rootEntry.getPath().equals(classpathEntry.getPath()))
+					i++;
+				else
+					j++;
+			}
+
+			for (; i < roots.length; i++) {
+				// If the new root is already among the children, no need to proceed further. Just return.
+				if (roots[i].equals(child)) {
+					return;
+				}
+				// If we start seeing root's classpath entry different from the child's entry, then the child can't
+				// be present further down the roots array.
+				if (!((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry().getPath()
+						.equals(currentEntryPath))
+					break;
+			}
+
+			if (indexToInsert >= 0) {
+				int newSize = roots.length + 1;
+				IPackageFragmentRoot[] newChildren = new IPackageFragmentRoot[newSize];
+
+				if (indexToInsert > 0)
+					System.arraycopy(roots, 0, newChildren, 0, indexToInsert);
+
+				newChildren[indexToInsert] = child;
+				System.arraycopy(roots, indexToInsert, newChildren, indexToInsert + 1, (newSize - indexToInsert - 1));
+				parent.setChildren(newChildren);
+				return;
+			}
+		}
+		parent.addChild(child);
+	}
 	/*
 	 * Process the given delta and look for projects being added, opened, closed or
 	 * with a java nature being added or removed.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index ae3da8c..56d449d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -2631,6 +2631,7 @@
 		JavaModelManager manager = JavaModelManager.getJavaModelManager();
 		ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
 		ResolvedClasspath result = new ResolvedClasspath();
+		Map knownDrives = new HashMap();
 
 		Map referencedEntriesMap = new HashMap();
 		List rawLibrariesPath = new ArrayList();
@@ -2691,11 +2692,11 @@
 								if (!rawLibrariesPath.contains(extraEntries[j].getPath())) {
 									// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305037
 									// referenced entries for variable entries could also be persisted with extra attributes, so addAsChainedEntry = true
-									addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true);
+									addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
 								}
 							}
 						}
-						addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+						addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
 					}
 					break;
 
@@ -2738,12 +2739,12 @@
 								ClasspathEntry[] extraEntries = cEntry.resolvedChainedLibraries();
 								for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
 									if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
-										addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+										addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
 									}
 								}
 							}
 						}
-						addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+						addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
 					}
 					break;
 
@@ -2756,15 +2757,15 @@
 						ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
 						for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
 							if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
-								addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true);
+								addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
 							}
 						}
 					}
 
-					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
 					break;
 				default :
-					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false);
+					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
 					break;
 			}
 		}
@@ -2775,7 +2776,7 @@
 
 	private void addToResult(IClasspathEntry rawEntry, IClasspathEntry resolvedEntry, ResolvedClasspath result,
 			LinkedHashSet resolvedEntries, ExternalFoldersManager externalFoldersManager,
-			Map oldChainedEntriesMap, boolean addAsChainedEntry) {
+			Map oldChainedEntriesMap, boolean addAsChainedEntry, Map knownDrives) {
 
 		IPath resolvedPath;
 		// If it's already been resolved, do not add to resolvedEntries
@@ -2799,7 +2800,7 @@
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=336046
 		// The source attachment path could be external too and in which case, must be added.
 		IPath sourcePath = resolvedEntry.getSourceAttachmentPath();
-		if (sourcePath != null && ExternalFoldersManager.isExternalFolderPath(sourcePath)) {
+		if (sourcePath != null && driveExists(sourcePath, knownDrives) && ExternalFoldersManager.isExternalFolderPath(sourcePath)) {
 			externalFoldersManager.addFolder(sourcePath, true);
 		}
 	}
@@ -2820,6 +2821,26 @@
 	}
 	
 	/*
+	 * File#exists() takes lot of time for an unmapped drive. Hence, cache the info.
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649
+	 */
+	private boolean driveExists(IPath sourcePath, Map knownDrives) {	
+		String drive = sourcePath.getDevice();
+		if (drive == null) return true;
+		Boolean good = (Boolean)knownDrives.get(drive);
+		if (good == null) {
+			if (new File(drive).exists()) {
+				knownDrives.put(drive, Boolean.TRUE);
+				return true;
+			} else {
+				knownDrives.put(drive, Boolean.FALSE);
+				return false;
+			}
+		}
+		return good.booleanValue();
+	}
+	
+	/*
 	 * Resolve the given perProjectInfo's raw classpath and store the resolved classpath in the perProjectInfo.
 	 */
 	public void resolveClasspath(PerProjectInfo perProjectInfo, boolean usePreviousSession, boolean addClasspathChange) throws JavaModelException {