update jdt.core to I20141118-0830 for 4.5 M4
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index 4bde9b1..c0ded89 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -16,7 +16,7 @@
  org.eclipse.jdt.core.tests.util
 Require-Bundle: org.junit;bundle-version="3.8.1",
  org.eclipse.jdt.debug;bundle-version="[3.2.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.10.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.test.performance;bundle-version="[3.10.0,4.0.0)",
  org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 78e361e..f0968d9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -77,155 +77,6 @@
 
 public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
 
-	// for compiling against JRE 8:
-	static final boolean IS_JRE_8;
-	static final String COMPARATOR_IMPL_JRE8;
-	static final String COMPARATOR_RAW_IMPL_JRE8;
-	static final String COLLECTION_IMPL_JRE8;
-	static final String COLLECTION_RAW_IMPL_JRE8;
-	static final String LIST_IMPL_JRE8;
-	static final String COLLECTION_AND_LIST_IMPL_JRE8;
-	static final String COLLECTION_AND_LIST_RAW_IMPL_JRE8;
-	static final String LIST_RAW_IMPL_JRE8;
-	static final String ITERABLE_IMPL_JRE8;
-	static final String ITERABLE_RAW_IMPL_JRE8;
-	static final String ITERATOR_IMPL_JRE8;
-	static final String ITERATOR_RAW_IMPL_JRE8;
-	static final String MAP_IMPL_JRE8;
-	static final String MAP_RAW_IMPL_JRE8;
-			
-	static {
-		String javaVersion = System.getProperty("java.specification.version");
-		IS_JRE_8 = "1.8".equals(javaVersion);
-		if (IS_JRE_8) { // TODO(stephan) accommodate future versions ...
-			COMPARATOR_IMPL_JRE8 = // replace '*' with T, '%' with U, $ with S
-				"	public java.util.Comparator<*> reverseOrder() { return null;}\n" +
-				"	public java.util.Comparator<*> reversed() { return null;}\n" +
-				"	public java.util.Comparator<*> thenComparing(java.util.Comparator<? super *> other) { return null;}\n" +
-				"	public <%> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor, java.util.Comparator<? super %> keyComparator) { return null;}\n" +
-				"	public <% extends java.lang.Comparable<? super %>> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator<*> thenComparingInt(java.util.function.ToIntFunction<? super *> keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator<*> thenComparingLong(java.util.function.ToLongFunction<? super *> keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator<*> thenComparingDouble(java.util.function.ToDoubleFunction<? super *> keyExtractor) { return null;}\n";
-			COMPARATOR_RAW_IMPL_JRE8 =
-				"	public java.util.Comparator reverseOrder() { return null;}\n" +
-				"	public java.util.Comparator reversed() { return null;}\n" +
-				"	public java.util.Comparator thenComparing(java.util.Comparator other) { return null;}\n" +
-				"	public java.util.Comparator thenComparing(java.util.function.Function keyExtractor, java.util.Comparator keyComparator) { return null;}\n" +
-				"	public java.util.Comparator thenComparing(java.util.function.Function keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator thenComparingInt(java.util.function.ToIntFunction keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator thenComparingLong(java.util.function.ToLongFunction keyExtractor) { return null;}\n" +
-				"	public java.util.Comparator thenComparingDouble(java.util.function.ToDoubleFunction keyExtractor) { return null;}\n";
-			COLLECTION_IMPL_JRE8 =
-				"	public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
-				"	public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
-				"	public java.util.stream.Stream<*> stream() { return null;}\n" +
-				"	public java.util.stream.Stream<*> parallelStream() { return null;}\n";
-			COLLECTION_AND_LIST_IMPL_JRE8 =
-				"	public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
-				"	public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
-				"	public java.util.stream.Stream<*> stream() { return null;}\n" +
-				"	public java.util.stream.Stream<*> parallelStream() { return null;}\n" +
-				"	public void sort(java.util.Comparator<? super *> comparator) {}\n" +
-				"	public void parallelSort(java.util.Comparator<? super *> comparator) {}\n" +
-				"	public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\n";
-			COLLECTION_RAW_IMPL_JRE8 =
-				"	public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n";
-			LIST_IMPL_JRE8 = // replace '*' with your concrete type argument
-				"	public void sort(java.util.Comparator<? super *> comparator) {}\n" +
-				"	public void parallelSort(java.util.Comparator<? super *> comparator) {}\n" +
-				"	public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\n";
-			LIST_RAW_IMPL_JRE8 =
-				"	public @SuppressWarnings(\"rawtypes\") void sort(java.util.Comparator comparator) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\n";
-			COLLECTION_AND_LIST_RAW_IMPL_JRE8 =
-				"	public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void sort(java.util.Comparator comparator) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\n";
-			ITERABLE_IMPL_JRE8 = // replace '*' with your concrete type argument
-				"	public void forEach(java.util.function.Consumer<? super *> block){}\n" +
-				"	public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n" +
-				"	public java.util.Spliterator<*> spliterator() {return null;}\n";
-			ITERABLE_RAW_IMPL_JRE8 =
-				"	public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer action) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") java.util.Spliterator spliterator() {return null;}\n";
-			ITERATOR_IMPL_JRE8 = // replace '*' with your concrete type argument
-					"public void forEach(java.util.function.Consumer<? super *> action) {}\n" +
-					"public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n";
-			ITERATOR_RAW_IMPL_JRE8 =
-				"	public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer block) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n";
-			MAP_IMPL_JRE8 = // '*' for 'K', '%' for 'V'
-				"	public boolean remove(Object key, Object value) { return false;}\n" +
-				"	public % getOrDefault(Object key, % defaultValue) {return defaultValue;}\n" +
-				"	public void forEach(java.util.function.BiConsumer<? super *, ? super %> block) {}\n" +
-				"	public void replaceAll(java.util.function.BiFunction<? super *, ? super %, ? extends %> function) {}\n" +
-				"	public % putIfAbsent(* key, % value) { return null;}\n" +
-				"	public boolean replace(* key, % oldValue, % newValue) { return false;}\n" +
-				"	public % replace(* key, % value) { return null;}\n" +
-				"	public % computeIfAbsent(* key, java.util.function.Function<? super *, ? extends %> mappingFunction) { return null;}\n" +
-				"	public % computeIfPresent(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" +
-				"	public % compute(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" +
-				"	public % merge(* key, % value, java.util.function.BiFunction<? super %, ? super %, ? extends %> remappingFunction) { return null;}\n";
-			MAP_RAW_IMPL_JRE8 =
-				"	public boolean remove(Object key, Object value) { return false;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") Object getOrDefault(Object key, Object defaultValue) { return defaultValue;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.BiConsumer block) {}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.BiFunction function) {}\n" +
-				"	public Object putIfAbsent(Object key, Object value) { return null;}\n" +
-				"	public boolean replace(Object key, Object oldValue, Object newValue) { return false;}\n" +
-				"	public Object replace(Object key, Object value) { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") Object computeIfAbsent(Object key, java.util.function.Function mappingFunction) { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") Object computeIfPresent(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") Object compute(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" +
-				"	public @SuppressWarnings(\"rawtypes\") Object merge(Object key, Object value, java.util.function.BiFunction remappingFunction) { return null;}\n";
-		} else {
-			COMPARATOR_IMPL_JRE8 = "";			
-			COMPARATOR_RAW_IMPL_JRE8 = "";
-			COLLECTION_IMPL_JRE8 = "";
-			COLLECTION_RAW_IMPL_JRE8 = "";
-			LIST_IMPL_JRE8 = "";
-			COLLECTION_AND_LIST_IMPL_JRE8 = "";
-			COLLECTION_AND_LIST_RAW_IMPL_JRE8 = "";
-			LIST_RAW_IMPL_JRE8 = "";
-			ITERABLE_IMPL_JRE8 = "";
-			ITERABLE_RAW_IMPL_JRE8 = "";
-			ITERATOR_IMPL_JRE8 = "\n\n";
-			ITERATOR_RAW_IMPL_JRE8 = "\n\n";
-			MAP_IMPL_JRE8 = "";
-			MAP_RAW_IMPL_JRE8 = "";
-		}
-	}
-	String getCollectionAndListRawImplJRE8() {
-		if (this.complianceLevel < ClassFileConstants.JDK1_5)
-			return COLLECTION_AND_LIST_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
-		return COLLECTION_AND_LIST_RAW_IMPL_JRE8;
-	} 
-	String getListRawImplJRE8() {
-		if (this.complianceLevel < ClassFileConstants.JDK1_5)
-			return LIST_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
-		return LIST_RAW_IMPL_JRE8;
-	}
-	String getIterableRawImplJRE8() {
-		if (this.complianceLevel < ClassFileConstants.JDK1_5)
-			return ITERABLE_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
-		return ITERABLE_RAW_IMPL_JRE8;
-	}
-	String getCollectionRawImplJRE8() {
-		if (this.complianceLevel < ClassFileConstants.JDK1_5)
-			return COLLECTION_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
-		return COLLECTION_RAW_IMPL_JRE8;
-	}
-
 	// javac comparison related types, fields and methods - see runJavac for
 	// details
 static class JavacCompiler {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java
index b9fa2c9..306c158 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java
@@ -515,7 +515,7 @@
 						"}\n" +
 						"interface OrderedSet<E> extends List<E>, Set<E> { boolean add(E o); }\n"
 		};
-		if (!IS_JRE_8 || this.complianceLevel < ClassFileConstants.JDK1_8)
+		if (this.complianceLevel < ClassFileConstants.JDK1_8)
 			this.runConformTest(testFiles, "");
 		else
 			this.runNegativeTest(
@@ -539,7 +539,7 @@
 	}
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=123943 variant to make it pass on JRE8
 	public void test009a() {
-		if (!IS_JRE_8 || this.complianceLevel < ClassFileConstants.JDK1_8)
+		if (this.complianceLevel < ClassFileConstants.JDK1_8)
 			return;
 		this.runConformTest(
 			new String[] {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index c07af4e..444f2b8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Benjamin Muskalla - Contribution for bug 239066
@@ -1710,29 +1710,29 @@
         "{0} {1}\n" +
         "{2}\n" +
         " \n" +
-        " Warning options:\n" +
-        "    -deprecation     + deprecation outside deprecated code\n" +
-        "    -nowarn -warn:none disable all warnings\n" +
+        " Warning options:\n" + 
+        "    -deprecation         + deprecation outside deprecated code\n" + 
+        "    -nowarn -warn:none disable all warnings\n" + 
         "    -nowarn:[<directories separated by " + File.pathSeparator+ ">]\n" +
         "                       specify directories from which optional problems should\n" +
         "                       be ignored\n" +
-        "    -warn:<warnings separated by ,>    enable exactly the listed warnings\n" +
-        "    -warn:+<warnings separated by ,>   enable additional warnings\n" +
-        "    -warn:-<warnings separated by ,>   disable specific warnings\n" +
+        "    -warn:<warnings separated by ,>    enable exactly the listed warnings\n" + 
+        "    -warn:+<warnings separated by ,>   enable additional warnings\n" + 
+        "    -warn:-<warnings separated by ,>   disable specific warnings\n" + 
 //{ObjectTeams: new options (marked individually as //OT: )
 //OT (2x):
         "      abstractrelevantrole + abstract relevant role (OTJLD 2.5(b))\n" +
         "      adaptDeprecated    + adapting a deprecated type/method\n" +
         "      all                  enable all warnings\n" + 
-        "      allDeadCode          dead code including trivial if(DEBUG) check\n" +
-        "      allDeprecation       deprecation including inside deprecated code\n" +
-        "      allJavadoc           invalid or missing javadoc\n" +
-        "      allOver-ann          all missing @Override annotations\n" +
-        "      all-static-method    all method can be declared as static warnings\n" +
+        "      allDeadCode          dead code including trivial if(DEBUG) check\n" + 
+        "      allDeprecation       deprecation including inside deprecated code\n" + 
+        "      allJavadoc           invalid or missing javadoc\n" + 
+        "      allOver-ann          all missing @Override annotations\n" + 
+        "      all-static-method    all method can be declared as static warnings\n" + 
 //OT (2x):
         "      ambiguousbinding   + ambiguous role-base bindings (OTJLD 2.3.4(a))\n" + 
         "      ambiguouslowering  + ambiguous lowering or upcast (OTJLD 2.2(f))\n" +
-        "      assertIdentifier   + ''assert'' used as identifier\n" +
+        "      assertIdentifier   + ''assert'' used as identifier\n" + 
 //OT:
         "      basecall           + base call not issued exactly once on each path\n" +
         "                           (OTJLD 4.3(b,c))\n" +
@@ -1743,32 +1743,32 @@
         "                           (OTJLD 2.1.2(d))\n" +
 //OT:
         "      bindingtosystemclass 	+ trying to bind a role to a system class\n" +
-        "      boxing               autoboxing conversion\n" +
-        "      charConcat         + char[] in String concat\n" +
-        "      compareIdentical   + comparing identical expressions\n" +
-        "      conditionAssign      possible accidental boolean assignment\n" +
-        "      constructorName    + method with constructor name\n" +
+        "      boxing               autoboxing conversion\n" + 
+        "      charConcat         + char[] in String concat\n" + 
+        "      compareIdentical   + comparing identical expressions\n" + 
+        "      conditionAssign      possible accidental boolean assignment\n" + 
+        "      constructorName    + method with constructor name\n" + 
 //OT:
         "      dangerouscallin    + dangerous callin binding (hashCode or equals)\n" +
-        "      deadCode           + dead code excluding trivial if (DEBUG) check\n" +
+        "      deadCode           + dead code excluding trivial if (DEBUG) check\n" + 
 //OT:
         "      decapsulation      + overriding access restrictions of a base class\n" +
         "                           (OTJLD 3.4)\n" +
-        "      dep-ann              missing @Deprecated annotation\n" +
-        "      deprecation        + deprecation outside deprecated code\n" +
-        "      discouraged        + use of types matching a discouraged access rule\n" +
-        "      emptyBlock           undocumented empty block\n" +
+        "      dep-ann              missing @Deprecated annotation\n" + 
+        "      deprecation        + deprecation outside deprecated code\n" + 
+        "      discouraged        + use of types matching a discouraged access rule\n" + 
+        "      emptyBlock           undocumented empty block\n" + 
         "      enumIdentifier       ''enum'' used as identifier\n" + 
         "      enumSwitch           incomplete enum switch\n" + 
         "      enumSwitchPedantic + report missing enum switch cases even\n" + 
         "                           in the presence of a default case\n" + 
 //OT:
         "      exceptioninguard   + guard predicate throwing checked exception\n" +
-        "      fallthrough          possible fall-through case\n" +
-        "      fieldHiding          field hiding another variable\n" +
-        "      finalBound           type parameter with final bound\n" +
-        "      finally            + finally block not completing normally\n" +
-        "      forbidden          + use of types matching a forbidden access rule\n" +
+        "      fallthrough          possible fall-through case\n" + 
+        "      fieldHiding          field hiding another variable\n" + 
+        "      finalBound           type parameter with final bound\n" + 
+        "      finally            + finally block not completing normally\n" + 
+        "      forbidden          + use of types matching a forbidden access rule\n" + 
 //OT:
         "      fragilecallin      + replace callin not providing expected result\n" +
         "                           (OTJLD 4.3(e))\n" + 
@@ -1776,16 +1776,16 @@
 //OT:
 		"      hiddenLiftingProblem + a lifting that is not directly visible in source\n" + 
 		"                             code could fail at runtime (OTJLD 2.3.5)\n" +
-        "      hiding               macro for fieldHiding, localHiding, typeHiding and\n" +
-        "                           maskedCatchBlock\n" +
+        "      hiding               macro for fieldHiding, localHiding, typeHiding and\n" + 
+        "                           maskedCatchBlock\n" + 
         "      includeAssertNull    raise null warnings for variables\n" + 
         "                           that got tainted in an assert expression\n" + 
         "      indirectStatic       indirect reference to static member\n" +
 //OT:
         "      inferredcallout    + a callout binding has to be inferred (OTJLD 3.1(j))\n" +
         "      inheritNullAnnot     inherit null annotations\n" + 
-        "      intfAnnotation     + annotation type used as super interface\n" +
-        "      intfNonInherited   + interface non-inherited method compatibility\n" +
+        "      intfAnnotation     + annotation type used as super interface\n" + 
+        "      intfNonInherited   + interface non-inherited method compatibility\n" + 
         "      intfRedundant        find redundant superinterfaces\n" + 
         "      invalidJavadoc       all warnings for malformed javadoc tags\n" + 
         "      invalidJavadocTag    validate javadoc tag arguments\n" + 
@@ -1794,9 +1794,9 @@
         "							tag args\n" + 
         "      invalidJavadocVisibility(<visibility>)  specify visibility modifier\n" + 
         "							for malformed javadoc tag warnings\n" + 
-        "      javadoc              invalid javadoc\n" +
-        "      localHiding          local variable hiding another variable\n" +
-        "      maskedCatchBlock   + hidden catch block\n" +
+        "      javadoc              invalid javadoc\n" + 
+        "      localHiding          local variable hiding another variable\n" + 
+        "      maskedCatchBlock   + hidden catch block\n" + 
         "      missingJavadocTags   missing Javadoc tags\n" + 
         "      missingJavadocTagsOverriding missing Javadoc tags in overriding methods\n" + 
         "      missingJavadocTagsMethod missing Javadoc tags for method type parameter\n" + 
@@ -1807,12 +1807,12 @@
         "							methods\n" + 
         "      missingJavadocCommentsVisibility(<visibility>)  specify visibility\n" + 
         "							modifier for missing javadoc comments warnings\n" + 
-        "      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n" +
-        "      noEffectAssign     + assignment without effect\n" +
-        "      null                 potential missing or redundant null check\n" +
-        "      nullAnnot(<annot. names separated by |>)   annotation based null analysis,\n" +
-        "                           nullable|nonnull|nonnullbydefault annotation types\n" +
-        "                           optionally specified using fully qualified names.\n" +
+        "      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n" + 
+        "      noEffectAssign     + assignment without effect\n" + 
+        "      null                 potential missing or redundant null check\n" + 
+        "      nullAnnot(<annot. names separated by |>)   annotation based null analysis,\n" + 
+        "                           nullable|nonnull|nonnullbydefault annotation types\n" + 
+        "                           optionally specified using fully qualified names.\n" + 
         "							Enabling this option enables all null-annotation\n" + 
         "							related sub-options. These can be individually\n" + 
         "							controlled using options listed below.\n" + 
@@ -1828,7 +1828,7 @@
         "      over-ann             missing @Override annotation (superclass)\n" + 
         "      paramAssign          assignment to a parameter\n" + 
         "      pkgDefaultMethod   + attempt to override package-default method\n" + 
-        "      raw                + usage of raw type\n" +
+        "      raw                + usage of raw type\n" + 
         "      resource           + (pot.) unsafe usage of resource of type Closeable\n" + 
 //OT:
         "      roleinstantiation  + unsafe instantiation of a role\n" +
@@ -1836,50 +1836,52 @@
 //OT:
         "      roletypesyntax     + old style syntax for role types (dependent types)\n" +
         "                           (OTJLD 1.2.2(b))\n" +
-        "      semicolon            unnecessary semicolon, empty statement\n" +
-        "      serial             + missing serialVersionUID\n" +
-        "      specialParamHiding   constructor or setter parameter hiding a field\n" +
+        "      semicolon            unnecessary semicolon, empty statement\n" + 
+        "      serial             + missing serialVersionUID\n" + 
+        "      specialParamHiding   constructor or setter parameter hiding a field\n" + 
         "      static-method        method can be declared as static\n" + 
-        "      static-access        macro for indirectStatic and staticReceiver\n" +
-        "      staticReceiver     + non-static reference to static member\n" +
-        "      super                overriding a method without making a super invocation\n" +
+        "      static-access        macro for indirectStatic and staticReceiver\n" + 
+        "      staticReceiver     + non-static reference to static member\n" + 
+        "      super                overriding a method without making a super invocation\n" + 
         "      suppress           + enable @SuppressWarnings\n" + 
         "                           When used with -err:, it can also silent optional\n" + 
         "                           errors and warnings\n" + 
         "      switchDefault      + switch statement lacking a default case\n" + 
-        "      syncOverride         missing synchronized in synchr. method override\n" +
-        "      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" +
+        "      syncOverride         missing synchronized in synchr. method override\n" + 
+        "      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" +
-        "      unused               macro for unusedAllocation, unusedArgument,\n" +
-        "                               unusedImport, unusedLabel, unusedLocal,\n" +
-        "                               unusedPrivate, unusedThrown, and unusedTypeArgs\n" +
-        "      unusedAllocation     allocating an object that is not used\n" +
+        "      unchecked          + unchecked type operation\n" + 
+        "      unnecessaryElse      unnecessary else clause\n" + 
+        "      unqualifiedField     unqualified reference to field\n" + 
+        "      unused               macro for unusedAllocation, unusedArgument,\n" + 
+        "                               unusedImport, unusedLabel, unusedLocal,\n" + 
+        "                               unusedPrivate, unusedThrown, and unusedTypeArgs,\n" + 
+        "								unusedExceptionParam\n"+
+        "      unusedAllocation     allocating an object that is not used\n" + 
         "      unusedArgument       unread method parameter\n" +
-        "      unusedImport       + unused import declaration\n" +
-        "      unusedLabel        + unused label\n" +
-        "      unusedLocal        + unread local variable\n" +
+        "      unusedExceptionParam unread exception parameter\n" + 
+        "      unusedImport       + unused import declaration\n" + 
+        "      unusedLabel        + unused label\n" + 
+        "      unusedLocal        + unread local variable\n" + 
         "      unusedParam		    unused parameter\n" + 
         "      unusedParamOverriding unused parameter for overriding method\n" + 
         "      unusedParamImplementing unused parameter for implementing method\n" + 
         "      unusedParamIncludeDoc unused parameter documented in comment tag\n" + 
-        "      unusedPrivate      + unused private member declaration\n" +
-        "      unusedThrown         unused declared thrown exception\n" +
+        "      unusedPrivate      + unused private member declaration\n" + 
+        "      unusedThrown         unused declared thrown exception\n" + 
         "      unusedThrownWhenOverriding unused declared thrown exception in \n" + 
         "							overriding method\n" + 
         "      unusedThrownIncludeDocComment     unused declared thrown exception,\n" + 
         "							documented in a comment tag\n" + 
         "      unusedThrownExemptExceptionThrowable  unused declared thrown exception,\n" + 
         "							exempt Exception and Throwable\n" + 
-        "      unusedTypeArgs     + unused type arguments for method and constructor\n" +
-        "      uselessTypeCheck     unnecessary cast/instanceof operation\n" +
-        "      varargsCast        + varargs argument need explicit cast\n" +
-        "      warningToken       + unsupported or unnecessary @SuppressWarnings\n" +
+        "      unusedTypeArgs     + unused type arguments for method and constructor\n" + 
+        "      uselessTypeCheck     unnecessary cast/instanceof operation\n" + 
+        "      varargsCast        + varargs argument need explicit cast\n" + 
+        "      warningToken       + unsupported or unnecessary @SuppressWarnings\n" + 
 // SH}
         "\n";
 	String expandedExpectedOutput =
@@ -1927,34 +1929,34 @@
 				true);
 		String logContents = Util.fileContent(logFileName);
 		String expectedLogContents =
-			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
-			"<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.004 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_004.dtd\">\n" +
-			"<compiler copyright=\"{2}\" name=\"{1}\" version=\"{3}\">\n" +
-			"	<command_line>\n" +
-			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---{0}X.java\"/>\n" +
-			"		<argument value=\"-1.5\"/>\n" +
-			"		<argument value=\"-proceedOnError\"/>\n" +
-			"		<argument value=\"-log\"/>\n" +
-			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---{0}log.xml\"/>\n" +
-			"		<argument value=\"-d\"/>\n" +
-			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\n" +
-			"	</command_line>\n" +
-			"	<options>\n" +
+			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
+			"<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.004 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_004.dtd\">\n" + 
+			"<compiler copyright=\"{2}\" name=\"{1}\" version=\"{3}\">\n" + 
+			"	<command_line>\n" + 
+			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---{0}X.java\"/>\n" + 
+			"		<argument value=\"-1.5\"/>\n" + 
+			"		<argument value=\"-proceedOnError\"/>\n" + 
+			"		<argument value=\"-log\"/>\n" + 
+			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---{0}log.xml\"/>\n" + 
+			"		<argument value=\"-d\"/>\n" + 
+			"		<argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\n" + 
+			"	</command_line>\n" + 
+			"	<options>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations\" value=\"disabled\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation\" value=\"ignore\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nonnull\" value=\"org.eclipse.jdt.annotation.NonNull\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault\" value=\"org.eclipse.jdt.annotation.NonNullByDefault\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nullable\" value=\"org.eclipse.jdt.annotation.Nullable\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nullanalysis\" value=\"disabled\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nonnull\" value=\"org.eclipse.jdt.annotation.NonNull\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault\" value=\"org.eclipse.jdt.annotation.NonNullByDefault\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nullable\" value=\"org.eclipse.jdt.annotation.Nullable\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.annotation.nullanalysis\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.lambda.genericSignature\" value=\"do not generate\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.methodParameters\" value=\"do not generate\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.shareCommonFinallyBlocks\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.5\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.debug.lineNumber\" value=\"generate\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.debug.localVariable\" value=\"do not generate\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.5\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.debug.lineNumber\" value=\"generate\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.debug.localVariable\" value=\"do not generate\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.debug.sourceFile\" value=\"generate\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.doc.comment.support\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.emulateJavacBug8031744\" value=\"enabled\"/>\n" +
@@ -1963,75 +1965,75 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.comparingIdentical\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deadCode\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecation\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.comparingIdentical\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deadCode\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecation\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finalParameterBound\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.forbiddenReference\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finalParameterBound\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.forbiddenReference\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts\" value=\"disabled\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.indirectStaticAccess\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadoc\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTags\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility\" value=\"public\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.localVariableHiding\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.indirectStaticAccess\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadoc\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTags\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility\" value=\"public\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.localVariableHiding\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingDefaultCase\" value=\"ignore\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation\" value=\"ignore\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocComments\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility\" value=\"public\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription\" value=\"return_tag\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTags\" value=\"ignore\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocComments\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility\" value=\"public\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription\" value=\"return_tag\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTags\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters\" value=\"disabled\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility\" value=\"public\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation\" value=\"enabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSerialVersion\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility\" value=\"public\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation\" value=\"enabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSerialVersion\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped\" value=\"warning\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict\" value=\"error\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullSpecViolation\" value=\"error\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullSpecViolation\" value=\"error\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic\" value=\"ignore\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressWarnings\" value=\"enabled\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressWarnings\" value=\"enabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields\" value=\"disabled\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.tasks\" value=\"warning\"/>\n" + 
@@ -2042,32 +2044,33 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.uninternedIdentityComparison\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable\" value=\"enabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference\" value=\"enabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedImport\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLabel\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLocal\" value=\"warning\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameter\" value=\"ignore\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference\" value=\"enabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedPrivateMember\" value=\"warning\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable\" value=\"enabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference\" value=\"enabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter\" value=\"ignore\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedImport\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLabel\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedLocal\" value=\"warning\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameter\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference\" value=\"enabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete\" value=\"disabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedPrivateMember\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedTypeArgumentsForMethodInvocation\" value=\"warning\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedTypeParameter\" value=\"ignore\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.unusedWarningToken\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast\" value=\"warning\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.processAnnotations\" value=\"disabled\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.processAnnotations\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.source\" value=\"1.5\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.storeAnnotations\" value=\"disabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.taskCaseSensitive\" value=\"enabled\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.taskPriorities\" value=\"\"/>\n" +
-			"		<option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\n" +
+			"		<option key=\"org.eclipse.jdt.core.compiler.taskCaseSensitive\" value=\"enabled\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.taskPriorities\" value=\"\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\n" + 
 //{ObjectTeams: new options
             "		<option key=\"org.eclipse.objectteams.otdt.compiler.option.pure_java\" value=\"disabled\"/>\n" +
             "		<option key=\"org.eclipse.objectteams.otdt.compiler.option.scoped_keywords\" value=\"enabled\"/>\n" + 
@@ -2095,25 +2098,25 @@
 			"		<option key=\"org.eclipse.objectteams.otdt.compiler.problem.weave_into_system_class\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.objectteams.otdt.core.compiler.problem.decapsulation\" value=\"report binding\"/>\n" + 
 // SH}
-			"	</options>\n" +
-			"	<classpaths>NORMALIZED SECTION</classpaths>\n" +
-			"	<sources>\n" +
-			"		<source output=\"---OUTPUT_DIR_PLACEHOLDER---\" path=\"---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\">\n" +
-			"			<problems errors=\"1\" problems=\"1\" warnings=\"0\">\n" +
-			"				<problem categoryID=\"40\" charEnd=\"28\" charStart=\"25\" id=\"UndefinedType\" line=\"3\" problemID=\"16777218\" severity=\"ERROR\">\n" +
-			"					<message value=\"Zork cannot be resolved to a type\"/>\n" +
-			"					<source_context sourceEnd=\"3\" sourceStart=\"0\" value=\"Zork z;\"/>\n" +
-			"					<arguments>\n" +
-			"						<argument value=\"Zork\"/>\n" +
-			"					</arguments>\n" +
-			"				</problem>\n" +
-			"			</problems>\n" +
-			"			<classfile path=\"---OUTPUT_DIR_PLACEHOLDER---{0}X.class\"/>\n" +
-			"		</source>\n" +
-			"	</sources>\n" +
-			"	<stats>\n" +
-			"		<problem_summary errors=\"1\" problems=\"1\" tasks=\"0\" warnings=\"0\"/>\n" +
-			"	</stats>\n" +
+			"	</options>\n" + 
+			"	<classpaths>NORMALIZED SECTION</classpaths>\n" + 
+			"	<sources>\n" + 
+			"		<source output=\"---OUTPUT_DIR_PLACEHOLDER---\" path=\"---OUTPUT_DIR_PLACEHOLDER---" + File.separator + "X.java\">\n" + 
+			"			<problems errors=\"1\" problems=\"1\" warnings=\"0\">\n" + 
+			"				<problem categoryID=\"40\" charEnd=\"28\" charStart=\"25\" id=\"UndefinedType\" line=\"3\" problemID=\"16777218\" severity=\"ERROR\">\n" + 
+			"					<message value=\"Zork cannot be resolved to a type\"/>\n" + 
+			"					<source_context sourceEnd=\"3\" sourceStart=\"0\" value=\"Zork z;\"/>\n" + 
+			"					<arguments>\n" + 
+			"						<argument value=\"Zork\"/>\n" + 
+			"					</arguments>\n" + 
+			"				</problem>\n" + 
+			"			</problems>\n" + 
+			"			<classfile path=\"---OUTPUT_DIR_PLACEHOLDER---{0}X.class\"/>\n" + 
+			"		</source>\n" + 
+			"	</sources>\n" + 
+			"	<stats>\n" + 
+			"		<problem_summary errors=\"1\" problems=\"1\" tasks=\"0\" warnings=\"0\"/>\n" + 
+			"	</stats>\n" + 
 			"</compiler>\n";
 		String normalizedExpectedLogContents =
 				MessageFormat.format(
@@ -14120,4 +14123,39 @@
 		new File(lib1Path).delete();
 	}
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=439750
+public void test439750() {
+	this.runConformTest(
+		new String[] {
+			"externalizable/warning/X.java",
+			"import java.io.FileInputStream;\n" +
+			"import java.io.IOException;\n" +
+			"class X {\n" +
+			"	public static void main(String[] args) {\n" +
+			"		FileInputStream fis = null;\n" +
+			"		try {\n" +
+			"			fis = new FileInputStream(\"xyz\");\n" +
+			"			System.out.println(\"fis\");\n" +
+			"		} catch (IOException e) {\n" +
+			"			e.printStackTrace();\n" +
+			"		} finally {\n" +
+			"			try {\n" +
+			"				if (fis != null) fis.close();\n" +
+			"			} catch (Exception e) {}\n" +
+ 			"		}\n" +
+ 			"	}\n" +
+			"}\n"
+			},
+			"\"" + OUTPUT_DIR +  File.separator + "externalizable" + File.separator + "warning" + File.separator + "X.java\""
+			+ " -1.6 -warn:unused -warn:unusedExceptionParam -d none",
+			"",
+			"----------\n" +
+			"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/externalizable/warning/X.java (at line 14)\n" +
+			"	} catch (Exception e) {}\n" +
+			"	                   ^\n" +
+			"The value of the exception parameter e is not used\n" +
+			"----------\n" +
+			"1 problem (1 warning)\n",
+			true);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index 044e7a0..27e2a38 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -36,6 +36,7 @@
  *								Bug 430150 - [1.8][null] stricter checking against type variables
  *								Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
  *								Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *     Jesper S Moller - Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -436,9 +437,10 @@
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasShorterRetention", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasWrongValueType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("ContainerAnnotationTypeMustHaveValue", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
-		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferredFunctionType", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
 		expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT));
 		expectedProblemAttributes.put("ConflictingNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -1352,9 +1354,10 @@
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasShorterRetention", SKIP);
 		expectedProblemAttributes.put("ContainerAnnotationTypeHasWrongValueType", SKIP);
 		expectedProblemAttributes.put("ContainerAnnotationTypeMustHaveValue", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotations", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", SKIP);
-		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", SKIP);
+		expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsOnBound", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferred", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+		expectedProblemAttributes.put("ContradictoryNullAnnotationsInferredFunctionType", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
 		expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST));
 		expectedProblemAttributes.put("CorruptedSignature", SKIP);
 		expectedProblemAttributes.put("DanglingReference", SKIP);
@@ -1403,7 +1406,7 @@
 		expectedProblemAttributes.put("EnumConstantsCannotBeSurroundedByParenthesis", SKIP);
 		expectedProblemAttributes.put("EnumStaticFieldInInInitializerContext", SKIP);
 		expectedProblemAttributes.put("EnumSwitchCannotTargetField", SKIP);
-		expectedProblemAttributes.put("ExceptionParameterIsNeverUsed", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_PARAMETER));
+		expectedProblemAttributes.put("ExceptionParameterIsNeverUsed", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_EXCEPTION_PARAMETER));
 		expectedProblemAttributes.put("ExceptionTypeAmbiguous", SKIP);
 		expectedProblemAttributes.put("ExceptionTypeInheritedNameHidesEnclosingName", SKIP);
 		expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
index afafc76..0400ac5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
@@ -1106,7 +1106,6 @@
 				"   public Iterator<String> iterator() {\n" +
 				"        return null;\n" +
 				"    }\n" +
-				ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
 				"}\n",
 			},
 			"----------\n" +
@@ -1629,13 +1628,11 @@
 			"	}\n" +
 			"	public void remove() {\n" +
 			"	}\n" +
-			ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") +
 			"}\n" +
 			"class Bar implements Iterable<String> {\n" +
 			"	public Iterator<String> iterator() {\n" +
 			"		return new ArrayIterator<String>(new String[]{\"a\",\"b\"});\n" +
 			"	}\n" +
-			ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
 			"}\n",
 		},
 		"ab");
@@ -1724,7 +1721,6 @@
 			"	}\n" +
 			"	public void remove() {\n" +
 			"	}\n" +
-			ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") +
 			"}\n" +
 			"interface IFoo extends Iterable<String> {\n" +
 			"}\n" +
@@ -1732,7 +1728,6 @@
 			"	public Iterator<String> iterator() {\n" +
 			"		return new ArrayIterator<String>(new String[]{\"a\",\"b\"});\n" +
 			"	}\n" +
-			ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
 			"}\n",
 		},
 		"ab");
@@ -1808,7 +1803,6 @@
 			"		X x = new X();\n" +
 			"		x.foo(x);\n" +
 			"	}\n" +
-			ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
 			"}",
 		},
 		"ab");
@@ -2023,7 +2017,6 @@
 			"				System.out.println(\"remove\");\n" +
 			"				this.iterator.remove();\n" +
 			"			}\n" +
-			ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") +
 			"		}\n" +
 			"		\n" +
 			"        static Set<Object> initForEach()        {\n" +
@@ -2120,7 +2113,6 @@
 			"				System.out.println(\"remove\");\n" +
 			"				this.iterator.remove();\n" +
 			"			}\n" +
-			ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") +
 			"		}\n" +
 			"		\n" +
 			"        static Set<Object> initForEach()        {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 06ad0a6..fad775e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -4463,8 +4463,6 @@
 				"    }\n" +
 				"    public int size() { return 0; }\n" +
 				"    public Object get(int index) { return null; }\n" +
-				ITERABLE_RAW_IMPL_JRE8 +
-				COLLECTION_AND_LIST_RAW_IMPL_JRE8 +
 				"}\n"
 			},
 			"SUCCESS");
@@ -6196,7 +6194,6 @@
 				"    public int compare(X x1, X x2) {\n" +
 				"        return comparator.compare(function.eval(x1),function.eval(x2));\n" +
 				"    }\n" +
-				COMPARATOR_RAW_IMPL_JRE8 +
 				"}\n",
 			},
 			"");
@@ -8897,7 +8894,6 @@
 				"   public Set<Map.Entry<String, V>> entrySet() {\n" +
 				"      return this.backingMap.entrySet();\n" +
 				"   }\n" +
-				MAP_IMPL_JRE8.replaceAll("\\*", "String").replaceAll("\\%", "V")+
 				"}\n",
 			},
 			"----------\n" +
@@ -10857,12 +10853,9 @@
 					"			public boolean hasNext() {return false;}\n" +
 					"			public Entry<String, Integer> next() {return null;}\n" +
 					"			public void remove() {}	\n" +
-					ITERATOR_IMPL_JRE8.replaceAll("\\*", "Entry<String,Integer>") +
 					"		};\n" +
 					"	}\n" +
 					"	public int size() {return 0;}\n" +
-					COLLECTION_RAW_IMPL_JRE8 +
-					ITERABLE_IMPL_JRE8.replaceAll("\\*", "Entry<String,Integer>") +
 					"}"
 			}
 		);
@@ -11434,8 +11427,6 @@
 				"    }\n" +
 				"    public Iterator<Runnable> iterator() {return null;}\n" +
 				"    public int size() {return 0;}\n" +
-				COLLECTION_RAW_IMPL_JRE8 +
-				ITERABLE_IMPL_JRE8.replaceAll("\\*", "Runnable") +
 				"}"
 				}
 		);
@@ -13615,7 +13606,6 @@
 				"    public boolean hasNext() { return false; }\n" +
 				"    public String next() { return null; }\n" +
 				"    public void remove() {}\n" +
-				ITERATOR_IMPL_JRE8.replaceAll("\\*", "String") +
 				"}\n",
 			},
 			"");
@@ -20051,7 +20041,6 @@
 				"			}\n" +
 				"			public void remove() {\n" +
 				"			}\n" +
-				ITERATOR_IMPL_JRE8.replaceAll("\\*", "U") +
 				"		}\n" +
 				"	}\n" +
 				"}\n",
@@ -25089,8 +25078,6 @@
 			"			List<String> list = new AbstractList<String>() {\n" +
 			"				@Override public int size() { return 0; }\n" +
 			"				@Override public String get(int i) { return args.get(i); }\n" +
-			COLLECTION_AND_LIST_IMPL_JRE8.replaceAll("\\*", "String") +
-			ITERABLE_IMPL_JRE8.replaceAll("\\*", "String") +
 			"			};\n" +
 			"		}\n" +
 			"	}\n" +
@@ -25102,14 +25089,13 @@
 		},
 		"SUCCESS");
 
-	String constantPoolIdx = IS_JRE_8 ? "73" : "36"; // depends on whether or not stubs for JRE8 default methods are included
 	String expectedOutput =
 		"  // Method descriptor #31 (I)Ljava/lang/Object;\n" +
 		"  // Stack: 2, Locals: 2\n" +
 		"  public bridge synthetic java.lang.Object get(int arg0);\n" +
 		"    0  aload_0 [this]\n" +
 		"    1  iload_1 [arg0]\n" +
-		"    2  invokevirtual X$Entry$1.get(int) : java.lang.String ["+constantPoolIdx+"]\n" +
+		"    2  invokevirtual X$Entry$1.get(int) : java.lang.String [36]\n" +
 		"    5  areturn\n" +
 		"      Line numbers:\n" +
 		"        [pc: 0, line: 1]\n";
@@ -26179,7 +26165,6 @@
 			"	}\n" +
 			"	public void remove() {\n" +
 			"	}\n" +
-			ITERATOR_IMPL_JRE8.replaceAll("\\*", "N") +
 			"}\n" +
 			"interface Set3<N extends Node> extends Iterable<N> {\n" +
 			"	SetIterator<N> iterator();\n" +
@@ -26211,27 +26196,27 @@
 			"}\n",
 		},
 		"----------\n" +
-		"1. WARNING in X.java (at line 23)\n" +
+		"1. WARNING in X.java (at line 21)\n" +
 		"	void f1(Set1 s) {\n" +
 		"	        ^^^^\n" +
 		"Set1 is a raw type. References to generic type Set1<N> should be parameterized\n" +
 		"----------\n" +
-		"2. ERROR in X.java (at line 24)\n" +
+		"2. ERROR in X.java (at line 22)\n" +
 		"	Node n_ = s.iterator().next();\n" +
 		"	          ^^^^^^^^^^^^^^^^^^^\n" +
 		"Type mismatch: cannot convert from Object to Node\n" +
 		"----------\n" +
-		"3. ERROR in X.java (at line 27)\n" +
+		"3. ERROR in X.java (at line 25)\n" +
 		"	for (Node n : s) {\n" +
 		"	              ^\n" +
 		"Type mismatch: cannot convert from element type Object to Node\n" +
 		"----------\n" +
-		"4. WARNING in X.java (at line 37)\n" +
+		"4. WARNING in X.java (at line 35)\n" +
 		"	void f3(Set3 s) {\n" +
 		"	        ^^^^\n" +
 		"Set3 is a raw type. References to generic type Set3<N> should be parameterized\n" +
 		"----------\n" +
-		"5. ERROR in X.java (at line 40)\n" +
+		"5. ERROR in X.java (at line 38)\n" +
 		"	for (Node n : s) {\n" +
 		"	              ^\n" +
 		"Type mismatch: cannot convert from element type Object to Node\n" +
@@ -28420,8 +28405,6 @@
 			"		// TODO Auto-generated method stub\n" +
 			"		\n" +
 			"	}" +
-			COLLECTION_RAW_IMPL_JRE8 +
-			ITERABLE_RAW_IMPL_JRE8 +
 			"}",
 		},
 		"",
@@ -34748,7 +34731,6 @@
 			"		public Iterator<W> iterator() {\n" +
 			"			return theList.iterator();\n" +
 			"		}\n" +
-			ITERABLE_IMPL_JRE8.replace('*', 'W') +
 			"	}\n" +
 			"\n" +
 			"	private PointList<Waypoint> waypoints = new PointList<Waypoint>();\n" +
@@ -35002,7 +34984,6 @@
 			"public int compare(T obj1, T obj2) {\n" +
 			"	return obj1.compareTo(obj2);\n" +
 			"}\n" +
-			COMPARATOR_IMPL_JRE8.replace('*', 'T').replace('%', 'U').replace('$', 'S') +
 			"}\n" +
 			"\n" +
 			"@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n" +
@@ -35053,7 +35034,6 @@
 			"public int compare(V obj1, V obj2) {\n" +
 			"	return 0;\n" +
 			"}\n" +
-			COMPARATOR_IMPL_JRE8.replace('*', 'V').replace('%', 'U').replace('$', 'S') +
 			"}", // =================
 
 		});
@@ -42465,8 +42445,6 @@
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=207573 - variation
 // FAIL ERRMSG
 public void test1210() {
-	if (this.complianceLevel >= ClassFileConstants.JDK1_8)
-		return;
 	this.runNegativeTest(
 		new String[] {
 			"X.java",
@@ -42496,7 +42474,7 @@
 		"1. ERROR in X.java (at line 6)\n" + 
 		"	Object[] o  = throwE(objs);\n" + 
 		"	              ^^^^^^^^^^^^\n" + 
-		"Type mismatch: cannot convert from Object[]&Exception to Object[]\n" + 
+		"Type mismatch: cannot convert from RuntimeException to Object[]\n" + 
 		"----------\n"));
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=208030
@@ -50726,7 +50704,6 @@
 				"			public boolean hasNext() {\n" + 
 				"				return false;\n" + 
 				"			}\n" + 
-				ITERATOR_RAW_IMPL_JRE8 +
 				"		};\n" + 
 				"	}\n" + 
 				"	Zork z;\n" +
@@ -50759,9 +50736,9 @@
 			"	                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 			"Unnecessary cast from Iterator to Iterator<String>\n" + 
 			"----------\n" + 
-			"6. ERROR in X.java (at line 38)\n"
+			"6. ERROR in X.java (at line 36)\n"
 			: // secondary error no longer reported at 1.8+
-			"5. ERROR in X.java (at line 38)\n"
+			"5. ERROR in X.java (at line 36)\n"
 			) +
 			"	Zork z;\n" + 
 			"	^^^^\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
index bd9867c..94c0c6f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
@@ -7,7 +7,7 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     Stephan Herrmann - Contributions for
  *								bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
  *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
  *								bug 401456 - Code compiles from javac/intellij, but fails from eclipse
@@ -29,6 +29,7 @@
  *								Bug 434044 - Java 8 generics thinks single method is ambiguous
  *								Bug 434793 - [1.8][null][compiler] AIOOBE in ParameterizedGenericMethodBinding.substitute when inlining a method
  *								Bug 438337 - StackOverflow after update from Kepler to Luna 
+ *								Bug 452194 - Code no longer compiles in 4.4.1, but with confusing error
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -5408,5 +5409,46 @@
 		   },
 		   "");
 }
+public void testBug452194() {
+	runNegativeTest(
+		new String[]{
+			"test/Main.java",
+			"package test;\n" + 
+			"\n" + 
+			"import java.util.Map.Entry;\n" + 
+			"\n" + 
+			"public class Main {\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		EcoreEMap map = new EcoreEMap();\n" + 
+			"		map.addUnique(new Object()); //Error here ONLY in 4.4\n" + 
+			"	}\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface InternalEList<E> {\n" + 
+			"	public void addUnique(E object);\n" + 
+			"}\n" + 
+			"\n" + 
+			"class EcoreEMap<K, V> implements InternalEList<Entry<K, V>> {\n" + 
+			"	public void addUnique(Entry<K, V> object) {\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in test\\Main.java (at line 7)\n" + 
+		"	EcoreEMap map = new EcoreEMap();\n" + 
+		"	^^^^^^^^^\n" + 
+		"EcoreEMap is a raw type. References to generic type EcoreEMap<K,V> should be parameterized\n" + 
+		"----------\n" + 
+		"2. WARNING in test\\Main.java (at line 7)\n" + 
+		"	EcoreEMap map = new EcoreEMap();\n" + 
+		"	                    ^^^^^^^^^\n" + 
+		"EcoreEMap is a raw type. References to generic type EcoreEMap<K,V> should be parameterized\n" + 
+		"----------\n" + 
+		"3. ERROR in test\\Main.java (at line 8)\n" + 
+		"	map.addUnique(new Object()); //Error here ONLY in 4.4\n" + 
+		"	    ^^^^^^^^^\n" + 
+		"The method addUnique(Map.Entry) in the type EcoreEMap is not applicable for the arguments (Object)\n" + 
+		"----------\n");
+}
 }
 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index 302a02c..f9850d3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -4920,4 +4920,75 @@
 		"Type safety: Potential heap pollution via varargs parameter p\n" + 
 		"----------\n");
 }
+// original:
+public void testBug452788a() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.util.function.Function;\n" + 
+			"\n" + 
+			"interface Test<A> {\n" + 
+			"\n" + 
+			"	<B3> Test<B3> create(B3 b);\n" + 
+			"\n" + 
+			"	<B2> Test<B2> transform(Function<? extends A, Test<B2>> f);\n" + 
+			"\n" + 
+			"	default <B1> Test<B1> wrap(Function<? super A, ? extends B1> f) {\n" + 
+			"		return transform(a -> create(f.apply(a)));\n" + 
+			"	}\n" + 
+			"}\n"
+		});
 }
+// variants:
+public void testBug452788b() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.util.function.Function;\n" + 
+			"\n" + 
+			"interface Test<A> {\n" + 
+			"\n" + 
+			"	<B3> Test<B3> create(B3 b);\n" + 
+			"\n" + 
+			"	<B2> Test<B2> transform(Function<? extends A, Test<B2>> f);\n" + 
+			"\n" + 
+			"	default <B1> Test<B1> wrap(Function<? super A, ? extends B1> f) {\n" + 
+			"		return transform((A a) -> create(f.apply(a)));\n" + // explicitly typed lambda
+			"	}\n" +
+			"	default <B> Function<? extends A, Test<B>> test1(Function<? super A, ? extends B> f) {\n" + 
+			"		return a -> create(f.apply(a));\n" + // remove outer invocation
+			"	}\n" + 
+			"	default <B> Function<? extends A, Function<? extends A, Test<B>>> test2(Function<? super A, ? extends B> f) {\n" + 
+			"		return a1 -> a2 -> create(f.apply(a2));\n" + // outer lambda instead of outer invocation
+			"	}\n" + 
+			"}\n"
+		});
+}
+// diamond allocation instead of method (was OK before the patch).
+public void testBug452788c() {
+	runConformTest(
+		new String[] {
+			"Test2.java",
+			"import java.util.function.Function;\n" + 
+			"\n" + 
+			"\n" + 
+			"public interface Test2<A> {\n" + 
+			"	<B2> Test2<B2> transform(Function<? extends A, Test2<B2>> f);\n" + 
+			"\n" + 
+			"	default <B1> Test2<B1> wrap(Function<? super A, ? extends B1> f) {\n" + 
+			"		return transform(a -> new TestImpl<>(f.apply(a)));\n" + 
+			"	}\n" + 
+			"}\n" + 
+			"\n" + 
+			"class TestImpl<A> implements Test2<A> {\n" + 
+			"\n" + 
+			"	public TestImpl(A a) { }\n" + 
+			"\n" + 
+			"	@Override\n" + 
+			"	public <B2> Test2<B2> transform(Function<? extends A, Test2<B2>> f) {\n" + 
+			"		return null;\n" + 
+			"	}	\n" + 
+			"}\n"
+		});
+}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
index 3fc9754..d1abd89 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java
@@ -6857,7 +6857,6 @@
 			"				compare(yourList != null ? yourList : myList, yourList);\n" + 
 			"				return 0;\n" + 
 			"			}\n" + 
-			COMPARATOR_RAW_IMPL_JRE8 +
 			"		};\n" + 
 			"		System.out.println(\"SUCCESS\");\n" + 
 			"	}\n" + 
@@ -6888,7 +6887,6 @@
 			"			private int foo(int i, int j) {\n" + 
 			"				return i - j;\n" + 
 			"			}\n" + 
-			COMPARATOR_RAW_IMPL_JRE8 +
 			"		};\n" + 
 			"		System.out.println(\"SUCCESS\");\n" + 
 			"	}\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index d7346a7..3b1c2bc 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -5496,6 +5496,91 @@
 			"",
 			customOptions);
 }
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=445949, Lambda parameter not shadowing in nested scope producing non-existent compilation error
+public void test445949() {
+	this.runConformTest(
+		new String[] {
+			"X.java",
+			"import java.util.function.Consumer;\n" +
+			"public class X {\n" +
+			"	void methodInFirstLevel(int y) {\n" +
+			"		class Second {\n" +
+			"			int t = y;\n" +
+			"			Consumer<Integer> myConsumer1 = (z) -> {\n" +
+			"				System.out.println(\"z = \" + z);\n" +
+			"				System.out.println(\"y = \" + y);\n" +
+			"				System.out.println(\"t = \" + t);\n" +
+			"			};\n" +
+			"			Consumer<Integer> myConsumer2 = (y) -> {\n" +
+			"				System.out.println(\"y = \" + y);\n" +
+			"				System.out.println(\"t = \" + t);\n" +
+			"			};\n" +
+			"			void foo( int y) {\n" +
+			"				System.out.println(\"y = \" + y);\n" +
+			"			}\n" +
+			"			class Third {\n" +
+			"				Consumer<Integer> myConsumer3 = (y) -> {\n" +
+			"					System.out.println(\"y = \" + y);\n" +
+			"				};\n" +
+			"			}\n" +
+			"			void bar(int y) {\n" +
+			"				new Third().myConsumer3.accept(y);\n" +
+			"			}\n" +
+			" 		}\n" +
+			"		new Second().myConsumer1.accept(10);\n" +
+			"		new Second().myConsumer2.accept(20);\n" +
+			"		new Second().foo(30);\n" +
+			"		new Second().bar(40);\n" +
+			"		\n" +
+			"	}\n" +
+			"	void foo() {\n" +
+			"  		Consumer<Integer> myConsumer2 = (y) -> {\n" +
+			"		class Inner {\n" +
+			"	  	Consumer<Integer> myConsumer4 = (y) -> { \n" +
+			"		class InnerMost {\n" +
+			"		Consumer<Integer> myConsumer3 = (y /*error without fix*/) -> {};\n" +
+			"		}\n" +
+			"	  	};\n" +
+			"		}\n" +
+			"		new Inner().myConsumer4.accept(10);\n" +
+			"	};\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		new X().methodInFirstLevel(5);\n" +
+			"		new X().foo();\n" +
+			"	}\n" +
+			"}\n"
+	},
+	"z = 10\ny = 5\nt = 5\ny = 20\nt = 5\ny = 30\ny = 40");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=445949, Lambda parameter not shadowing in nested scope producing non-existent compilation error
+public void test445949a() {
+	this.runNegativeTest(
+		new String[] {
+			"X.java",
+			"import java.util.function.Consumer;\n" +
+			"class X {\n" +
+			"	void foo(int y) {\n" +
+			"		Consumer<Integer> c1 = (y)-> {};\n" +
+			"	}\n" +
+			"	void foo2() {\n" +
+			"		int y;\n" +
+			"		Consumer<Integer> c1 = (y)-> {};\n" +
+			"	}\n" +
+			"}\n"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 4)\n" +
+		"	Consumer<Integer> c1 = (y)-> {};\n" +
+		"	                        ^\n" +
+		"Lambda expression's parameter y cannot redeclare another local variable defined in an enclosing scope. \n" +
+		"----------\n" +
+		"2. ERROR in X.java (at line 8)\n" +
+		"	Consumer<Integer> c1 = (y)-> {};\n" +
+		"	                        ^\n" +
+		"Lambda expression's parameter y cannot redeclare another local variable defined in an enclosing scope. \n" +
+		"----------\n");
+}
 public static Class testClass() {
 	return LambdaExpressionsTest.class;
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
index 910f2c4..03b8dff 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaRegressionTest.java
@@ -509,6 +509,96 @@
 			"}\n"
 	});
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=451840
+// [1.8] java.lang.BootstrapMethodError when running code with constructor reference
+public void testBug451840() {
+	runNegativeTest(new String [] {
+		"X.java",
+		"public class X {\n" +  
+		"    public static void main(String[] args) {\n" + 
+		"    	X test = new X();\n" + 
+		"    	MySupplier<X> s = test::new; // incorrect\n" + 
+		"    }\n" + 
+		"    public interface MySupplier<T> {\n" + 
+		"        T create();\n" + 
+		"    }\n" + 
+		"}"},
+		"----------\n" + 
+		"1. ERROR in X.java (at line 4)\n" + 
+		"	MySupplier<X> s = test::new; // incorrect\n" + 
+		"	                  ^^^^\n" + 
+		"test cannot be resolved to a type\n" + 
+		"----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=448556
+// [1.8][compiler] Invalid compiler error about effectively final variable outside the context of a lambda.
+public void testBug4448556() {
+	this.runConformTest(new String [] {
+		"X.java",
+		"import java.io.Serializable;\n" + 
+		"import java.util.Arrays;\n" + 
+		"import java.util.List;\n" + 
+		"public class X {\n" + 
+		"    private static final List<Integer> INTEGERS = Arrays.asList(1, 2, 3, 4);\n" + 
+		"    public static void main(String[] args) {\n" + 
+		"        for (int i = 0; i < INTEGERS.size(); i++) {\n" + 
+		"            MyPredicate<Integer> predicate = INTEGERS.get(i)::equals;\n" + 
+		"        }\n" + 
+		"    }  \n" + 
+		"    public interface MyPredicate<T> extends Serializable {\n" + 
+		"        boolean accept(T each);\n" + 
+		"    }\n" + 
+		"}"
+	},
+	"");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=448556
+// [1.8][compiler] Invalid compiler error about effectively final variable outside the context of a lambda.
+public void testBug4448556a() {
+	this.runConformTest(new String [] {
+		"X.java",
+		"import java.io.Serializable;\n" + 
+		"import java.util.Arrays;\n" + 
+		"import java.util.List;\n" + 
+		"public class X {\n" + 
+		"	int value = 0; \n" + 
+		"    private static final List<Integer> INTEGERS = Arrays.asList(1, 2, 3, 4);\n" + 
+		"    public Integer next() {\n" + 
+		"    	return new Integer(++value);\n" + 
+		"    }\n" + 
+		"    public static void main(String[] args) {\n" + 
+		"    	X t = new X();\n" + 
+		"        MyPredicate<Integer> predicate = t.next()::equals;\n" + 
+		"        System.out.println(\"Value \" + t.value + \" accept \" + predicate.accept(t.value));\n" + 
+		"    }\n" + 
+		"    public interface MyPredicate<T> extends Serializable {\n" + 
+		"        boolean accept(T each);\n" + 
+		"    }\n" + 
+		"}"
+	},
+	"Value 1 accept true");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=453687
+// [1.8][compiler]Incorrect errors when compiling code with Method References
+public void testBug453687() {
+	this.runConformTest(new String [] {
+		"X.java",
+		"import static java.util.stream.Collectors.groupingBy;\n" + 
+		"import static java.util.stream.Collectors.mapping;\n" + 
+		"import static java.util.stream.Collectors.toSet;\n" + 
+		"import java.util.Locale;\n" + 
+		"import java.util.Map;\n" + 
+		"import java.util.Set;\n" + 
+		"import java.util.stream.Stream;\n" + 
+		"public class X {\n" + 
+		"	public static void main(String[] args) {\n" + 
+		"		Map<String, Set<String>> countryLanguagesMap = Stream.of(Locale.getAvailableLocales()).collect(\n" + 
+		"				groupingBy(Locale::getDisplayCountry, mapping(Locale::getDisplayLanguage, toSet())));\n" + 
+		"	}\n" + 
+		"} "
+	},
+	"");
+}
 public static Class testClass() {
 	return LambdaRegressionTest.class;
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
index fe8a511..96d9be9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalVariableTest.java
@@ -737,7 +737,7 @@
 //Error message for exception parameter not being used.
 public void test412119b() {
 	Map options = getCompilerOptions();
-	options.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnusedExceptionParameter, CompilerOptions.ERROR);
 	this.runNegativeTest(
 			new String[] {
 				"p/X.java",
@@ -784,7 +784,7 @@
 	if (this.complianceLevel < ClassFileConstants.JDK1_7)
 		return;
 	Map options = getCompilerOptions();
-	options.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnusedExceptionParameter, CompilerOptions.ERROR);
 	this.runNegativeTest(
 			new String[] {
 				"p/X.java",
@@ -831,6 +831,7 @@
 		return;
 	Map options = getCompilerOptions();
 	options.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.WARNING);
+	options.put(CompilerOptions.OPTION_ReportUnusedExceptionParameter, CompilerOptions.WARNING);
 	this.runNegativeTest(
 			new String[] {
 				"p/X.java",
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
index c2e25f6..5f6c016 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -2563,8 +2563,6 @@
 				"        public int size() {\n" +
 				"                return 0;\n" +
 				"        }\n" +
-				getCollectionAndListRawImplJRE8() +
-				getIterableRawImplJRE8() +
 				"}", // =================
 			},
 			"");
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index 4453690..73953e0 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -1825,7 +1825,6 @@
 				"import java.util.*;\n" + 
 				"public class X extends java.util.AbstractMap {\n" +
 				"	public java.util.Set entrySet() { return null; }\n" +
-				MAP_RAW_IMPL_JRE8 +
 				"}\n"
 			},
 			""
@@ -6900,8 +6899,6 @@
 				"	public boolean hasNext() {	return false; }\n" +
 				"	public Object next() {	return null; }\n" +
 				"	public void remove() {}\n" +
-				ITERABLE_RAW_IMPL_JRE8 +
-				COLLECTION_AND_LIST_RAW_IMPL_JRE8 +
 				"}\n", // =================
 			},
 			"----------\n" +
@@ -7022,8 +7019,6 @@
 				"	public boolean hasNext() {	return false; }\n" +
 				"	public Object next() {	return null; }\n" +
 				"	public void remove() {}\n" +
-				ITERABLE_RAW_IMPL_JRE8 +
-				COLLECTION_AND_LIST_RAW_IMPL_JRE8 +
 				"}\n", // =================
 			},
 			"----------\n" +
@@ -7134,8 +7129,6 @@
 				"	public boolean hasNext() {	return false; }\n" +
 				"	public Object next() {	return null; }\n" +
 				"	public void remove() {}\n" +
-				ITERABLE_RAW_IMPL_JRE8 +
-				COLLECTION_AND_LIST_RAW_IMPL_JRE8 + 
 				"}\n", // =================
 			},
 			"----------\n" +
@@ -11442,7 +11435,6 @@
 			"		return compare((I) o1, (I) o2);\n" +
 			"	}\n" +
 			"	public int compare(I o1, I o2) { return 0; }\n" +
-			COMPARATOR_RAW_IMPL_JRE8 +
 			"}"
 		},
 		""
@@ -12355,7 +12347,6 @@
 			"			public int compare(Object o1, Object o2) {\n" + 
 			"				return 0;\n" + 
 			"			}\n" + 
-			COMPARATOR_RAW_IMPL_JRE8 +
 			"		};\n" + 
 			"		Test.assertEquals(\"Test\", comparator, new ArrayList(), new ArrayList());\n" + 
 			"	}\n" + 
@@ -12426,7 +12417,6 @@
 			"			public int compare(Object o1, Object o2) {\n" + 
 			"				return 0;\n" + 
 			"			}\n" + 
-			COMPARATOR_RAW_IMPL_JRE8 +
 			"		};\n" + 
 			"		Test.assertEquals(\"Test\", comparator, new ArrayList(), new ArrayList());\n" + 
 			"	}\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index aa77ed2..8dcd36f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -6664,7 +6664,7 @@
 		"1. ERROR in ClassF.java (at line 13)\n" + 
 		"	needNonNull(o);\n" + 
 		"	            ^\n" + 
-		"Null type mismatch: required \'@NonNull Object\' but the provided value is inferred as @Nullable\n" + 
+		"Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
 		"----------\n");
 }
 // Bug 415413 - [compiler][null] NullpointerException in Null Analysis caused by interaction of LoopingFlowContext and FinallyFlowContext
@@ -7584,7 +7584,7 @@
 		"----------\n");
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=444024, Type mismatch error in annotation generics assignment which happens "sometimes"
-public void _test444024() {
+public void test444024() {
 		this.runConformTest(
 		   new String[] {
 			   "ViewpointOrganisationEntity.java",
@@ -7653,4 +7653,229 @@
 		"----------\n",
 		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
 }
+public void testBug445147() {
+	runConformTestWithLibs(
+		new String[] {
+			"foobar/Bar.java",
+			"package foobar;\n" + 
+			"@org.eclipse.jdt.annotation.NonNullByDefault\n" + 
+			"interface Bar<B extends Bar<B, F>, F extends Foo<F, B>> {}",
+			"foobar/Foo.java",
+			"package foobar;\n" + 
+			"@org.eclipse.jdt.annotation.NonNullByDefault\n" + 
+			"interface Foo<F extends Foo<F, B>, B extends Bar<B, F>> {}"
+		},
+		getCompilerOptions(),
+		"");
+}
+public void testBug445708() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // uses switch on string.
+	runNegativeTestWithLibs(
+		new String[] {
+			"SwitchTest.java",
+			"import org.eclipse.jdt.annotation.Nullable;\n" + 
+			"\n" + 
+			"public class SwitchTest\n" + 
+			"{\n" + 
+			"   private enum EnumValue\n" + 
+			"   {\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   public static void main(String[] args)\n" + 
+			"   {\n" + 
+			"      // Should be flagged as \"Potential null pointer access,\" but is not.\n" + 
+			"      switch (computeStringValue())\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Nullable String stringValue = null;\n" + 
+			"      \n" + 
+			"      // Properly flagged as \"Null pointer access.\"\n" + 
+			"      switch (stringValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      stringValue = computeStringValue();\n" + 
+			"      \n" + 
+			"      // Should be flagged as \"Potential null pointer access,\" but is not.\n" + 
+			"      switch (stringValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      // Should also be flagged, but is not.\n" + 
+			"      switch (computeEnumValue())\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Nullable EnumValue enumValue = null;\n" + 
+			"      \n" + 
+			"      // Fixed in bug #403674.\n" + 
+			"      switch (enumValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static @Nullable String computeStringValue()\n" + 
+			"   {\n" + 
+			"      return null;\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static @Nullable EnumValue computeEnumValue()\n" + 
+			"   {\n" + 
+			"      return null;\n" + 
+			"   }\n" + 
+			"}\n"
+		}, 
+		"----------\n" + 
+		"1. ERROR in SwitchTest.java (at line 12)\n" + 
+		"	switch (computeStringValue())\n" + 
+		"	        ^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential null pointer access: The method computeStringValue() may return null\n" + 
+		"----------\n" + 
+		"2. ERROR in SwitchTest.java (at line 19)\n" + 
+		"	switch (stringValue)\n" + 
+		"	        ^^^^^^^^^^^\n" + 
+		"Null pointer access: The variable stringValue can only be null at this location\n" + 
+		"----------\n" + 
+		"3. ERROR in SwitchTest.java (at line 26)\n" + 
+		"	switch (stringValue)\n" + 
+		"	        ^^^^^^^^^^^\n" +
+		(this.complianceLevel < ClassFileConstants.JDK1_8
+		? "Potential null pointer access: The variable stringValue may be null at this location\n"
+		: "Potential null pointer access: this expression has a \'@Nullable\' type\n" ) +
+		"----------\n" + 
+		"4. ERROR in SwitchTest.java (at line 31)\n" + 
+		"	switch (computeEnumValue())\n" + 
+		"	        ^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential null pointer access: The method computeEnumValue() may return null\n" + 
+		"----------\n" + 
+		"5. ERROR in SwitchTest.java (at line 38)\n" + 
+		"	switch (enumValue)\n" + 
+		"	        ^^^^^^^^^\n" + 
+		"Null pointer access: The variable enumValue can only be null at this location\n" + 
+		"----------\n");
+}
+// same as above but 1.8 with declaration annotations
+public void testBug445708b() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) return; // only one combination tested
+	Map customOptions = getCompilerOptions();
+	customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull");
+	customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable");
+	runNegativeTestWithLibs(
+		new String[] {
+			CUSTOM_NULLABLE_NAME,
+			CUSTOM_NULLABLE_CONTENT,
+			"SwitchTest.java",
+			"import org.eclipse.jdt.annotation.Nullable;\n" + 
+			"\n" + 
+			"public class SwitchTest\n" + 
+			"{\n" + 
+			"   private enum EnumValue\n" + 
+			"   {\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   public static void main(String[] args)\n" + 
+			"   {\n" + 
+			"      // Should be flagged as \"Potential null pointer access,\" but is not.\n" + 
+			"      switch (computeStringValue())\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Nullable String stringValue = null;\n" + 
+			"      \n" + 
+			"      // Properly flagged as \"Null pointer access.\"\n" + 
+			"      switch (stringValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      stringValue = computeStringValue();\n" + 
+			"      \n" + 
+			"      // Should be flagged as \"Potential null pointer access,\" but is not.\n" + 
+			"      switch (stringValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      // Should also be flagged, but is not.\n" + 
+			"      switch (computeEnumValue())\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"      \n" + 
+			"      @Nullable EnumValue enumValue = null;\n" + 
+			"      \n" + 
+			"      // Fixed in bug #403674.\n" + 
+			"      switch (enumValue)\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static @Nullable String computeStringValue()\n" + 
+			"   {\n" + 
+			"      return null;\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static @Nullable EnumValue computeEnumValue()\n" + 
+			"   {\n" + 
+			"      return null;\n" + 
+			"   }\n" + 
+			"}\n"
+		}, 
+		"----------\n" + 
+		"1. ERROR in SwitchTest.java (at line 12)\n" + 
+		"	switch (computeStringValue())\n" + 
+		"	        ^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential null pointer access: The method computeStringValue() may return null\n" + 
+		"----------\n" + 
+		"2. ERROR in SwitchTest.java (at line 19)\n" + 
+		"	switch (stringValue)\n" + 
+		"	        ^^^^^^^^^^^\n" + 
+		"Null pointer access: The variable stringValue can only be null at this location\n" + 
+		"----------\n" + 
+		"3. ERROR in SwitchTest.java (at line 26)\n" + 
+		"	switch (stringValue)\n" + 
+		"	        ^^^^^^^^^^^\n" +
+		"Potential null pointer access: this expression has a \'@Nullable\' type\n" +
+		"----------\n" + 
+		"4. ERROR in SwitchTest.java (at line 31)\n" + 
+		"	switch (computeEnumValue())\n" + 
+		"	        ^^^^^^^^^^^^^^^^^^\n" + 
+		"Potential null pointer access: The method computeEnumValue() may return null\n" + 
+		"----------\n" + 
+		"5. ERROR in SwitchTest.java (at line 38)\n" + 
+		"	switch (enumValue)\n" + 
+		"	        ^^^^^^^^^\n" + 
+		"Null pointer access: The variable enumValue can only be null at this location\n" + 
+		"----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=452780 - Internal compiler error: arrayIndexOutOfBounds
+public void testBug452780() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) return;
+	runConformTestWithLibs(
+		new String[] {
+			"Tools2.java",
+			"import java.util.Arrays;\n" + 
+			"import java.util.List;\n" + 
+			"import java.util.Set;\n" + 
+			"import java.util.stream.Collector;\n" + 
+			"import java.util.stream.Collectors;\n" + 
+			"import org.eclipse.jdt.annotation.NonNull;\n" + 
+			"public class Tools2 {\n" + 
+			"	@SafeVarargs\n" + 
+			"	public static <T> List<@NonNull T> asList(T... ts) {\n" + 
+			"		@SuppressWarnings(\"null\")\n" + 
+			"		@NonNull\n" + 
+			"		List<@NonNull T> res = Arrays.asList(ts);\n" + 
+			"		return res;\n" + 
+			"	}\n" + 
+			"	@SuppressWarnings(\"null\")\n" + 
+			"	public static <T> Collector<@NonNull T, @NonNull ?, @NonNull Set<@NonNull T>> toSet() {\n" + 
+			"		@NonNull\n" + 
+			"		Collector<@NonNull T, ?, @NonNull Set<@NonNull T>> res = Collectors\n" + 
+			"				.toSet();\n" + 
+			"		return res;\n" + 
+			"	}\n" + 
+			"}"
+		},
+		getCompilerOptions(),
+		"");
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
index 21bdbfb..89e9277 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 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
@@ -12,6 +12,7 @@
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *								bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith()
  *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								Bug 453635 - [compiler][null] Update NullReferenceImplTests and friends
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -22,9 +23,13 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -33,6 +38,7 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.eclipse.jdt.core.tests.compiler.regression.NullReferenceImplTests.State;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
 import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo.AssertionFailedException;
@@ -171,7 +177,7 @@
 			new State(25), // 011001
 			new State(26), // 011010
 			new State(27), // 011011
-			new State(28), // 011100
+			new State(28, "pot. n & pot. nn & pot. un"), // 011100
 			new State(29), // 011101
 			new State(30), // 011110
 			new State(31), // 011111
@@ -512,6 +518,12 @@
 	public String toString() {
 		return this.name;
 	}
+	public boolean equals(Object other) {
+		return (other instanceof State) && ((State)other).value == this.value;
+	}
+	public int hashCode() {
+		return this.value;
+	}
 	}
 
 public NullReferenceImplTests(String name) {
@@ -1262,9 +1274,9 @@
 		target.nullBit2 = source.nullBit2;
 		target.nullBit3 = source.nullBit3;
 		target.nullBit4 = source.nullBit4;
-//		target.nullBit5 = source.nullBit5;
-//		target.nullBit6 = source.nullBit6;
 	}
+	target.iNBit = source.iNBit;
+	target.iNNBit = source.iNNBit;
 	target.tagBits = source.tagBits;
 	target.maxFieldCount = source.maxFieldCount;
 	if (source.extra != null) {
@@ -1310,8 +1322,6 @@
 		zis.nullBit2 = nullBits[1] << position;
 		zis.nullBit3 = nullBits[2] << position;
 		zis.nullBit4 = nullBits[3] << position;
-//		zis.nullBit5 = nullBits[4] << position;
-//		zis.nullBit6 = nullBits[5] << position;
 	}
  	else {
 		int vectorIndex = (position / BitCacheSize) - 1,
@@ -1324,7 +1334,12 @@
 		    zis.extra[j] = new long[length];
 		    zis.extra[j][vectorIndex] = nullBits[j - 2] << position;
         }
+        // FIXME: while IN,INN are not included in nullBits:
+        Arrays.fill(zis.extra[UnconditionalFlowInfo.IN],  -1L);
+        Arrays.fill(zis.extra[UnconditionalFlowInfo.INN],  -1L);
 	}
+	zis.iNBit = -1L; // FIXME: nullBits[4] << position;
+	zis.iNNBit = -1L; // FIXME: nullBits[5] << position;
 	if (nullBits[0] != 0 || nullBits[1] != 0
 	        || nullBits[2] != 0 || nullBits[3] != 0
 	        || nullBits[4] != 0 || nullBits[5] != 0) {
@@ -1344,8 +1359,8 @@
 			|| zis.nullBit2 != other.nullBit2
 			|| zis.nullBit3 != other.nullBit3
 			|| zis.nullBit4 != other.nullBit4
-			/* || zis.nullBit5 != other.nullBit5
-			|| zis.nullBit6 != other.nullBit6 */) {
+			/*|| zis.iNBit != other.iNBit // FIXME: include these bits in comparison?
+			|| zis.iNNBit != other.iNNBit */) {
 		return false;
 	}
 	int left = zis.extra == null ? 0 : zis.extra[2].length,
@@ -1397,11 +1412,11 @@
 				((zis.nullBit3 & mask) ^
 					(other.nullBit3 & mask)) == 0 &&
 				((zis.nullBit4 & mask) ^
-					(other.nullBit4 & mask)) == 0 /* &&
-				((zis.nullBit5 & mask) ^
-					(other.nullBit5 & mask)) == 0 &&
-				((zis.nullBit6 & mask) ^
-					(other.nullBit6 & mask)) == 0 */;
+					(other.nullBit4 & mask)) == 0 /* &&  // FIXME: include these bits in comparison?
+				((zis.iNBit & mask) ^
+					(other.iNBit & mask)) == 0 &&
+				((zis.iNNBit & mask) ^
+					(other.iNNBit & mask)) == 0 */;
 	}
 	else {
 		int left = zis.extra == null ?
@@ -1449,8 +1464,8 @@
 					+ "," + (zis.nullBit2 >> position) //$NON-NLS-1$
 					+ "," + (zis.nullBit3 >> position) //$NON-NLS-1$
 					+ "," + (zis.nullBit4 >> position) //$NON-NLS-1$
-//					+ "," + (zis.nullBit5 >> position) //$NON-NLS-1$
-//					+ "," + (zis.nullBit6 >> position) //$NON-NLS-1$
+//					+ "," + (zis.iNBit >> position) //$NON-NLS-1$
+//					+ "," + (zis.iNNBit >> position) //$NON-NLS-1$
 					+ "}"; //$NON-NLS-1$
 	}
 	else {
@@ -1688,7 +1703,13 @@
 			i < length; i++) {
 		NullReferenceImplTransformations.transformations[i].hydrate();
 	}
-	NullReferenceImplTests.State[] transitiveClosure = computeTransitiveClosure();
+	NullReferenceImplTests.State[] transitiveClosure = computeTransitiveClosure(); // need for initialization?
+	transitiveClosure = addSymbolicStates(transitiveClosure); // don't rely on reachibility alone, since we don't cover all operations in these tests.
+	Arrays.sort(transitiveClosure, new Comparator() {
+		public int compare(Object o1, Object o2) {
+			return new Integer(((State)o1).value).compareTo(new Integer(((State)o2).value));
+		}
+	});
 	try {
 		BufferedReader in;
 		BufferedWriter out;
@@ -1725,6 +1746,15 @@
 		System.exit(2);
 	}
 }
+private static State[] addSymbolicStates(State[] transitiveClosure) {
+	Set allStates = new HashSet();
+	for (int i = 0; i < transitiveClosure.length; i++)
+		allStates.add(transitiveClosure[i]);
+	for (int i=0; i < State.statesNb; i++)
+		if (State.states[i].symbolic)
+			allStates.add(State.states[i]);
+	return (State[]) allStates.toArray(new State[allStates.size()]);
+}
 
 private static void printHelp(boolean longText) {
 	if (longText) {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java
index c1b13b1..9085544 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTransformations.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 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
@@ -10,6 +10,7 @@
  *     Stephan Herrmann - Contribution for
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *								bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith()
+ *								Bug 453635 - [compiler][null] Update NullReferenceImplTests and friends
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -19,6 +20,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,19 +34,20 @@
 		markAsComparedEqualToNonNull =
 		// markAsComparedEqualToNonNull DEFINITION START
 		// start => prot. non null
-		// prot. non null => prot. non null
-		// prot. null => prot. non null
 		// pot. unknown => pot. nn & prot. nn
 		// pot. non null => pot. nn & prot. nn
-		// pot. nn & prot. nn => pot. nn & prot. nn
 		// pot. nn & pot. un => pot. nn & prot. nn
 		// pot. null => prot. non null
-		// pot. n & prot. n => prot. non null
 		// pot. n & pot. un => pot. nn & prot. nn
 		// pot. n & pot. nn => pot. nn & prot. nn
+		// pot. n & pot. nn & pot. un => prot. non null		 // pot. nn & prot. nn could be better?
 		// def. unknown => def. non null
 		// def. non null => def. non null
+		// pot. nn & prot. nn => pot. nn & prot. nn
 		// def. null => prot. non null
+		// pot. n & prot. n => prot. non null
+		// prot. null => prot. non null
+		// prot. non null => prot. non null
 		// markAsComparedEqualToNonNull DEFINITION END
 			new TwoDimensionalTransformation("markAsComparedEqualToNonNull",
 					new byte[][] {
@@ -56,6 +59,7 @@
 					{0x10,0x3C},
 					{0x14,0x2C},
 					{0x18,0x2C},
+					{0x1C,0x3C},
 					{0x24,0x28},
 					{0x28,0x28},
 					{0x2C,0x2C},
@@ -75,19 +79,20 @@
 		markAsComparedEqualToNull =
 		// markAsComparedEqualToNull DEFINITION START
 		// start => prot. null
-		// prot. non null => prot. null
-		// prot. null => prot. null
 		// pot. unknown => pot. n & prot. n
 		// pot. non null => prot. null
-		// pot. nn & prot. nn => prot. null
 		// pot. nn & pot. un => pot. n & prot. n
 		// pot. null => pot. n & prot. n
-		// pot. n & prot. n => pot. n & prot. n
 		// pot. n & pot. un => pot. n & prot. n
 		// pot. n & pot. nn => pot. n & prot. n
+		// pot. n & pot. nn & pot. un => pot. n & prot. n
 		// def. unknown => def. null
 		// def. non null => prot. null
+		// pot. nn & prot. nn => prot. null
 		// def. null => def. null
+		// pot. n & prot. n => pot. n & prot. n
+		// prot. null => prot. null
+		// prot. non null => prot. null
 		// markAsComparedEqualToNull DEFINITION END
 			new TwoDimensionalTransformation("markAsComparedEqualToNull",
 				new byte[][] {
@@ -99,6 +104,7 @@
 				{0x10,0x34},
 				{0x14,0x34},
 				{0x18,0x34},
+				{0x1C,0x34},
 				{0x24,0x30},
 				{0x28,0x38},
 				{0x2C,0x38},
@@ -118,19 +124,20 @@
 		markAsDefinitelyNonNull =
 		// markAsDefinitelyNonNull DEFINITION START
 		// start => def. non null
-		// prot. non null => def. non null
-		// prot. null => def. non null
 		// pot. unknown => def. non null
 		// pot. non null => def. non null
-		// pot. nn & prot. nn => def. non null
 		// pot. nn & pot. un => def. non null
 		// pot. null => def. non null
-		// pot. n & prot. n => def. non null
 		// pot. n & pot. un => def. non null
 		// pot. n & pot. nn => def. non null
+		// pot. n & pot. nn & pot. un => def. non null
 		// def. unknown => def. non null
 		// def. non null => def. non null
+		// pot. nn & prot. nn => def. non null
 		// def. null => def. non null
+		// pot. n & prot. n => def. non null
+		// prot. null => def. non null
+		// prot. non null => def. non null
 		// markAsDefinitelyNonNull DEFINITION END
 			new TwoDimensionalTransformation("markAsDefinitelyNonNull",
 				new byte[][] {
@@ -142,6 +149,7 @@
 				{0x10,0x28},
 				{0x14,0x28},
 				{0x18,0x28},
+				{0x1C,0x28},
 				{0x24,0x28},
 				{0x28,0x28},
 				{0x2C,0x28},
@@ -161,19 +169,20 @@
 		markAsDefinitelyNull =
 		// markAsDefinitelyNull DEFINITION START
 		// start => def. null
-		// prot. non null => def. null
-		// prot. null => def. null
 		// pot. unknown => def. null
 		// pot. non null => def. null
-		// pot. nn & prot. nn => def. null
 		// pot. nn & pot. un => def. null
 		// pot. null => def. null
-		// pot. n & prot. n => def. null
 		// pot. n & pot. un => def. null
 		// pot. n & pot. nn => def. null
+		// pot. n & pot. nn & pot. un => def. null
 		// def. unknown => def. null
 		// def. non null => def. null
+		// pot. nn & prot. nn => def. null
 		// def. null => def. null
+		// pot. n & prot. n => def. null
+		// prot. null => def. null
+		// prot. non null => def. null
 		// markAsDefinitelyNull DEFINITION END
 			// PREMATURE add 'catch rules'
 			new TwoDimensionalTransformation("markAsDefinitelyNull",
@@ -186,6 +195,7 @@
 				{0x10,0x30},
 				{0x14,0x30},
 				{0x18,0x30},
+				{0x1C,0x30},
 				{0x24,0x30},
 				{0x28,0x30},
 				{0x2C,0x30},
@@ -205,19 +215,20 @@
 		markAsDefinitelyUnknown =
 		// markAsDefinitelyUnknown DEFINITION START
 		// start => def. unknown
-		// prot. non null => def. unknown
-		// prot. null => def. unknown
 		// pot. unknown => def. unknown
 		// pot. non null => def. unknown
-		// pot. nn & prot. nn => def. unknown
 		// pot. nn & pot. un => def. unknown
 		// pot. null => def. unknown
-		// pot. n & prot. n => def. unknown
 		// pot. n & pot. un => def. unknown
 		// pot. n & pot. nn => def. unknown
+		// pot. n & pot. nn & pot. un => def. unknown
 		// def. unknown => def. unknown
 		// def. non null => def. unknown
+		// pot. nn & prot. nn => def. unknown
 		// def. null => def. unknown
+		// pot. n & prot. n => def. unknown
+		// prot. null => def. unknown
+		// prot. non null => def. unknown
 		// markAsDefinitelyUnknown DEFINITION END
 			new TwoDimensionalTransformation("markAsDefinitelyUnknown",
 				new byte[][] {
@@ -229,6 +240,7 @@
 				{0x10,0x24},
 				{0x14,0x24},
 				{0x18,0x24},
+				{0x1C,0x24},
 				{0x24,0x24},
 				{0x28,0x24},
 				{0x2C,0x24},
@@ -250,6 +262,7 @@
 		// def. non null + def. non null => def. non null
 		// def. non null + def. null => def. null
 		// def. non null + def. unknown => def. unknown
+		// def. non null + pot. n & pot. nn & pot. un => pot. non null // BOGUS
 		// def. non null + pot. n & pot. nn => pot. n & pot. nn
 		// def. non null + pot. n & pot. un => pot. n & pot. nn
 		// def. non null + pot. n & prot. n => pot. n & prot. n
@@ -264,6 +277,7 @@
 		// def. null + def. non null => def. non null
 		// def. null + def. null => def. null
 		// def. null + def. unknown => def. unknown
+		// def. null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// def. null + pot. n & pot. nn => pot. n & pot. nn
 		// def. null + pot. n & pot. un => pot. n & pot. un
 		// def. null + pot. n & prot. n => def. null
@@ -278,6 +292,7 @@
 		// def. unknown + def. non null => def. non null
 		// def. unknown + def. null => def. null
 		// def. unknown + def. unknown => def. unknown
+		// def. unknown + pot. n & pot. nn & pot. un => pot. non null // BOGUS
 		// def. unknown + pot. n & pot. nn => pot. n & pot. nn
 		// def. unknown + pot. n & pot. un => pot. n & pot. un	// we loose the def here, but we need the pot. null
 		// def. unknown + pot. n & prot. n => def. null
@@ -289,9 +304,25 @@
 		// def. unknown + prot. non null => def. non null
 		// def. unknown + prot. null => def. null
 		// def. unknown + start => def. unknown
+		// pot. n & pot. nn & pot. un + def. non null => def. non null
+		// pot. n & pot. nn & pot. un + def. null => def. null
+		// pot. n & pot. nn & pot. un + def. unknown => def. unknown
+		// pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & prot. n
+		// pot. n & pot. nn & pot. un + pot. nn & pot. un => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. nn & prot. nn
+		// pot. n & pot. nn & pot. un + pot. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. null => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. unknown => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + prot. non null => pot. nn & prot. nn
+		// pot. n & pot. nn & pot. un + prot. null => pot. n & prot. n
+		// pot. n & pot. nn & pot. un + start => pot. n & pot. nn & pot. un
 		// pot. n & pot. nn + def. non null => def. non null
 		// pot. n & pot. nn + def. null => def. null
 		// pot. n & pot. nn + def. unknown => def. unknown
+		// pot. n & pot. nn + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & prot. n => pot. n & prot. n
@@ -306,6 +337,7 @@
 		// pot. n & pot. un + def. non null => def. non null
 		// pot. n & pot. un + def. null => def. null
 		// pot. n & pot. un + def. unknown => def. unknown
+		// pot. n & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn // should ideally include un
 		// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
 		// pot. n & pot. un + pot. n & prot. n => pot. n & prot. n
@@ -320,6 +352,7 @@
 		// pot. n & prot. n + def. non null => def. non null
 		// pot. n & prot. n + def. null => def. null
 		// pot. n & prot. n + def. unknown => def. unknown
+		// pot. n & prot. n + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
 		// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
@@ -334,6 +367,7 @@
 		// pot. nn & pot. un + def. non null => def. non null
 		// pot. nn & pot. un + def. null => def. null
 		// pot. nn & pot. un + def. unknown => def. unknown
+		// pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. non null // should ideally include un
 		// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & prot. n => pot. n & prot. n
@@ -348,6 +382,7 @@
 		// pot. nn & prot. nn + def. non null => def. non null
 		// pot. nn & prot. nn + def. null => def. null
 		// pot. nn & prot. nn + def. unknown => def. unknown
+		// pot. nn & prot. nn + pot. n & pot. nn & pot. un => pot. non null	// must include n
 		// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & prot. n => pot. n & prot. n
@@ -362,6 +397,7 @@
 		// pot. non null + def. non null => def. non null
 		// pot. non null + def. null => def. null
 		// pot. non null + def. unknown => def. unknown
+		// pot. non null + pot. n & pot. nn & pot. un => pot. non null // must include n
 		// pot. non null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. non null + pot. n & pot. un => pot. n & pot. nn
 		// pot. non null + pot. n & prot. n => pot. n & prot. n
@@ -376,6 +412,7 @@
 		// pot. null + def. non null => def. non null
 		// pot. null + def. null => def. null
 		// pot. null + def. unknown => def. unknown
+		// pot. null + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. null + pot. n & pot. un => pot. n & pot. un
 		// pot. null + pot. n & prot. n => pot. n & prot. n
@@ -390,6 +427,7 @@
 		// pot. unknown + def. non null => def. non null
 		// pot. unknown + def. null => def. null
 		// pot. unknown + def. unknown => def. unknown
+		// pot. unknown + pot. n & pot. nn & pot. un => pot. non null // must include n
 		// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
 		// pot. unknown + pot. n & pot. un => pot. n & pot. un
 		// pot. unknown + pot. n & prot. n => pot. n & prot. n
@@ -404,6 +442,7 @@
 		// prot. non null + def. non null => def. non null
 		// prot. non null + def. null => def. null
 		// prot. non null + def. unknown => def. unknown
+		// prot. non null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// prot. non null + pot. n & pot. nn => pot. n & pot. nn
 		// prot. non null + pot. n & pot. un => pot. n & pot. un
 		// prot. non null + pot. n & prot. n => pot. n & prot. n
@@ -418,6 +457,7 @@
 		// prot. null + def. non null => def. non null
 		// prot. null + def. null => def. null
 		// prot. null + def. unknown => def. unknown
+		// prot. null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// prot. null + pot. n & pot. nn => pot. n & pot. nn
 		// prot. null + pot. n & pot. un => pot. n & pot. un
 		// prot. null + pot. n & prot. n => pot. n & prot. n
@@ -432,6 +472,7 @@
 		// start + def. non null => def. non null
 		// start + def. null => def. null
 		// start + def. unknown => def. unknown
+		// start + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// start + pot. n & pot. nn => pot. n & pot. nn
 		// start + pot. n & pot. un => pot. n & pot. un
 		// start + pot. n & prot. n => pot. n & prot. n
@@ -454,6 +495,7 @@
 				{0x00,0x10,0x10},
 				{0x00,0x14,0x14},
 				{0x00,0x18,0x18},
+				{0x00,0x1C,0x1C},
 				{0x00,0x24,0x24},
 				{0x00,0x28,0x28},
 				{0x00,0x2C,0x2C},
@@ -468,6 +510,7 @@
 				{0x04,0x10,0x14},
 				{0x04,0x14,0x14},
 				{0x04,0x18,0x18},
+				{0x04,0x1C,0x08},
 				{0x04,0x24,0x24},
 				{0x04,0x28,0x28},
 				{0x04,0x2C,0x2C},
@@ -482,6 +525,7 @@
 				{0x08,0x10,0x18},
 				{0x08,0x14,0x18},
 				{0x08,0x18,0x18},
+				{0x08,0x1C,0x08},
 				{0x08,0x24,0x24},
 				{0x08,0x28,0x28},
 				{0x08,0x2C,0x2C},
@@ -496,6 +540,7 @@
 				{0x0C,0x10,0x18},
 				{0x0C,0x14,0x18},
 				{0x0C,0x18,0x18},
+				{0x0C,0x1C,0x08},
 				{0x0C,0x24,0x24},
 				{0x0C,0x28,0x28},
 				{0x0C,0x2C,0x2C},
@@ -510,6 +555,7 @@
 				{0x10,0x10,0x10},
 				{0x10,0x14,0x14},
 				{0x10,0x18,0x18},
+				{0x10,0x1C,0x18},
 				{0x10,0x24,0x24},
 				{0x10,0x28,0x28},
 				{0x10,0x2C,0x2C},
@@ -524,6 +570,7 @@
 				{0x14,0x10,0x14},
 				{0x14,0x14,0x14},
 				{0x14,0x18,0x18},
+				{0x14,0x1C,0x18},
 				{0x14,0x24,0x24},
 				{0x14,0x28,0x28},
 				{0x14,0x2C,0x2C},
@@ -538,6 +585,7 @@
 				{0x18,0x10,0x18},
 				{0x18,0x14,0x18},
 				{0x18,0x18,0x18},
+				{0x18,0x1C,0x18},
 				{0x18,0x24,0x24},
 				{0x18,0x28,0x28},
 				{0x18,0x2C,0x2C},
@@ -545,6 +593,21 @@
 				{0x18,0x34,0x34},
 				{0x18,0x38,0x34},
 				{0x18,0x3C,0x2C},
+				{0x1C,0x00,0x1C},
+				{0x1C,0x04,0x1C},
+				{0x1C,0x08,0x1C},
+				{0x1C,0x0C,0x1C},
+				{0x1C,0x10,0x18},
+				{0x1C,0x14,0x18},
+				{0x1C,0x18,0x18},
+				{0x1C,0x1C,0x18},
+				{0x1C,0x24,0x24},
+				{0x1C,0x28,0x28},
+				{0x1C,0x2C,0x2C},
+				{0x1C,0x30,0x30},
+				{0x1C,0x34,0x34},
+				{0x1C,0x38,0x34},
+				{0x1C,0x3C,0x2C},
 				{0x24,0x00,0x24},
 				{0x24,0x04,0x24},
 				{0x24,0x08,0x24},
@@ -552,6 +615,7 @@
 				{0x24,0x10,0x14},
 				{0x24,0x14,0x14},
 				{0x24,0x18,0x18},
+				{0x24,0x1C,0x08},
 				{0x24,0x24,0x24},
 				{0x24,0x28,0x28},
 				{0x24,0x2C,0x28},
@@ -566,6 +630,7 @@
 				{0x28,0x10,0x18},
 				{0x28,0x14,0x18},
 				{0x28,0x18,0x18},
+				{0x28,0x1C,0x08},
 				{0x28,0x24,0x24},
 				{0x28,0x28,0x28},
 				{0x28,0x2C,0x28},
@@ -580,6 +645,7 @@
 				{0x2C,0x10,0x18},
 				{0x2C,0x14,0x18},
 				{0x2C,0x18,0x18},
+				{0x2C,0x1C,0x08},
 				{0x2C,0x24,0x24},
 				{0x2C,0x28,0x28},
 				{0x2C,0x2C,0x2C},
@@ -594,6 +660,7 @@
 				{0x30,0x10,0x30},
 				{0x30,0x14,0x14},
 				{0x30,0x18,0x18},
+				{0x30,0x1C,0x1C},
 				{0x30,0x24,0x24},
 				{0x30,0x28,0x28},
 				{0x30,0x2C,0x2C},
@@ -608,6 +675,7 @@
 				{0x34,0x10,0x34},
 				{0x34,0x14,0x14},
 				{0x34,0x18,0x18},
+				{0x34,0x1C,0x1C},
 				{0x34,0x24,0x24},
 				{0x34,0x28,0x28},
 				{0x34,0x2C,0x2C},
@@ -622,6 +690,7 @@
 				{0x38,0x10,0x34},
 				{0x38,0x14,0x14},
 				{0x38,0x18,0x18},
+				{0x38,0x1C,0x1C},
 				{0x38,0x24,0x24},
 				{0x38,0x28,0x28},
 				{0x38,0x2C,0x2C},
@@ -636,6 +705,7 @@
 				{0x3C,0x10,0x10},
 				{0x3C,0x14,0x14},
 				{0x3C,0x18,0x18},
+				{0x3C,0x1C,0x1C},
 				{0x3C,0x24,0x24},
 				{0x3C,0x28,0x28},
 				{0x3C,0x2C,0x2C},
@@ -655,6 +725,7 @@
 		// def. non null + def. non null => def. non null
 		// def. non null + def. null => pot. n & pot. nn
 		// def. non null + def. unknown => def. unknown
+		// def. non null + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// def. non null + pot. n & pot. nn => pot. n & pot. nn
 		// def. non null + pot. n & pot. un => pot. n & pot. nn
 		// def. non null + pot. n & prot. n => pot. n & pot. nn
@@ -669,6 +740,7 @@
 		// def. null + def. non null => pot. n & pot. nn
 		// def. null + def. null => def. null
 		// def. null + def. unknown => pot. n & pot. un
+		// def. null + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// def. null + pot. n & pot. nn => pot. n & pot. nn
 		// def. null + pot. n & pot. un => pot. n & pot. un
 		// def. null + pot. n & prot. n => def. null
@@ -683,6 +755,7 @@
 		// def. unknown + def. non null => def. unknown
 		// def. unknown + def. null => pot. n & pot. un
 		// def. unknown + def. unknown => def. unknown
+		// def. unknown + pot. n & pot. nn & pot. un => pot. n & pot. nn // should ideally include un
 		// def. unknown + pot. n & pot. nn => pot. n & pot. nn
 		// def. unknown + pot. n & pot. un => pot. n & pot. un
 		// def. unknown + pot. n & prot. n => pot. n & pot. un
@@ -694,9 +767,25 @@
 		// def. unknown + prot. non null => def. unknown
 		// def. unknown + prot. null => def. unknown
 		// def. unknown + start => def. unknown
+		// pot. n & pot. nn & pot. un + def. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + def. null => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + def. unknown => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. nn & pot. un => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. null => pot. n & pot. nn
+		// pot. n & pot. nn & pot. un + pot. unknown => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + prot. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + prot. null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + start => pot. n & pot. nn & pot. un
 		// pot. n & pot. nn + def. non null => pot. n & pot. nn
 		// pot. n & pot. nn + def. null => pot. n & pot. nn
 		// pot. n & pot. nn + def. unknown => pot. n & pot. nn
+		// pot. n & pot. nn + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & pot. un => pot. n & pot. nn
 		// pot. n & pot. nn + pot. n & prot. n => pot. n & pot. nn
@@ -711,6 +800,7 @@
 		// pot. n & pot. un + def. non null => pot. n & pot. nn
 		// pot. n & pot. un + def. null => pot. n & pot. un
 		// pot. n & pot. un + def. unknown => pot. n & pot. un
+		// pot. n & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
 		// pot. n & pot. un + pot. n & prot. n => pot. n & pot. un
@@ -725,6 +815,7 @@
 		// pot. n & prot. n + def. non null => pot. n & pot. nn
 		// pot. n & prot. n + def. null => pot. n & prot. n
 		// pot. n & prot. n + def. unknown => pot. n & pot. un
+		// pot. n & prot. n + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
 		// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
@@ -739,6 +830,7 @@
 		// pot. nn & pot. un + def. non null => pot. nn & pot. un
 		// pot. nn & pot. un + def. null => pot. n & pot. nn
 		// pot. nn & pot. un + def. unknown => pot. nn & pot. un
+		// pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn
@@ -753,6 +845,7 @@
 		// pot. nn & prot. nn + def. non null => pot. nn & prot. nn
 		// pot. nn & prot. nn + def. null => pot. n & pot. nn
 		// pot. nn & prot. nn + def. unknown => pot. nn & pot. un
+		// pot. nn & prot. nn + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn
@@ -767,6 +860,7 @@
 		// pot. non null + def. non null => pot. non null
 		// pot. non null + def. null => pot. n & pot. nn
 		// pot. non null + def. unknown => pot. nn & pot. un
+		// pot. non null + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. non null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. non null + pot. n & pot. un => pot. n & pot. nn
 		// pot. non null + pot. n & prot. n => pot. n & pot. nn
@@ -781,6 +875,7 @@
 		// pot. null + def. non null => pot. n & pot. nn
 		// pot. null + def. null => pot. null
 		// pot. null + def. unknown => pot. n & pot. un
+		// pot. null + pot. n & pot. nn & pot. un => pot. n & pot. nn
 		// pot. null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. null + pot. n & pot. un => pot. n & pot. un
 		// pot. null + pot. n & prot. n => pot. null
@@ -795,6 +890,7 @@
 		// pot. unknown + def. non null => pot. nn & pot. un
 		// pot. unknown + def. null => pot. n & pot. un
 		// pot. unknown + def. unknown => pot. unknown
+		// pot. unknown + pot. n & pot. nn & pot. un => pot. n & pot. nn // should ideally include un
 		// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
 		// pot. unknown + pot. n & pot. un => pot. n & pot. un
 		// pot. unknown + pot. n & prot. n => pot. n & pot. un
@@ -809,6 +905,7 @@
 		// prot. non null + def. non null => pot. nn & prot. nn
 		// prot. non null + def. null => pot. null
 		// prot. non null + def. unknown => pot. unknown
+		// prot. non null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// prot. non null + pot. n & pot. nn => pot. n & pot. nn
 		// prot. non null + pot. n & pot. un => pot. n & pot. un
 		// prot. non null + pot. n & prot. n => pot. null
@@ -823,6 +920,7 @@
 		// prot. null + def. non null => pot. non null
 		// prot. null + def. null => pot. n & prot. n
 		// prot. null + def. unknown => pot. unknown
+		// prot. null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// prot. null + pot. n & pot. nn => pot. n & pot. nn
 		// prot. null + pot. n & pot. un => pot. n & pot. un
 		// prot. null + pot. n & prot. n => pot. n & prot. n
@@ -837,6 +935,7 @@
 		// start + def. non null => pot. non null
 		// start + def. null => pot. null
 		// start + def. unknown => pot. unknown
+		// start + pot. n & pot. nn & pot. un => pot. n & pot. nn // un?
 		// start + pot. n & pot. nn => pot. n & pot. nn
 		// start + pot. n & pot. un => pot. n & pot. un
 		// start + pot. n & prot. n => pot. null
@@ -860,6 +959,7 @@
 				{0x00,0x10,0x10},
 				{0x00,0x14,0x14},
 				{0x00,0x18,0x18},
+				{0x00,0x1C,0x18},
 				{0x00,0x24,0x04},
 				{0x00,0x28,0x08},
 				{0x00,0x2C,0x08},
@@ -874,6 +974,7 @@
 				{0x04,0x10,0x14},
 				{0x04,0x14,0x14},
 				{0x04,0x18,0x18},
+				{0x04,0x1C,0x18},
 				{0x04,0x24,0x04},
 				{0x04,0x28,0x0C},
 				{0x04,0x2C,0x0C},
@@ -888,6 +989,7 @@
 				{0x08,0x10,0x18},
 				{0x08,0x14,0x18},
 				{0x08,0x18,0x18},
+				{0x08,0x1C,0x18},
 				{0x08,0x24,0x0C},
 				{0x08,0x28,0x08},
 				{0x08,0x2C,0x08},
@@ -902,6 +1004,7 @@
 				{0x0C,0x10,0x18},
 				{0x0C,0x14,0x18},
 				{0x0C,0x18,0x18},
+				{0x0C,0x1C,0x18},
 				{0x0C,0x24,0x0C},
 				{0x0C,0x28,0x0C},
 				{0x0C,0x2C,0x0C},
@@ -916,6 +1019,7 @@
 				{0x10,0x10,0x10},
 				{0x10,0x14,0x14},
 				{0x10,0x18,0x18},
+				{0x10,0x1C,0x18},
 				{0x10,0x24,0x14},
 				{0x10,0x28,0x18},
 				{0x10,0x2C,0x18},
@@ -930,6 +1034,7 @@
 				{0x14,0x10,0x14},
 				{0x14,0x14,0x14},
 				{0x14,0x18,0x18},
+				{0x14,0x1C,0x18},
 				{0x14,0x24,0x14},
 				{0x14,0x28,0x18},
 				{0x14,0x2C,0x18},
@@ -944,6 +1049,7 @@
 				{0x18,0x10,0x18},
 				{0x18,0x14,0x18},
 				{0x18,0x18,0x18},
+				{0x18,0x1C,0x18},
 				{0x18,0x24,0x18},
 				{0x18,0x28,0x18},
 				{0x18,0x2C,0x18},
@@ -951,6 +1057,21 @@
 				{0x18,0x34,0x18},
 				{0x18,0x38,0x18},
 				{0x18,0x3C,0x18},
+				{0x1C,0x00,0x1C},
+				{0x1C,0x04,0x1C},
+				{0x1C,0x08,0x1C},
+				{0x1C,0x0C,0x1C},
+				{0x1C,0x10,0x18},
+				{0x1C,0x14,0x18},
+				{0x1C,0x18,0x18},
+				{0x1C,0x1C,0x18},
+				{0x1C,0x24,0x1C},
+				{0x1C,0x28,0x1C},
+				{0x1C,0x2C,0x1C},
+				{0x1C,0x30,0x18},
+				{0x1C,0x34,0x18},
+				{0x1C,0x38,0x1C},
+				{0x1C,0x3C,0x1C},
 				{0x24,0x00,0x24},
 				{0x24,0x04,0x24},
 				{0x24,0x08,0x24},
@@ -958,6 +1079,7 @@
 				{0x24,0x10,0x14},
 				{0x24,0x14,0x14},
 				{0x24,0x18,0x18},
+				{0x24,0x1C,0x18},
 				{0x24,0x24,0x24},
 				{0x24,0x28,0x24},
 				{0x24,0x2C,0x24},
@@ -972,6 +1094,7 @@
 				{0x28,0x10,0x18},
 				{0x28,0x14,0x18},
 				{0x28,0x18,0x18},
+				{0x28,0x1C,0x18},
 				{0x28,0x24,0x24},
 				{0x28,0x28,0x28},
 				{0x28,0x2C,0x28},
@@ -986,6 +1109,7 @@
 				{0x2C,0x10,0x18},
 				{0x2C,0x14,0x18},
 				{0x2C,0x18,0x18},
+				{0x2C,0x1C,0x18},
 				{0x2C,0x24,0x0C},
 				{0x2C,0x28,0x2C},
 				{0x2C,0x2C,0x2C},
@@ -1000,6 +1124,7 @@
 				{0x30,0x10,0x30},
 				{0x30,0x14,0x14},
 				{0x30,0x18,0x18},
+				{0x30,0x1C,0x18},
 				{0x30,0x24,0x14},
 				{0x30,0x28,0x18},
 				{0x30,0x2C,0x18},
@@ -1014,6 +1139,7 @@
 				{0x34,0x10,0x34},
 				{0x34,0x14,0x14},
 				{0x34,0x18,0x18},
+				{0x34,0x1C,0x18},
 				{0x34,0x24,0x14},
 				{0x34,0x28,0x18},
 				{0x34,0x2C,0x18},
@@ -1028,6 +1154,7 @@
 				{0x38,0x10,0x34},
 				{0x38,0x14,0x14},
 				{0x38,0x18,0x18},
+				{0x38,0x1C,0x1C},
 				{0x38,0x24,0x04},
 				{0x38,0x28,0x08},
 				{0x38,0x2C,0x08},
@@ -1042,6 +1169,7 @@
 				{0x3C,0x10,0x10},
 				{0x3C,0x14,0x14},
 				{0x3C,0x18,0x18},
+				{0x3C,0x1C,0x1C},
 				{0x3C,0x24,0x04},
 				{0x3C,0x28,0x2C},
 				{0x3C,0x2C,0x2C},
@@ -1061,45 +1189,72 @@
 		// mergedWith DEFINITION START
 		// def. non null + def. non null => def. non null
 		// def. non null + def. null => pot. n & pot. nn
+		// def. non null + pot. n & prot. n => pot. n & pot. nn
+		// def. non null + pot. nn & prot. nn => pot. nn & prot. nn
+		// def. non null + prot. non null => pot. nn & prot. nn
+		// def. non null + prot. null => pot. non null		 // PREMATURE should become tainted null & pot. nn... not really, depends on the three way merge... or even on the conditions that got there (pb with no contrib prot. null branch)
 		// def. null + def. null => def. null
-		// def. unknown + def. non null => def. unknown
+		// def. null + pot. n & prot. n => pot. n & prot. n
+		// def. null + prot. non null => pot. null
+		// def. null + prot. null => pot. n & prot. n
+		// def. unknown + def. non null => pot. nn & pot. un
 		// def. unknown + def. null => pot. n & pot. un // pot. n priv. over def. unknown
 		// def. unknown + def. unknown => def. unknown
+		// def. unknown + pot. n & prot. n => pot. n & pot. un
+		// def. unknown + pot. nn & prot. nn => pot. nn & pot. un
+		// def. unknown + prot. non null => def. unknown // test726
+		// def. unknown + prot. null => pot. unknown	// PREMATURE possibly wrong, but no test case yet
+		// pot. n & pot. nn & pot. un + def. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + def. null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + def. unknown => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + pot. nn & prot. nn => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + prot. non null => pot. n & pot. nn & pot. un
+		// pot. n & pot. nn & pot. un + prot. null => pot. n & pot. nn & pot. un
 		// pot. n & pot. nn + def. non null => pot. n & pot. nn
 		// pot. n & pot. nn + def. null => pot. n & pot. nn
 		// pot. n & pot. nn + def. unknown => pot. n & pot. nn
+		// pot. n & pot. nn + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. n & pot. nn + pot. n & pot. nn => pot. n & pot. nn
+		// pot. n & pot. nn + pot. n & prot. n => pot. n & pot. nn
+		// pot. n & pot. nn + pot. nn & prot. nn => pot. n & pot. nn
+		// pot. n & pot. nn + prot. non null => pot. n & pot. nn
+		// pot. n & pot. nn + prot. null => pot. n & pot. nn
 		// pot. n & pot. un + def. non null => pot. n & pot. nn
 		// pot. n & pot. un + def. null => pot. n & pot. un
 		// pot. n & pot. un + def. unknown => pot. n & pot. un
+		// pot. n & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. n & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. n & pot. un + pot. n & pot. un => pot. n & pot. un
-		// pot. n & prot. n + def. non null => pot. n & pot. nn
-		// pot. n & prot. n + def. null => pot. n & prot. n
-		// pot. n & prot. n + def. unknown => pot. n & pot. un
-		// pot. n & prot. n + pot. n & pot. nn => pot. n & pot. nn
-		// pot. n & prot. n + pot. n & pot. un => pot. n & pot. un
+		// pot. n & pot. un + pot. n & prot. n => pot. n & pot. un
+		// pot. n & pot. un + pot. nn & prot. nn => pot. n & pot. nn
+		// pot. n & pot. un + prot. non null => pot. n & pot. un
+		// pot. n & pot. un + prot. null => pot. n & pot. un
 		// pot. n & prot. n + pot. n & prot. n => pot. n & prot. n
+		// pot. n & prot. n + prot. non null => pot. null
+		// pot. n & prot. n + prot. null => pot. n & prot. n
 		// pot. nn & pot. un + def. non null => pot. nn & pot. un
 		// pot. nn & pot. un + def. null => pot. n & pot. nn
 		// pot. nn & pot. un + def. unknown => pot. nn & pot. un
+		// pot. nn & pot. un + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. nn & pot. un + pot. n & pot. nn => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & pot. un + pot. n & prot. n => pot. n & pot. nn
 		// pot. nn & pot. un + pot. nn & pot. un => pot. nn & pot. un
+		// pot. nn & pot. un + pot. nn & prot. nn => pot. nn & pot. un
 		// pot. nn & pot. un + pot. null => pot. n & pot. nn
-		// pot. nn & prot. nn + def. non null => pot. nn & prot. nn
+		// pot. nn & pot. un + prot. non null => pot. nn & pot. un
+		// pot. nn & pot. un + prot. null => pot. n & pot. nn
 		// pot. nn & prot. nn + def. null => pot. n & pot. nn
-		// pot. nn & prot. nn + def. unknown => pot. nn & pot. un
-		// pot. nn & prot. nn + pot. n & pot. nn => pot. n & pot. nn
-		// pot. nn & prot. nn + pot. n & pot. un => pot. n & pot. nn
 		// pot. nn & prot. nn + pot. n & prot. n => pot. n & pot. nn
-		// pot. nn & prot. nn + pot. nn & pot. un => pot. nn & pot. un
 		// pot. nn & prot. nn + pot. nn & prot. nn => pot. nn & prot. nn
-		// pot. nn & prot. nn + pot. null => pot. n & pot. nn
+		// pot. nn & prot. nn + prot. non null => pot. nn & prot. nn
+		// pot. nn & prot. nn + prot. null => pot. n & pot. nn
 		// pot. non null + def. non null => pot. non null
 		// pot. non null + def. null => pot. n & pot. nn
 		// pot. non null + def. unknown => pot. nn & pot. un
+		// pot. non null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. non null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. non null + pot. n & pot. un => pot. n & pot. nn
 		// pot. non null + pot. n & prot. n => pot. n & pot. nn
@@ -1107,16 +1262,23 @@
 		// pot. non null + pot. nn & prot. nn => pot. non null
 		// pot. non null + pot. non null => pot. non null
 		// pot. non null + pot. null => pot. n & pot. nn
+		// pot. non null + prot. non null => pot. non null
+		// pot. non null + prot. null => pot. n & pot. nn
 		// pot. null + def. non null => pot. n & pot. nn
 		// pot. null + def. null => pot. null
 		// pot. null + def. unknown => pot. n & pot. un
+		// pot. null + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. null + pot. n & pot. nn => pot. n & pot. nn
 		// pot. null + pot. n & pot. un => pot. n & pot. un
 		// pot. null + pot. n & prot. n => pot. null
+		// pot. null + pot. nn & prot. nn => pot. n & pot. nn
 		// pot. null + pot. null => pot. null
+		// pot. null + prot. non null => pot. null
+		// pot. null + prot. null => pot. null
 		// pot. unknown + def. non null => pot. nn & pot. un
 		// pot. unknown + def. null => pot. n & pot. un
 		// pot. unknown + def. unknown => pot. unknown
+		// pot. unknown + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// pot. unknown + pot. n & pot. nn => pot. n & pot. nn
 		// pot. unknown + pot. n & pot. un => pot. n & pot. un
 		// pot. unknown + pot. n & prot. n => pot. n & pot. un
@@ -1125,34 +1287,15 @@
 		// pot. unknown + pot. non null => pot. nn & pot. un
 		// pot. unknown + pot. null => pot. n & pot. un
 		// pot. unknown + pot. unknown => pot. unknown
-		// prot. non null + def. non null => pot. nn & prot. nn
-		// prot. non null + def. null => pot. null
-		// prot. non null + def. unknown => def. unknown // test726
-		// prot. non null + pot. n & pot. nn => pot. n & pot. nn
-		// prot. non null + pot. n & pot. un => pot. n & pot. un
-		// prot. non null + pot. n & prot. n => pot. null
-		// prot. non null + pot. nn & pot. un => pot. nn & pot. un
-		// prot. non null + pot. nn & prot. nn => pot. nn & prot. nn
-		// prot. non null + pot. non null => pot. non null
-		// prot. non null + pot. null => pot. null
-		// prot. non null + pot. unknown => pot. unknown
+		// pot. unknown + prot. non null => pot. unknown
+		// pot. unknown + prot. null => pot. unknown // PREMATURE possibly wrong, but no test case yet
 		// prot. non null + prot. non null => prot. non null
-		// prot. non null + prot. null => pot. null // PREMATURE use tainted instead
-		// prot. null + def. non null => pot. non null		 // PREMATURE should become tainted null & pot. nn... not really, depends on the three way merge... or even on the conditions that got there (pb with no contrib prot. null branch)
-		// prot. null + def. null => pot. n & prot. n
-		// prot. null + def. unknown => pot. unknown	// PREMATURE possibly wrong, but no test case yet
-		// prot. null + pot. n & pot. nn => pot. n & pot. nn
-		// prot. null + pot. n & pot. un => pot. n & pot. un
-		// prot. null + pot. n & prot. n => pot. n & prot. n
-		// prot. null + pot. nn & pot. un => pot. n & pot. nn
-		// prot. null + pot. nn & prot. nn => pot. n & pot. nn
-		// prot. null + pot. non null => pot. n & pot. nn
-		// prot. null + pot. null => pot. null
-		// prot. null + pot. unknown => pot. unknown // PREMATURE possibly wrong, but no test case yet
+		// prot. null + prot. non null => pot. null // PREMATURE use tainted instead
 		// prot. null + prot. null => prot. null
 		// start + def. non null => pot. non null
 		// start + def. null => pot. null
 		// start + def. unknown => pot. unknown
+		// start + pot. n & pot. nn & pot. un => pot. n & pot. nn & pot. un
 		// start + pot. n & pot. nn => pot. n & pot. nn
 		// start + pot. n & pot. un => pot. n & pot. un
 		// start + pot. n & prot. n => pot. null
@@ -1195,6 +1338,8 @@
 				{0x04,0x2C,0x0C},
 				{0x04,0x30,0x14},
 				{0x04,0x34,0x14},
+				{0x04,0x38,0x04},
+				{0x04,0x3C,0x04},
 				{0x08,0x08,0x08},
 				{0x08,0x0C,0x0C},
 				{0x08,0x10,0x18},
@@ -1206,6 +1351,8 @@
 				{0x08,0x2C,0x08},
 				{0x08,0x30,0x18},
 				{0x08,0x34,0x18},
+				{0x08,0x38,0x18},
+				{0x08,0x3C,0x08},
 				{0x0C,0x0C,0x0C},
 				{0x0C,0x10,0x18},
 				{0x0C,0x14,0x18},
@@ -1213,29 +1360,42 @@
 				{0x0C,0x1C,0x1C},
 				{0x0C,0x24,0x0C},
 				{0x0C,0x28,0x0C},
+				{0x0C,0x2C,0x0C},
 				{0x0C,0x30,0x18},
 				{0x0C,0x34,0x18},
+				{0x0C,0x38,0x18},
+				{0x0C,0x3C,0x0C},
 				{0x10,0x10,0x10},
 				{0x10,0x14,0x14},
 				{0x10,0x18,0x18},
 				{0x10,0x1C,0x1C},
 				{0x10,0x24,0x14},
 				{0x10,0x28,0x18},
+				{0x10,0x2C,0x18},
 				{0x10,0x30,0x10},
 				{0x10,0x34,0x10},
+				{0x10,0x38,0x10},
+				{0x10,0x3C,0x10},
 				{0x14,0x14,0x14},
 				{0x14,0x18,0x18},
 				{0x14,0x1C,0x1C},
 				{0x14,0x24,0x14},
 				{0x14,0x28,0x18},
+				{0x14,0x2C,0x18},
 				{0x14,0x30,0x14},
+				{0x14,0x34,0x14},
+				{0x14,0x38,0x14},
+				{0x14,0x3C,0x14},
 				{0x18,0x18,0x18},
 				{0x18,0x1C,0x1C},
 				{0x18,0x24,0x18},
 				{0x18,0x28,0x18},
+				{0x18,0x2C,0x18},
 				{0x18,0x30,0x18},
+				{0x18,0x34,0x18},
+				{0x18,0x38,0x18},
+				{0x18,0x3C,0x18},
 				{0x1C,0x1C,0x1C},
-				{0x1C,0x20,0x1C},
 				{0x1C,0x24,0x1C},
 				{0x1C,0x28,0x1C},
 				{0x1C,0x2C,0x1C},
@@ -1245,49 +1405,31 @@
 				{0x1C,0x3C,0x1C},
 				{0x24,0x24,0x24},
 				{0x24,0x28,0x0C},
+				{0x24,0x2C,0x0C},
 				{0x24,0x30,0x14},
+				{0x24,0x34,0x14},
+				{0x24,0x38,0x04},
+				{0x24,0x3C,0x24},
 				{0x28,0x28,0x28},
+				{0x28,0x2C,0x2C},
 				{0x28,0x30,0x18},
-				{0x2C,0x0C,0x0C},
-				{0x2C,0x10,0x18},
-				{0x2C,0x14,0x18},
-				{0x2C,0x18,0x18},
-				{0x2C,0x24,0x0C},
-				{0x2C,0x28,0x2C},
+				{0x28,0x34,0x18},
+				{0x28,0x38,0x08},
+				{0x28,0x3C,0x2C},
 				{0x2C,0x2C,0x2C},
 				{0x2C,0x30,0x18},
 				{0x2C,0x34,0x18},
+				{0x2C,0x38,0x18},
+				{0x2C,0x3C,0x2C},
 				{0x30,0x30,0x30},
-				{0x34,0x14,0x14},
-				{0x34,0x18,0x18},
-				{0x34,0x24,0x14},
-				{0x34,0x28,0x18},
-				{0x34,0x30,0x34},
+				{0x30,0x34,0x34},
+				{0x30,0x38,0x34},
+				{0x30,0x3C,0x10},
 				{0x34,0x34,0x34},
-				{0x38,0x04,0x04},
-				{0x38,0x08,0x18},
-				{0x38,0x0C,0x18},
-				{0x38,0x10,0x10},
-				{0x38,0x14,0x14},
-				{0x38,0x18,0x18},
-				{0x38,0x24,0x04},
-				{0x38,0x28,0x08},
-				{0x38,0x2C,0x18},
-				{0x38,0x30,0x34},
-				{0x38,0x34,0x34},
+				{0x34,0x38,0x34},
+				{0x34,0x3C,0x10},
 				{0x38,0x38,0x38},
-				{0x3C,0x04,0x04},
-				{0x3C,0x08,0x08},
-				{0x3C,0x0C,0x0C},
-				{0x3C,0x10,0x10},
-				{0x3C,0x14,0x14},
-				{0x3C,0x18,0x18},
-				{0x3C,0x24,0x24},
-				{0x3C,0x28,0x2C},
-				{0x3C,0x2C,0x2C},
-				{0x3C,0x30,0x10},
-				{0x3C,0x34,0x10},
-				{0x3C,0x38,0x10},
+				{0x38,0x3C,0x10},
 				{0x3C,0x3C,0x3C},
 				// mergedWith INITIALIZER END
 				}) {
@@ -1838,6 +1980,7 @@
 						// loop
 					}
 					int i, length;
+					// definitions of two-dim trafos in natural order (by state value):
 					for (i = 0, length = consideredStates.length; i < length; i++) {
 						output.write(tab);
 						output.write("// ");
@@ -2033,26 +2176,41 @@
 abstract UnconditionalFlowInfo output(UnconditionalFlowInfo input1, UnconditionalFlowInfo input2);
 void printDefinitions(BufferedWriter output, State[] consideredStates, String tab)
 		throws IOException {
-	int i, j, length;
+	int i, j, length = consideredStates.length;
 	State result;
-	for (i = 0, length = consideredStates.length; i < length; i++) {
+	// temporary store to support lexical sorting:
+	String[] lines = new String[length * length];
+	int lCount = 0;
+	for (i = 0; i < length; i++) {
 		for (j = 0; j < length; j++) {
-			output.write(tab);
-			output.write("// ");
-			output.write(consideredStates[i].name);
-			output.write(" + ");
-			output.write(consideredStates[j].name);
-			output.write(" => ");
-			output.write(
-				(result = (State)
-					((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name);
+			StringBuffer line = new StringBuffer();
+			line.append(tab);
+			line.append("// ");
+			line.append(consideredStates[i].name);
+			line.append(" + ");
+			line.append(consideredStates[j].name);
+			line.append(" => ");
+			line.append(
+				(result = (State) getResult(this.computedTransitions, consideredStates[i], consideredStates[j])).name);
 			if (!result.symbolic ||
-				result != this.initializedTransitions.get(consideredStates[i])) {
-				output.write("\t\t CHECK");
+				result != getResult(this.initializedTransitions, consideredStates[i], consideredStates[j])) {
+				line.append("\t\t CHECK");
 			}
-			output.write('\n');
+			line.append('\n');
+			lines[lCount++] = line.toString();
 		}
 	}
+	Arrays.sort(lines);
+	for (i = 0; i < lCount; i++) {
+		output.write(lines[i]);
+	}
+}
+Object getResult(Map transitions, State statei, State statej) {
+	Object res1 = transitions.get(statei);
+	if (res1 instanceof Map) {
+		return ((Map)res1).get(statej);
+	}
+	return null;
 }
 void printInitializers(BufferedWriter output, State[] consideredStates, String tab)
 		throws IOException {
@@ -2822,26 +2980,40 @@
 		throws IOException {
 	// only difference with parent is that we print only half of possible
 	// combinations
-	int i, j, length;
+	int i, j, length = consideredStates.length;
 	State result;
-	for (i = 0, length = consideredStates.length; i < length; i++) {
+	// temporary store to support lexical sorting:
+	String[] lines = new String[length * (length +1) / 2 ];
+	int lCount = 0;
+	for (i = 0; i < length; i++) {
 		for (j = i; j < length; j++) {
-			output.write(tab);
-			output.write("// ");
-			output.write(consideredStates[i].name);
-			output.write(" + ");
-			output.write(consideredStates[j].name);
-			output.write(" => ");
-			output.write(
-				(result = (State)
-					((Map) this.computedTransitions.get(consideredStates[i])).get(consideredStates[j])).name);
+			StringBuffer line = new StringBuffer();
+			line.append(tab);
+			line.append("// ");
+			line.append(consideredStates[i].name);
+			line.append(" + ");
+			line.append(consideredStates[j].name);
+			line.append(" => ");
+			line.append(
+				(result = (State) getResult(this.computedTransitions, consideredStates[i], consideredStates[j])).name);
 			if (!result.symbolic ||
-				result != this.initializedTransitions.get(consideredStates[i])) {
-				output.write("\t\t CHECK");
+				result != getResult(this.initializedTransitions, consideredStates[i], consideredStates[j])) {
+				line.append("\t\t CHECK");
 			}
-			output.write('\n');
+			line.append('\n');
+			lines[lCount++] = line.toString();
 		}
 	}
+	Arrays.sort(lines);
+	for (i = 0; i < lCount; i++) {
+		output.write(lines[i]);
+	}
+}
+Object getResult(Map transitions, State statei, State statej) {
+	Object r = super.getResult(transitions, statei, statej);
+	if (r == null)
+		r = super.getResult(transitions, statej, statei);
+	return r;
 }
 void printInitializers(BufferedWriter output, State[] consideredStates, String tab)
 		throws IOException {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index 859331b..cfd4783 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -35,6 +35,9 @@
  *							bug 384380 - False positive on a "Potential null pointer access" after a continue
  *							bug 406384 - Internal error with I20130413
  *							Bug 364326 - [compiler][null] NullPointerException is not found by compiler. FindBugs finds that one
+ *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
+ *							Bug 195638 - [compiler][null][refactoring] Wrong error : "Null pointer access: The variable xxx can only be null at this location " with try..catch in loop
+ *							Bug 454031 - [compiler][null][loop] bug in null analysis; wrong "dead code" detection
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -63,9 +66,12 @@
 // Only the highest compliance level is run; add the VM argument
 // -Dcompliance=1.4 (for example) to lower it if needed
 static {
-//		TESTS_NAMES = new String[] { "test0037_autounboxing_3" };
-//		TESTS_NAMES = new String[] { "testBug401088" };
-//		TESTS_NAMES = new String[] { "testBug402993" };
+//		TESTS_NAMES = new String[] { "test0525_try_finally_unchecked_exception" };
+//		TESTS_NAMES = new String[] { "testBug441737" };
+//		TESTS_NAMES = new String[] { "testBug453305" };
+//		TESTS_NAMES = new String[] { "testBug431016" };
+//		TESTS_NAMES = new String[] { "testBug432109" };
+//		TESTS_NAMES = new String[] { "testBug418500" }; 
 //		TESTS_NUMBERS = new int[] { 561 };
 //		TESTS_RANGE = new int[] { 1, 2049 };
 }
@@ -5650,7 +5656,7 @@
 
 // null analysis -- try/finally
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=150082
-public void test0525_try_finally_unchecked_exception() {
+public void _test0525_try_finally_unchecked_exception() {
 	this.runNegativeTest(
 		new String[] {
 			"X.java",
@@ -8501,7 +8507,7 @@
 
 // null analysis - for
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195638
-public void _test0746_for_try_catch() {
+public void test0746_for_try_catch() {
 	runTest(
 		new String[] {
 			"X.java",
@@ -11706,7 +11712,7 @@
 						"  void foo(int[] argArray) {\n" +
 						"    int[] array = {2};\n" +
 						"    int[] collectionVar = {1,2};\n" +
-						"	 if(argArray == null) return;" +
+						"	 if(argArray == null) return;\n" +
 						"    for(int x:collectionVar) {\n" +
 						"        if (collectionVar == null);\n" +	// collectionVar cannot be null here
 						"        if (array == null);\n" +				// array is not null here
@@ -11718,6 +11724,8 @@
 						"        if (array == null);\n" +				// array is not null here
 						"		 if (argArray == null);\n" +		// argArray cannot be null here
 						"    } while (count<10);\n" +
+						"	 array = new int[0];\n" + 			// reset tainting by null check
+						"	 if (argArray == null) return;\n" + // reset tainting by null check
 						"    for (int i=0; i<2; i++) {\n" +
 						"        if (array == null);\n" +				// array is not null here
 						"		 if (argArray == null);\n" +		// argArray cannot be null here
@@ -11729,47 +11737,47 @@
 						"  }\n" +
 						"}"},
 				"----------\n" +
-				"1. ERROR in X.java (at line 6)\n" +
+				"1. ERROR in X.java (at line 7)\n" +
 				"	if (collectionVar == null);\n" +
 				"	    ^^^^^^^^^^^^^\n" +
 				"Null comparison always yields false: The variable collectionVar cannot be null at this location\n" +
 				"----------\n" +
-				"2. ERROR in X.java (at line 7)\n" +
+				"2. ERROR in X.java (at line 8)\n" +
 				"	if (array == null);\n" +
 				"	    ^^^^^\n" +
 				"Null comparison always yields false: The variable array cannot be null at this location\n" +
 				"----------\n" +
-				"3. ERROR in X.java (at line 8)\n" +
+				"3. ERROR in X.java (at line 9)\n" +
 				"	if (argArray == null);\n" +
 				"	    ^^^^^^^^\n" +
 				"Null comparison always yields false: The variable argArray cannot be null at this location\n" +
 				"----------\n" +
-				"4. ERROR in X.java (at line 13)\n" +
+				"4. ERROR in X.java (at line 14)\n" +
 				"	if (array == null);\n" +
 				"	    ^^^^^\n" +
 				"Null comparison always yields false: The variable array cannot be null at this location\n" +
 				"----------\n" +
-				"5. ERROR in X.java (at line 14)\n" +
+				"5. ERROR in X.java (at line 15)\n" +
 				"	if (argArray == null);\n" +
 				"	    ^^^^^^^^\n" +
 				"Null comparison always yields false: The variable argArray cannot be null at this location\n" +
 				"----------\n" +
-				"6. ERROR in X.java (at line 17)\n" +
+				"6. ERROR in X.java (at line 20)\n" +
 				"	if (array == null);\n" +
 				"	    ^^^^^\n" +
 				"Null comparison always yields false: The variable array cannot be null at this location\n" +
 				"----------\n" +
-				"7. ERROR in X.java (at line 18)\n" +
+				"7. ERROR in X.java (at line 21)\n" +
 				"	if (argArray == null);\n" +
 				"	    ^^^^^^^^\n" +
 				"Null comparison always yields false: The variable argArray cannot be null at this location\n" +
 				"----------\n" +
-				"8. ERROR in X.java (at line 21)\n" +
+				"8. ERROR in X.java (at line 24)\n" +
 				"	if (array == null);\n" +
 				"	    ^^^^^\n" +
 				"Null comparison always yields false: The variable array cannot be null at this location\n" +
 				"----------\n" +
-				"9. ERROR in X.java (at line 22)\n" +
+				"9. ERROR in X.java (at line 25)\n" +
 				"	if (argArray == null);\n" +
 				"	    ^^^^^^^^\n" +
 				"Null comparison always yields false: The variable argArray cannot be null at this location\n" +
@@ -14699,12 +14707,38 @@
 		"	o1 = null;\n" + 
 		"	^^\n" + 
 		"Redundant assignment: The variable o1 can only be null at this location\n" + 
+/* In general it's safer *not* to assume that o1 is null on every iteration (see also testBug336428d2):
 		"----------\n" + 
 		"2. ERROR in DoWhileBug.java (at line 8)\n" + 
 		"	if ((o2 = o1) == null) break;\n" + 
 		"	    ^^^^^^^^^\n" + 
 		"Redundant null check: The variable o2 can only be null at this location\n" + 
-		"----------\n");
+ */
+		"----------\n"
+		);
+}
+
+// Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+// variant after Bug 454031 to demonstrate:
+// - previously we would believe that o1 is always null in the assignment to o2 -> bogus warning re redundant null check
+// - with improved analysis we don't claim to know the value of o1 in this assignment -> no warning
+public void testBug336428d2() {
+	this.runConformTest(
+		new String[] {
+	"DoWhileBug.java",
+			"public class DoWhileBug {\n" + 
+			"	void test(boolean b1) {\n" + 
+			"		Object o1 = null;\n" + 
+			"		Object o2 = null;\n" + 
+			"		do {\n" +
+			"           if (b1)\n" + 
+			"				o1 = null;\n" +
+			"           if ((o2 = o1) == null) System.out.println(\"null\");\n" +
+			"			o1 = new Object();\n" +
+			"		} while (true);\n" + 
+			"	}\n" + 
+			"}"	
+		});
 }
 
 //Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
@@ -14731,11 +14765,13 @@
 			"	o1 = null;\n" + 
 			"	^^\n" + 
 			"Redundant assignment: The variable o1 can only be null at this location\n" + 
+/* In general it's safer *not* to assume that o1 is null on every iteration:
 			"----------\n" +
 			"2. ERROR in DoWhileBug.java (at line 8)\n" + 
 			"	assert (o2 = o1) != null : \"bug\";\n" + 
 			"	       ^^^^^^^^^\n" + 
 			"Null comparison always yields false: The variable o2 can only be null at this location\n" + 
+ */
 			"----------\n");
 	}
 }
@@ -16398,8 +16434,8 @@
 }
 
 // Bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
-// DISABLED: block-less if involved - info about pot.nn. is lost when checking against loop's info (deferred check)
-public void _testBug345305_6() {
+// block-less if involved - info about pot.nn. was lost when checking against loop's info (deferred check)
+public void testBug345305_6() {
 	runNegativeTest(
 		new String[] {
 			"X.java",
@@ -17011,4 +17047,384 @@
 		"Redundant null check: The variable exc can only be null at this location\n" + 
 		"----------\n");
 }
+public void testBug453305() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses foreach loop
+	runConformTest(
+		new String[] {
+			"NullTest.java",
+			"import java.util.*;\n" + 
+			"public class NullTest {\n" + 
+			"    class SomeOtherClass {\n" + 
+			"\n" + 
+			"        public SomeOtherClass m() {\n" + 
+			"            return new SomeOtherClass();\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        public void doSomething() {\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    public Object m1() {\n" + 
+			"        SomeOtherClass result = null;\n" + 
+			"        List<Object> list = new ArrayList<Object>();\n" + 
+			"        for (Object next : list) {\n" + 
+			"            System.out.println(next);\n" + 
+			"            boolean bool = false;\n" + 
+			"            if (bool) {\n" + 
+			"                SomeOtherClass something = new SomeOtherClass();\n" + 
+			"                result = something.m();\n" + 
+			"            } else {\n" + 
+			"                result = new SomeOtherClass();\n" + 
+			"            }\n" + 
+			"            result.doSomething(); // warning is here\n" + 
+			"            break;\n" + 
+			"        }\n" + 
+			"        return null;\n" + 
+			"    }\n" + 
+			"}\n"
+		});
 }
+public void testBug431016() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses foreach loop
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"public class Test {\n" + 
+			"  void test(Object[] values) {\n" + 
+			"    Object first = null;\n" + 
+			"    for (Object current : values) {\n" + 
+			"        if (first == null) {\n" + 
+			"            first = current;\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        if (current.hashCode() > 0) {\n" + 
+			"            System.out.println(first.hashCode());\n" + 
+			"        }\n" + 
+			"\n" + 
+			"        System.out.println(first.hashCode());\n" + 
+			"      }\n" + 
+			"  }\n" + 
+			"}\n"
+		});
+}
+// originally created for documentation purpose, see https://bugs.eclipse.org/453483#c9
+public void testBug431016_simplified() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"public class Test {\n" + 
+			"  void test(Object input, boolean b) {\n" + 
+			"    Object o = null;\n" + 
+			"    while (true) {\n" + 
+			"      if (o == null)\n" + 
+			"        o = input;\n" + 
+			"      if (b)\n" + 
+			"        o.toString();\n" + 
+			"      o.toString();\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n"
+		});
+}
+public void testBug432109() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // uses generics & foreach loop
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.util.Collection;\n" +
+			"public class Test {\n" +
+			"  public void test(Collection <Object> values)\n" + 
+			"  {\n" + 
+			"      boolean condition = false;\n" + 
+			"      \n" + 
+			"      for(Object value : values)\n" + 
+			"      {\n" + 
+			"                  \n" + 
+			"          if(value == null)\n" + 
+			"          {\n" + 
+			"              if( condition )\n" + 
+			"              {\n" + 
+			"                  // without this continue statement, \n" + 
+			"                  // there is no warning below\n" + 
+			"                  continue; \n" + 
+			"              }\n" + 
+			"              \n" + 
+			"              value = getDefaultValue();\n" + 
+			"          }\n" + 
+			"          \n" + 
+			"          // IDE complains here about potential null pointer access\n" + 
+			"          value.toString();\n" + 
+			"      }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public String getDefaultValue() { return \"<empty>\"; }\n" +
+			"}\n"
+		});
+}
+public void testBug435528() {
+	runNegativeTest(
+		new String[] {
+			"Test.java",
+			"public class Test\n" + 
+			"{\n" + 
+			"   static final String a = \"A\";\n" + 
+			"\n" + 
+			"   static void main(String args[])\n" + 
+			"   {\n" + 
+			"      String x = null;\n" + 
+			"      while (true) {\n" + 
+			"         x = Math.random() < 0.5 ? a : \"BB\";\n" + 
+			"         if (a != null) {\n" + 
+			"            System.out.println(\"s2 value: \" + x);\n" + 
+			"         }\n" + 
+			"         if (x.equals(\"A\")) {\n" + 
+			"            break;\n" + 
+			"         } else {\n" + 
+			"            x = null;\n" + 
+			"         }\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 15)\n" + 
+		"	} else {\n" + 
+		"            x = null;\n" + 
+		"         }\n" + 
+		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + 
+		"----------\n");
+}
+public void testBug418500() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.util.*;\n" +
+			"public class Test {\n" +
+			(this.complianceLevel < ClassFileConstants.JDK1_5 ? "\n" : "  @SuppressWarnings(\"unchecked\")\n" ) +
+			"  void method() {\n" + 
+			"    Map topMap = new HashMap();\n" + 
+			"    List targets = null;\n" + 
+			"    \n" + 
+			"    for (int idx = 1; idx < 100; idx++) {\n" + 
+			"      String[] targetArray = (String[]) topMap.get(\"a\");\n" + 
+			"      if (targetArray != null) {\n" + 
+			"        targets = Arrays.asList(targetArray);\n" + 
+			"      } else {\n" + 
+			"        targets = new ArrayList(64);\n" + 
+			"      }\n" + 
+			"      if (targets.size() > 0) {\n" + 
+			"        topMap.put(\"b\", targets.toArray(new String[1]));\n" + 
+			"      } else {\n" + 
+			"        topMap.remove(\"b\");\n" + 
+			"      }\n" + 
+			"\n" + 
+			"      // BUG - this statement causes null analysis to\n" + 
+			"      // report that at the targets.size() statement above\n" + 
+			"      // targets must be null. Commenting this line eliminates the error.\n" + 
+			"      targets = null;\n" + 
+			"    }\n" + 
+			"  }\n" +
+			"}\n"
+		});
+}
+public void testBug441737() {
+	runConformTest(
+		new String[] {
+			"Bogus.java",
+			"public class Bogus {\n" + 
+			"    static boolean ok = true;\n" + 
+			"    static int count = 0;\n" + 
+			"    public static void main(String[] args) {\n" + 
+			"        Thing x = new Thing();\n" + 
+			"        // if y is left uninitialized here, the warning below disappears\n" + 
+			"        Thing y = null;\n" + 
+			"        do {\n" + 
+			"            y = x;\n" + 
+			"            if (ok) {\n" + 
+			"                // if this assignment is moved out of the if statement\n" + 
+			"                // or commented out, the warning below disappears\n" + 
+			"                x = y.resolve();\n" + 
+			"            }\n" + 
+			"            // a warning about y being potentially null occurs here:\n" + 
+			"            x = y.resolve();\n" + 
+			"        } while (x != y);\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    static class Thing {\n" + 
+			"        public Thing resolve() {\n" + 
+			"            return count++ > 2 ? this : new Thing();\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"}\n"
+		});
+}
+// fixed in 3.6.2, likely via bug 332637.
+public void testBug195638_comment3() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.sql.Connection;\n" +
+			"import java.sql.SQLException;\n" +
+			"public class Test {\n" + 
+			"  void m() throws SQLException\n" + 
+			"  {\n" + 
+			"    Connection conn = null;\n" + 
+			"    try\n" + 
+			"    {\n" + 
+			"      conn = createConnection();\n" + 
+			"\n" + 
+			"      for (; ; )\n" + 
+			"      {\n" + 
+			"        throwSomething();\n" + 
+			"      }\n" + 
+			"    }\n" + 
+			"    catch (MyException e)\n" + 
+			"    {\n" + 
+			"      conn.rollback(); //The variable can never be null here...\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  private void throwSomething() throws MyException\n" + 
+			"  {\n" + 
+			"    throw new MyException();\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  class MyException extends Exception\n" + 
+			"  {\n" + 
+			"\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  private Connection createConnection()\n" + 
+			"  {\n" + 
+			"    return null;\n" + 
+			"  }\n" +
+			"}\n"
+		});
+}
+public void testBug195638_comment6() {
+	runNegativeTest(
+		new String[] {
+			"CanOnlyBeNullShouldBeMayBeNull.java",
+			"public class CanOnlyBeNullShouldBeMayBeNull {\n" + 
+			"\n" + 
+			"	private void method() {\n" + 
+			"		String tblVarRpl = null;\n" + 
+			"		while (true) {\n" + 
+			"			boolean isOpenVariableMortageRateProduct = true;\n" + 
+			"			boolean tblVarRplAllElementAddedIndicator = false;\n" + 
+			"			if (isOpenVariableMortageRateProduct) {\n" + 
+			"				if (tblVarRplAllElementAddedIndicator == false)\n" + 
+			"					tblVarRpl = \"\";\n" + 
+			"				tblVarRpl.substring(1);	//Can only be null???\n" + 
+			"				return; \n" + 
+			"			}\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in CanOnlyBeNullShouldBeMayBeNull.java (at line 3)\n" + 
+		"	private void method() {\n" + 
+		"	             ^^^^^^^^\n" + 
+		"The method method() from the type CanOnlyBeNullShouldBeMayBeNull is never used locally\n" + 
+		"----------\n" + 
+		"2. ERROR in CanOnlyBeNullShouldBeMayBeNull.java (at line 11)\n" + 
+		"	tblVarRpl.substring(1);	//Can only be null???\n" + 
+		"	^^^^^^^^^\n" + 
+		"Potential null pointer access: The variable tblVarRpl may be null at this location\n" + 
+		"----------\n");
+}
+public void testBug195638_comment14() {
+	runNegativeTest(
+		new String[] {
+			"Test.java",
+			"public class Test {\n" + 
+			"    private void test() {\n" + 
+			"        boolean x = true;\n" + 
+			"        Object o = null;\n" + 
+			"        \n" + 
+			"        for (;;) {\n" + 
+			"            if (x) o = new Object();\n" + 
+			"            \n" + 
+			"            o.toString(); // warning here\n" + // bug was: Null pointer access: The variable o can only be null at this location
+			"            \n" + 
+			"            o = null;\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 2)\n" + 
+		"	private void test() {\n" + 
+		"	             ^^^^^^\n" + 
+		"The method test() from the type Test is never used locally\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 9)\n" + 
+		"	o.toString(); // warning here\n" + 
+		"	^\n" + 
+		"Potential null pointer access: The variable o may be null at this location\n" + 
+		"----------\n");
+}
+public void testBug195638_comment19() {
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"public class Test {\n" + 
+			"    public void testIt() {\n" + 
+			"      Object aRole = null;\n" + 
+			"      for (;;) {\n" + 
+			"        aRole = new Object();\n" + 
+			"        if (aRole.toString() == null) {\n" + 
+			"          aRole = getObject(); // changing to \"new Object()\" makes warning disappear.\n" + 
+			"        }\n" + 
+			"        aRole.toString();\n" + 
+			"        // above line gets: \"Null pointer access: The variable aRole can only be null at this location\"\n" + 
+			"        break;\n" + 
+			"      }\n" + 
+			"    }\n" + 
+			"    private Object getObject() {\n" + 
+			"      return new Object();\n" + 
+			"    }\n" + 
+			"}\n"
+		});
+}
+public void testBug454031() {
+	runNegativeTest(
+		new String[] {
+			"xy/Try.java",
+			"package xy;\n" + 
+			"\n" + 
+			"public class Try {\n" + 
+			"    public static void main(String[] args) {\n" + 
+			"        foo(new Node());\n" + 
+			"    }\n" + 
+			"    static void foo(Node n) {\n" + 
+			"        Node selectedNode= n;\n" + 
+			"        if (selectedNode == null) {\n" + 
+			"            return;\n" + 
+			"        }\n" + 
+			"        while (selectedNode != null && !(selectedNode instanceof Cloneable)) {\n" + 
+			"            selectedNode= selectedNode.getParent();\n" + 
+			"        }\n" + 
+			"        if (selectedNode == null) { //wrong problem: Null comparison always yields false: The variable selectedNode cannot be null at this location\n" + 
+			"            // wrong problem: dead code\n" + 
+			"            System.out.println(selectedNode.hashCode());\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"}\n" +
+			"\n" + 
+			"class Node {\n" + 
+			"    Node getParent() {\n" + 
+			"        return null;\n" + 
+			"    }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in xy\\Try.java (at line 17)\n" + 
+		"	System.out.println(selectedNode.hashCode());\n" + 
+		"	                   ^^^^^^^^^^^^\n" + 
+		"Null pointer access: The variable selectedNode can only be null at this location\n" + 
+		"----------\n");
+}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTestAsserts.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTestAsserts.java
index 82cb7cf..0b7be36 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTestAsserts.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTestAsserts.java
@@ -9,6 +9,7 @@
  *		IBM Corporation - initial API and implementation
  *		Stephan Herrmann - Contribution for
  *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *								Bug 454031 - [compiler][null][loop] bug in null analysis; wrong "dead code" detection
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -724,7 +725,7 @@
 				"		do {\n" +
 				"           if (b1)\n" + 
 				"				o1 = null;\n" +
-				"           org.eclipse.core.runtime.Assert.isLegal ((o2 = o1) != null);\n" +
+				"           org.eclipse.core.runtime.Assert.isLegal (o1 != null);\n" +
 				"		} while (true);\n" + 
 				"	}\n" + 
 				"}"	
@@ -736,9 +737,9 @@
 			"Redundant assignment: The variable o1 can only be null at this location\n" + 
 			"----------\n" + 
 			"2. ERROR in DoWhileBug.java (at line 8)\n" + 
-			"	org.eclipse.core.runtime.Assert.isLegal ((o2 = o1) != null);\n" + 
-			"	                                         ^^^^^^^^^\n" + 
-			"Null comparison always yields false: The variable o2 can only be null at this location\n" + 
+			"	org.eclipse.core.runtime.Assert.isLegal (o1 != null);\n" + 
+			"	                                         ^^\n" + 
+			"Null comparison always yields false: The variable o1 can only be null at this location\n" + 
 			"----------\n",
 			this.assertLib,
 			true);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 12a128d..d0d0055 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -6909,4 +6909,393 @@
 		null,
 		"");
 }
+public void testBug448777() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"DoubleInference.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"\n" + 
+			"public class DoubleInference {\n" + 
+			"\n" + 
+			"	@FunctionalInterface\n" + 
+			"	interface Func<@Nullable T>  {\n" + 
+			"		T a(T i);\n" + 
+			"	}\n" + 
+			"\n" + 
+			"	<X> X applyWith(Func<X> f, X x) { return x; }\n" + 
+			"\n" + 
+			"	@NonNull String test1() {\n" + 
+			"		return applyWith(i -> i, \"hallo\");\n" + 
+			"	}\n" +
+			"	void test2(Func<String> f1, Func<@NonNull String> f2) {\n" + 
+			"		f1.a(null);\n" + 
+			"		f2.a(null);\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in DoubleInference.java (at line 10)\n" + 
+		"	<X> X applyWith(Func<X> f, X x) { return x; }\n" + 
+		"	                     ^\n" + 
+		"Null constraint mismatch: The type \'X\' is not a valid substitute for the type parameter \'@Nullable T\'\n" + 
+		"----------\n" + 
+		"2. ERROR in DoubleInference.java (at line 13)\n" + 
+		"	return applyWith(i -> i, \"hallo\");\n" + 
+		"	                 ^^^^^^\n" + 
+		"The target type of this expression must be a functional interface\n" + 
+		"----------\n" + 
+		"3. ERROR in DoubleInference.java (at line 15)\n" + 
+		"	void test2(Func<String> f1, Func<@NonNull String> f2) {\n" + 
+		"	                ^^^^^^\n" + 
+		"Null constraint mismatch: The type \'String\' is not a valid substitute for the type parameter \'@Nullable T\'\n" + 
+		"----------\n" + 
+		"4. ERROR in DoubleInference.java (at line 15)\n" + 
+		"	void test2(Func<String> f1, Func<@NonNull String> f2) {\n" + 
+		"	                                 ^^^^^^^^^^^^^^^\n" + 
+		"Null constraint mismatch: The type \'@NonNull String\' is not a valid substitute for the type parameter \'@Nullable T\'\n" + 
+		"----------\n" + 
+		"5. ERROR in DoubleInference.java (at line 17)\n" + 
+		"	f2.a(null);\n" + 
+		"	^^^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable String a(@NonNull @Nullable String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n");
+}
+public void testBug446442_comment2a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// swapped order of method declarations
+public void testBug446442_comment2b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// inherit from two different supers
+public void testBug446442_comment2c() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo0<T, N extends Number> {\n" + 
+			"	void m(@Nullable T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Foo1<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo1<Integer, Integer>,  Foo0<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(@NonNull Integer i) {}\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x= null;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 13)\n" + 
+		"	public void m(@NonNull Integer i) {}\n" + 
+		"	              ^^^^^^^^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo0<Integer,Integer> declares this parameter as @Nullable\n" + 
+		"----------\n");
+}
+// merging @NonNull & unannotated in arg-position must answer unannotated
+public void testBug446442_2a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		@NonNull Object o = x;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 12)\n" + 
+		"	@NonNull Object o = x;\n" + 
+		"	                    ^\n" + 
+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+		"----------\n");
+}
+// merging @NonNull & unannotated in arg-position must answer unannotated - swapped order
+public void testBug446442_2b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(T arg1);\n" + 
+			"\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		@NonNull Object o = x;\n" + 
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in Test.java (at line 12)\n" + 
+		"	@NonNull Object o = x;\n" + 
+		"	                    ^\n" + 
+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Object\'\n" + 
+		"----------\n");
+}
+// using inherited implementation to fulfill both contracts
+public void testBug446442_3() {
+	runConformTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"interface Foo<T, N extends Number> {\n" + 
+			"	void m(@NonNull N arg2);\n" + 
+			"\n" + 
+			"	void m(T arg1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"class Impl {\n" + 
+			"  public void m(Integer a) {}\n" + 
+			"}\n" + 
+			"class BazImpl extends Impl implements Baz {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	void test(BazImpl b) {\n" + 
+			"		b.m(null);\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+// unsuccessful attempt to trigger use of MostSpecificExceptionMethodBinding
+public void testBug446442_4() {
+	runConformTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"interface Foo<T, N extends Number> {\n" + 
+			"	abstract void m(@NonNull N arg2) throws Exception;\n" + 
+			"\n" + 
+			"	default void m(T arg1) throws java.io.IOException {}\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"abstract class Impl {\n" + 
+			"  public void m(Integer a) throws java.io.IOException {}\n" + 
+			"}\n" + 
+			"class BazImpl extends Impl implements Baz {}\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"	void test(BazImpl b) throws java.io.IOException {\n" + 
+			"		b.m(null);\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+// annotated return types
+public void testBug446442_5() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"interface Foo<T, N extends Number> {\n" + 
+			"	T m(T t);\n" + 
+			"\n" + 
+			"	@NonNull N m(N n);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, Integer> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public Integer m(Integer i) { return new Integer(0); }\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> null;\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 11)\n" + 
+		"	public Integer m(Integer i) { return new Integer(0); }\n" + 
+		"	       ^^^^^^^\n" + 
+		"The return type is incompatible with \'@NonNull Integer\' returned from Foo<Integer,Integer>.m(Integer) (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 15)\n" + 
+		"	Baz baz= x -> null;\n" + 
+		"	              ^^^^\n" + 
+		"Null type mismatch: required \'@NonNull Integer\' but the provided value is null\n" + 
+		"----------\n");
+}
+// conflicting annotations on type arguments
+public void testBug446442_6a() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"import java.util.*;\n" +
+			"interface Foo<T,C1 extends Collection<T>, C2 extends List<T>> {\n" + 
+			"	void m(C1 a1);\n" + 
+			"\n" + 
+			"	void m(C2 a2);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, ArrayList<@NonNull Integer>, ArrayList<@Nullable Integer>> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public void m(ArrayList<@NonNull Integer> i) {} // contradictory type cannot be implemented\n" +
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> { // contradictory type cannot be used as SAM\n" +
+			"		x.add(null); // contradictory type cause errors at call sites\n" +
+			"	}; \n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 12)\n" + 
+		"	public void m(ArrayList<@NonNull Integer> i) {} // contradictory type cannot be implemented\n" + 
+		"	              ^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>> declares this parameter as \'ArrayList<@Nullable Integer>\' (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 16)\n" + 
+		"	Baz baz= x -> { // contradictory type cannot be used as SAM\n" + 
+		"		x.add(null); // contradictory type cause errors at call sites\n" + 
+		"	}; \n" + 
+		"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: function type was inferred as \'void (ArrayList<@NonNull @Nullable Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"3. ERROR in Test.java (at line 17)\n" + 
+		"	x.add(null); // contradictory type cause errors at call sites\n" + 
+		"	^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'boolean add(@NonNull @Nullable Integer)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n");
+}
+// swapped order of method declarations + added return type
+public void testBug446442_6b() {
+	runNegativeTestWithLibs(
+		new String[] {
+			"Test.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"import java.util.*;\n" +
+			"interface Foo<T,C1 extends Collection<T>, C2 extends List<T>> {\n" + 
+			"	C2 m(C2 a2);\n" + 
+			"\n" + 
+			"	C1 m(C1 a1);\n" + 
+			"}\n" + 
+			"\n" + 
+			"interface Baz extends Foo<Integer, ArrayList<@NonNull Integer>, ArrayList<@Nullable Integer>> {}\n" + 
+			"\n" +
+			"class Impl implements Baz {\n" + 
+			"  public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+			"}\n" +
+			"\n" + 
+			"public class Test {\n" + 
+			"	Baz baz= x -> {\n" + 
+			"		x.add(null);\n" +
+			"		x.get(0);\n" +
+			"		return x;\n" + 
+			"	};\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Test.java (at line 12)\n" + 
+		"	public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+		"	       ^^^^^^^^^\n" + 
+		"The return type is incompatible with \'ArrayList<@Nullable Integer>\' returned from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>>.m(ArrayList<Integer>) (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"2. ERROR in Test.java (at line 12)\n" + 
+		"	public ArrayList<@NonNull Integer> m(ArrayList<@Nullable Integer> i) { return i; }\n" + 
+		"	                                     ^^^^^^^^^\n" + 
+		"Illegal redefinition of parameter i, inherited method from Foo<Integer,ArrayList<Integer>,ArrayList<Integer>> declares this parameter as \'ArrayList<@NonNull Integer>\' (mismatching null constraints)\n" + 
+		"----------\n" + 
+		"3. ERROR in Test.java (at line 16)\n" + 
+		"	Baz baz= x -> {\n" + 
+		"		x.add(null);\n" + 
+		"		x.get(0);\n" + 
+		"		return x;\n" + 
+		"	};\n" + 
+		"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: function type was inferred as \'ArrayList<@NonNull @Nullable Integer> (ArrayList<@NonNull @Nullable Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"4. ERROR in Test.java (at line 17)\n" + 
+		"	x.add(null);\n" + 
+		"	^^^^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'boolean add(@NonNull @Nullable Integer)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n" + 
+		"5. ERROR in Test.java (at line 18)\n" + 
+		"	x.get(0);\n" + 
+		"	^^^^^^^^\n" + 
+		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable Integer get(int)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"----------\n");
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
index 7ad7024..3197162 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2013 IBM Corporation and others.
+ * Copyright (c) 2006, 2014 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
@@ -1788,7 +1788,6 @@
             		"    public Iterator<Value_Type> iterator() {\n" +
             		"        return null;\n" +
             		"    }\n" +
-            		ITERABLE_IMPL_JRE8.replaceAll("\\*", "Value_Type") +
             		"}\n" +
             		"\n" +
             		"class BirBlock {\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
index 21e5431..a75c14a 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
@@ -2494,7 +2494,6 @@
 					"        public void remove() {\n" +
 					"            throw new UnsupportedOperationException();\n" +
 					"        }\n" +
-					ITERATOR_IMPL_JRE8.replaceAll("\\*", "T") +
 					"    }\n" +
 					"    public static void main(String[] args) {\n" +
 					"        new IteratorChain<Number>(null, null);\n" +
@@ -2503,7 +2502,7 @@
 				},
 				this.complianceLevel < ClassFileConstants.JDK1_7 ?
 				"----------\n" + 
-				"1. WARNING in X.java (at line 20)\n" + 
+				"1. WARNING in X.java (at line 18)\n" + 
 				"	new IteratorChain<Number>(null, null);\n" + 
 				"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 				"Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" + 
@@ -2514,7 +2513,7 @@
 				"	                                                                                                       ^^^^^^^^^^^\n" + 
 				"Type safety: Potential heap pollution via varargs parameter collections\n" + 
 				"----------\n" + 
-				"2. WARNING in X.java (at line 20)\n" + 
+				"2. WARNING in X.java (at line 18)\n" + 
 				"	new IteratorChain<Number>(null, null);\n" + 
 				"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 				"Type safety: A generic array of Collection<? extends Number> is created for a varargs parameter\n" + 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
index e27cbc2..39d210f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
@@ -9389,7 +9389,7 @@
 
 	//https://bugs.eclipse.org/bugs/show_bug.cgi?id=192774
 	//Test ability to distinguish AST nodes of multiple similar annotations.
-	public void _test0276() throws JavaModelException {
+	public void test0276() throws JavaModelException {
 		this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
 		String contents =
 			"@interface Annot {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
index 5725375..422bc2e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
@@ -9376,7 +9376,7 @@
 
 	//https://bugs.eclipse.org/bugs/show_bug.cgi?id=192774
 	//Test ability to distinguish AST nodes of multiple similar annotations.
-	public void _test0276() throws JavaModelException {
+	public void test0276() throws JavaModelException {
 		this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
 		String contents =
 			"@interface Annot {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
index 4987268..a526939 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
@@ -9400,7 +9400,7 @@
 
 	//https://bugs.eclipse.org/bugs/show_bug.cgi?id=192774
 	//Test ability to distinguish AST nodes of multiple similar annotations.
-	public void _test0276() throws JavaModelException {
+	public void test0276() throws JavaModelException {
 		this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
 		String contents =
 			"@interface Annot {\n" +
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 d11a815..8cd980f 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
@@ -3995,6 +3995,9 @@
 			} else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
 				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
 				return;
+			} else if (token.equals("unusedExceptionParam")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedExceptionParameter, severity, isEnabling);
+				return;
 			} else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
 				setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
 				return;
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 cb05206..bc1e56d 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
@@ -422,9 +422,11 @@
 \      unqualifiedField     unqualified reference to field\n\
 \      unused               macro for unusedAllocation, unusedArgument,\n\
 \                               unusedImport, unusedLabel, unusedLocal,\n\
-\                               unusedPrivate, unusedThrown, and unusedTypeArgs\n\
+\                               unusedPrivate, unusedThrown, and unusedTypeArgs,\n\
+\								unusedExceptionParam\n\
 \      unusedAllocation     allocating an object that is not used\n\
 \      unusedArgument       unread method parameter\n\
+\      unusedExceptionParam unread exception parameter\n\
 \      unusedImport       + unused import declaration\n\
 \      unusedLabel        + unused label\n\
 \      unusedLocal        + unread local variable\n\
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 708c85e..709211c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -196,6 +196,7 @@
  *									NullityMismatchAgainstFreeTypeVariable
  *									ImplicitObjectBoundNoNullDefault
  *									IllegalParameterNullityRedefinition
+ *									ContradictoryNullAnnotationsInferredFunctionType
  *      Jesper S Moller  - added the following constants
  *									TargetTypeNotAFunctionalInterface
  *									OuterLocalMustBeEffectivelyFinal
@@ -1803,6 +1804,8 @@
 	int ImplicitObjectBoundNoNullDefault = 971;
 	/** @since 3.11 */
 	int IllegalParameterNullityRedefinition = MethodRelated + 972;
+	/** @since 3.11 */
+	int ContradictoryNullAnnotationsInferredFunctionType = MethodRelated + 973;
 
 
 	// Java 8 work
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index d98db81..3e08063 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -34,6 +34,7 @@
  *								Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables
  *								Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
  *								Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *     Jesper S Moller - Contributions for
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
  *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -1015,7 +1016,7 @@
 		AnnotationBinding [] se8Annotations = null;
 		int se8count = 0;
 		long se8nullBits = 0;
-		Annotation se8NullAnnotation = null;
+		Annotation se8NullAnnotation = null; // just any involved annotation so we have a location for error reporting
 		int firstSE8 = -1;
 		for (int i = 0, length = annotations.length; i < length; i++) {
 			AnnotationBinding annotation = annotations[i].getCompilerAnnotation();
@@ -1038,10 +1039,10 @@
 					se8Annotations[se8count++] = annotation;
 				}
 				if (annotationType.id == TypeIds.T_ConfiguredAnnotationNonNull) {
-					se8nullBits = TagBits.AnnotationNonNull;
+					se8nullBits |= TagBits.AnnotationNonNull;
 					se8NullAnnotation = annotations[i];
 				} else if (annotationType.id == TypeIds.T_ConfiguredAnnotationNullable) {
-					se8nullBits = TagBits.AnnotationNullable;
+					se8nullBits |= TagBits.AnnotationNullable;
 					se8NullAnnotation = annotations[i];
 				}
 			}
@@ -1106,13 +1107,14 @@
 		
 		// for arrays: @T X[] SE7 associates @T to the type, but in SE8 it affects the leaf component type
 		long prevNullBits = existingType.leafComponentType().tagBits & TagBits.AnnotationNullMASK;
-		if (se8nullBits != 0 && prevNullBits != se8nullBits && ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK)) {
-			if (existingType instanceof TypeVariableBinding) {
-				// let type-use annotations override annotations on the type parameter declaration
-				existingType = existingType.withoutToplevelNullAnnotation();
-			} else {
-				scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
+		if ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK) { // contradiction after merge?
+			if (!(existingType instanceof TypeVariableBinding)) { // let type-use annotations override annotations on the type parameter declaration
+				if (prevNullBits != TagBits.AnnotationNullMASK && se8nullBits != TagBits.AnnotationNullMASK) { // conflict caused by the merge?
+					scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation);
+				}
+				se8Annotations = Binding.NO_ANNOTATIONS;
 			}
+			existingType = existingType.withoutToplevelNullAnnotation();
 		}
 		TypeBinding oldLeafType = (unionRef == null) ? existingType.leafComponentType() : unionRef.resolvedType;
 		AnnotationBinding [][] goodies = new AnnotationBinding[typeRef.getAnnotatableLevels()][];
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 0c7258e..9692df5 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
@@ -39,6 +39,7 @@
  *							Bug 429203 - [1.8][compiler] NPE in AllocationExpression.binding
  *							Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
  *							Bug 434297 - [1.8] NPE in LamdaExpression.analyseCode with lamda expression nested in a conditional expression
+ *							Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *     Jesper S Moller <jesper@selskabet.org> - Contributions for
  *							bug 378674 - "The method can be declared as static" is wrong
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
@@ -111,6 +112,7 @@
 	 // hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
 	private SimpleLookupTable/*<PMB,IC18>*/ inferenceContexts;
 	public HashMap<TypeBinding, MethodBinding> solutionsPerTargetType;
+	private InferenceContext18 outerInferenceContext; // resolving within the context of an outer (lambda) inference?
 	public boolean argsContainCast;
 	public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
 	public boolean argumentsHaveErrors = false;
@@ -948,6 +950,6 @@
 	return this.expressionContext;
 }
 public InferenceContext18 freshInferenceContext(Scope scope) {
-	return new InferenceContext18(scope, this.arguments, this);
+	return new InferenceContext18(scope, this.arguments, this, this.outerInferenceContext);
 }
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
index 67bcf5c..0c25430 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -138,7 +138,8 @@
 			if (this.defaultValue != null) {
 				MemberValuePair pair = new MemberValuePair(this.selector, this.sourceStart, this.sourceEnd, this.defaultValue);
 				pair.binding = this.binding;
-				pair.resolveTypeExpecting(this.scope, returnTypeBinding);
+				if (pair.value.resolvedType == null)
+					pair.resolveTypeExpecting(this.scope, returnTypeBinding);
 				this.binding.setDefaultValue(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair.getValue(this.defaultValue));
 			} else { // let it know it does not have a default value so it won't try to find it
 				this.binding.setDefaultValue(null);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 1833a96..4fdfb35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -135,10 +135,12 @@
 		Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
 		if (existingVariable != null && existingVariable.isValidBinding()){
 			final boolean localExists = existingVariable instanceof LocalVariableBinding;
-			if (localExists && (this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope()) {
-				scope.problemReporter().lambdaRedeclaresArgument(this);
-			} else if (localExists && this.hiddenVariableDepth == 0) {
-				scope.problemReporter().redefineArgument(this);
+			if (localExists && this.hiddenVariableDepth == 0) {
+				if ((this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope()) {
+					scope.problemReporter().lambdaRedeclaresArgument(this);
+				} else {
+					scope.problemReporter().redefineArgument(this);
+				}
 			} else {
 				boolean isSpecialArgument = false;
 				if (existingVariable instanceof FieldBinding) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index 1cbb730..c6e5fea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -29,6 +29,7 @@
  *							bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
  *							Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
+ *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -129,7 +130,7 @@
 	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
 		VariableBinding var = this.lhs.nullAnnotatedVariableBinding(compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8);
 		if (var != null) {
-			nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, nullStatus, this.expression, this.expression.resolvedType);
+			nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, nullStatus, this.expression, this.expression.resolvedType);
 			if (nullStatus == FlowInfo.NON_NULL
 					&& var instanceof FieldBinding
 					&& this.lhs instanceof Reference
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 412471b..079a108 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
@@ -728,12 +728,7 @@
 		System.arraycopy(falsePolys, 0, allPolys, truePolys.length, falsePolys.length);
 		return allPolys;
 	}
-	
-	public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method) {
-		return this.valueIfTrue.isPertinentToApplicability(typeVariable, method) 
-				&& this.valueIfFalse.isPertinentToApplicability(typeVariable, method);
-	}
-	
+
 	public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) {
 		return this.valueIfTrue.isPertinentToApplicability(targetType, method) 
 				&& this.valueIfFalse.isPertinentToApplicability(targetType, method);
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 5d7c0d5..63021d2 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
@@ -26,6 +26,7 @@
  *								Bug 427483 - [Java 8] Variables in lambdas sometimes can't be resolved
  *								Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *								Bug 428352 - [1.8][compiler] Resolution errors don't always surface
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 409245 - [1.8][compiler] Type annotations dropped when call is routed through a synthetic bridge method
  *******************************************************************************/
@@ -887,6 +888,6 @@
 	}
 	// -- interface InvocationSite: --
 	public InferenceContext18 freshInferenceContext(Scope scope) {
-		return new InferenceContext18(scope, this.arguments, this);
+		return new InferenceContext18(scope, this.arguments, this, null);
 	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 3187d05..ffd78af 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -10,7 +10,7 @@
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
- *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *     Stephan Herrmann - Contributions for 
  *								bug 292478 - Report potentially null across variable assignment
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
@@ -28,6 +28,7 @@
  *								Bug 426996 - [1.8][inference] try to avoid method Expression.unresolve()?
  *								Bug 428274 - [1.8] [compiler] Cannot cast from Number to double
  *								Bug 428352 - [1.8][compiler] Resolution errors don't always surface
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -48,6 +49,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
@@ -1140,10 +1142,6 @@
 	return this.constant;
 }
 
-public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method) {
-	return true;
-}
-
 public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) {
 	return true;
 }
@@ -1247,7 +1245,7 @@
 	return expressionType;
 }
 
-public Expression resolveExpressionExpecting(TypeBinding targetType, Scope scope) {
+public Expression resolveExpressionExpecting(TypeBinding targetType, Scope scope, InferenceContext18 context) {
 	return this; // subclasses should implement for a better resolved expression if required.
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index 5324d3c..ca3462f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -15,6 +15,7 @@
  *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
  *								Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *								Bug 429403 - [1.8][null] null mismatch from type arguments is not reported at field initializer
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *								Bug 409250 - [1.8][compiler] Various loose ends in 308 code generation
  *******************************************************************************/
@@ -129,7 +130,7 @@
 		if (options.isAnnotationBasedNullAnalysisEnabled) {
 			if (this.binding.isNonNull() || options.sourceLevel >= ClassFileConstants.JDK1_8) {
 				int nullStatus = this.initialization.nullStatus(flowInfo, flowContext);
-				NullAnnotationMatching.checkAssignment(initializationScope, flowContext, this.binding, nullStatus, this.initialization, this.initialization.resolvedType);
+				NullAnnotationMatching.checkAssignment(initializationScope, flowContext, this.binding, flowInfo, nullStatus, this.initialization, this.initialization.resolvedType);
 			}
 		}
 		this.initialization.checkNPEbyUnboxing(initializationScope, flowContext, flowInfo);
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 8ff664e..25f2077 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
@@ -16,6 +16,7 @@
  *								bug 393719 - [compiler] inconsistent warnings on iteration variables
  *								Bug 411964 - [1.8][null] leverage null type annotation in foreach statement
  *								Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Jesper S Moller -  Contribution for
  *								bug 401853 - Eclipse Java compiler creates invalid bytecode (java.lang.VerifyError)
  *******************************************************************************/
@@ -124,8 +125,8 @@
 		actionInfo.markAsDefinitelyUnknown(elementVarBinding);
 		if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
 			int elementNullStatus = FlowInfo.tagBitsToNullStatus(this.collectionElementType.tagBits);
-			int nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, elementVarBinding, elementNullStatus,
-																		this.collection, this.collectionElementType);
+			int nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, elementVarBinding, null, // have no useful flowinfo for element var
+																		elementNullStatus, this.collection, this.collectionElementType);
 			if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) {
 				actionInfo.markNullStatus(elementVarBinding, nullStatus);
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index c8b3e59..fa12013 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -19,6 +19,7 @@
  *							Bug 424403 - [1.8][compiler] Generic method call with method reference argument fails to resolve properly.
  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *							Bug 428352 - [1.8][compiler] Resolution errors don't always surface
+ *							Bug 446442 - [1.8] merge null annotations from super methods
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
  *******************************************************************************/
@@ -107,22 +108,19 @@
 		return true;
 	}
 	
-	public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method) {
-		if (method != null) { // when called from type inference
-			if (typeVariable.declaringElement == method)
-				return false;
-			if (method.isConstructor() && typeVariable.declaringElement == method.declaringClass)
-				return false;
-		} else { // for internal calls
-			if (typeVariable.declaringElement instanceof MethodBinding)
-				return false;
-		}
-		return true;
-	}
-	
 	public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) {
-		if (targetType instanceof TypeVariableBinding)
-			return isPertinentToApplicability((TypeVariableBinding) targetType, method);
+		if (targetType instanceof TypeVariableBinding) {
+			TypeVariableBinding typeVariable = (TypeVariableBinding) targetType;
+			if (method != null) { // when called from type inference
+				if (typeVariable.declaringElement == method)
+					return false;
+				if (method.isConstructor() && typeVariable.declaringElement == method.declaringClass)
+					return false;
+			} else { // for internal calls
+				if (typeVariable.declaringElement instanceof MethodBinding)
+					return false;
+			}
+		}
 		return true;
 	}
 
@@ -182,6 +180,8 @@
 		
 		this.descriptor = sam;
 		if (kosherDescriptor(blockScope, sam, true)) {
+			if (blockScope.environment().globalOptions.isAnnotationBasedNullAnalysisEnabled)
+				NullAnnotationMatching.checkForContradictions(sam, this, blockScope);
 			return this.resolvedType = this.expectedType;		
 		}
 		
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IPolyExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IPolyExpression.java
index 309cdf5..b499183 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IPolyExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IPolyExpression.java
@@ -7,16 +7,18 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *							Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
 
 /**
  	Contract to be implemented by all poly expressions and potential poly expressions for uniform integration into overload resolution and type inference.
@@ -43,7 +45,6 @@
 	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope skope);	
 	
 	// Pertinence checks.
-	public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method);
 	public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method);
 
 	// Polyness checks
@@ -59,6 +60,6 @@
 	*/
 	public TypeBinding resolveType(BlockScope blockScope);
 	// Resolve expression tentatively - should have no lingering side-effects that may impact final resolution ! 
-	public Expression resolveExpressionExpecting(TypeBinding targetType, Scope scope);
+	public Expression resolveExpressionExpecting(TypeBinding targetType, Scope scope, InferenceContext18 inferenceContext);
 	
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 224ee80..42b3001 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -33,6 +33,8 @@
  *							Bug 432110 - [1.8][compiler] nested lambda type incorrectly inferred vs javac
  *							Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
  *							Bug 441693 - [1.8][null] Bogus warning for type argument annotated with @NonNull
+ *							Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
+ *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
  *******************************************************************************/
@@ -124,6 +126,7 @@
 	private static final Block NO_BODY = new Block(0);
 	private HashMap<TypeBinding, LambdaExpression> copiesPerTargetType;
 	protected Expression [] resultExpressions = NO_EXPRESSIONS;
+	public InferenceContext18 inferenceContext; // when performing tentative resolve keep a back reference to the driving context
 	
 	public LambdaExpression(CompilationResult compilationResult, boolean assistNode, boolean requiresGenericSignature) {
 		super(compilationResult);
@@ -537,7 +540,7 @@
 					&& lambdaInfo.reachMode() == FlowInfo.REACHABLE)
 			{
 				Expression expression = (Expression)this.body;
-				checkAgainstNullAnnotation(flowContext, expression, expression.nullStatus(lambdaInfo, flowContext));
+				checkAgainstNullAnnotation(flowContext, expression, flowInfo, expression.nullStatus(lambdaInfo, flowContext));
 			}
 		}
 		return flowInfo;
@@ -593,12 +596,12 @@
 	}
 
 	// simplified version of ReturnStatement.checkAgainstNullAnnotation()
-	void checkAgainstNullAnnotation(FlowContext flowContext, Expression expression, int nullStatus) {
+	void checkAgainstNullAnnotation(FlowContext flowContext, Expression expression, FlowInfo flowInfo, int nullStatus) {
 		if (nullStatus != FlowInfo.NON_NULL) {
 			// if we can't prove non-null check against declared null-ness of the descriptor method:
 			// Note that this.binding never has a return type declaration, always inherit null-ness from the descriptor
 			if ((this.descriptor.returnType.tagBits & TagBits.AnnotationNonNull) != 0) {
-				flowContext.recordNullityMismatch(this.scope, expression, expression.resolvedType, this.descriptor.returnType, nullStatus);
+				flowContext.recordNullityMismatch(this.scope, expression, expression.resolvedType, this.descriptor.returnType, flowInfo, nullStatus);
 			}
 		}
 	}
@@ -777,7 +780,7 @@
 		
 		LambdaExpression copy = null;
 		try {
-			copy = cachedResolvedCopy(targetType, argumentsTypeElided(), false); // if argument types are elided, we don't care for result expressions against *this* target, any valid target is OK.
+			copy = cachedResolvedCopy(targetType, argumentsTypeElided(), false, null); // if argument types are elided, we don't care for result expressions against *this* target, any valid target is OK.
 		} catch (CopyFailureException cfe) {
 			if (this.assistNode)
 				return true; // can't type check result expressions, just say yes.
@@ -815,7 +818,7 @@
 		private static final long serialVersionUID = 1L;
 	}
 
-	private LambdaExpression cachedResolvedCopy(TypeBinding targetType, boolean anyTargetOk, boolean requireExceptionAnalysis) {
+	private LambdaExpression cachedResolvedCopy(TypeBinding targetType, boolean anyTargetOk, boolean requireExceptionAnalysis, InferenceContext18 context) {
 
 		targetType = findGroundTargetType(this.enclosingScope, targetType, argumentsTypeElided());
 		if (targetType == null)
@@ -848,6 +851,7 @@
 
 				copy.setExpressionContext(this.expressionContext);
 				copy.setExpectedType(targetType);
+				copy.inferenceContext = context;
 				TypeBinding type = copy.resolveType(this.enclosingScope);
 				if (type == null || !type.isValidBinding())
 					return null;
@@ -875,10 +879,10 @@
 	 * @param targetType the target functional type against which inference is attempted, must be a non-null valid functional type 
 	 * @return a resolved copy of 'this' or null if significant errors where encountered
 	 */
-	public LambdaExpression resolveExpressionExpecting(TypeBinding targetType, Scope skope) {
+	public LambdaExpression resolveExpressionExpecting(TypeBinding targetType, Scope skope, InferenceContext18 context) {
 		LambdaExpression copy = null;
 		try {
-			copy = cachedResolvedCopy(targetType, false, true);
+			copy = cachedResolvedCopy(targetType, false, true, context);
 		} catch (CopyFailureException cfe) {
 			return null;
 		}
@@ -915,7 +919,7 @@
 		if (r1.isCompatibleWith(r2, skope))
 			return true;
 		
-		LambdaExpression copy = cachedResolvedCopy(s, true /* any resolved copy is good */, false); // we expect a cached copy - otherwise control won't reach here.
+		LambdaExpression copy = cachedResolvedCopy(s, true /* any resolved copy is good */, false, null); // we expect a cached copy - otherwise control won't reach here.
 		Expression [] returnExpressions = copy.resultExpressions;
 		int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
 		
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 6da9160..c1a1acb 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
@@ -27,6 +27,7 @@
  *							Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *							Bug 430150 - [1.8][null] stricter checking against type variables
+ *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Jesper S Moller - Contributions for
  *							Bug 378674 - "The method can be declared as static" is wrong
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
@@ -145,7 +146,7 @@
 	}
 	flowInfo.markAsDefinitelyAssigned(this.binding);
 	if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
-		nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, this.binding, nullStatus, this.initialization, this.initialization.resolvedType);
+		nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, this.binding, flowInfo, nullStatus, this.initialization, this.initialization.resolvedType);
 	}
 	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
 		flowInfo.markNullStatus(this.binding, nullStatus);
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 0a2b7df..deccc3f 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
@@ -50,6 +50,7 @@
  *								Bug 428352 - [1.8][compiler] Resolution errors don't always surface
  *								Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
  *								Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *     Jesper S Moller - Contributions for
  *								Bug 378674 - "The method can be declared as static" is wrong
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
@@ -197,6 +198,7 @@
 	 // hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
 	private SimpleLookupTable/*<PGMB,InferenceContext18>*/ inferenceContexts;
 	private HashMap<TypeBinding, MethodBinding> solutionsPerTargetType;
+	private InferenceContext18 outerInferenceContext; // resolving within the context of an outer (lambda) inference?
 	
 	private boolean receiverIsType;
 	protected boolean argsContainCast;
@@ -1301,6 +1303,10 @@
 }
 
 protected TypeBinding findMethodBinding(BlockScope scope) {
+	ReferenceContext referenceContext = scope.methodScope().referenceContext;
+	if (referenceContext instanceof LambdaExpression) {
+		this.outerInferenceContext = ((LambdaExpression) referenceContext).inferenceContext;
+	}
 	
 	if (this.expectedType != null && this.binding instanceof PolyParameterizedGenericMethodBinding) {
 		this.binding = this.solutionsPerTargetType.get(this.expectedType);
@@ -1657,7 +1663,7 @@
 }
 // -- Interface InvocationSite: --
 public InferenceContext18 freshInferenceContext(Scope scope) {
-	return new InferenceContext18(scope, this.arguments, this);
+	return new InferenceContext18(scope, this.arguments, this, this.outerInferenceContext);
 }
 @Override
 public boolean isQualifiedSuper() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index 270349c..1a979f7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -13,11 +13,13 @@
 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
@@ -77,7 +79,7 @@
 	
 	/** Check null-ness of 'var' against a possible null annotation */
 	public static int checkAssignment(BlockScope currentScope, FlowContext flowContext,
-									   VariableBinding var, int nullStatus, Expression expression, TypeBinding providedType)
+									   VariableBinding var, FlowInfo flowInfo, int nullStatus, Expression expression, TypeBinding providedType)
 	{
 		long lhsTagBits = 0L;
 		boolean hasReported = false;
@@ -87,8 +89,8 @@
 			if (expression instanceof ConditionalExpression && expression.isPolyExpression()) {
 				// drill into both branches:
 				ConditionalExpression ce = ((ConditionalExpression) expression);
-				int status1 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, ce.ifTrueNullStatus, ce.valueIfTrue, ce.valueIfTrue.resolvedType);
-				int status2 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, ce.ifFalseNullStatus, ce.valueIfFalse, ce.valueIfFalse.resolvedType);
+				int status1 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, ce.ifTrueNullStatus, ce.valueIfTrue, ce.valueIfTrue.resolvedType);
+				int status2 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, ce.ifFalseNullStatus, ce.valueIfFalse, ce.valueIfFalse.resolvedType);
 				if (status1 == status2)
 					return status1;
 				return nullStatus; // if both branches disagree use the precomputed & merged nullStatus
@@ -99,7 +101,7 @@
 				currentScope.problemReporter().nullityMismatchingTypeAnnotation(expression, providedType, var.type, annotationStatus);
 				hasReported = true;
 			} else if (annotationStatus.isUnchecked()) {
-				flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, nullStatus);
+				flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, flowInfo, nullStatus);
 				hasReported = true;
 			} else if (annotationStatus.nullStatus != FlowInfo.UNKNOWN) {
 				return annotationStatus.nullStatus;
@@ -107,7 +109,7 @@
 		}
 		if (lhsTagBits == TagBits.AnnotationNonNull && nullStatus != FlowInfo.NON_NULL) {
 			if (!hasReported)
-				flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, nullStatus);
+				flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, flowInfo, nullStatus);
 			return FlowInfo.NON_NULL;
 		} else if (lhsTagBits == TagBits.AnnotationNullable && nullStatus == FlowInfo.UNKNOWN) {	// provided a legacy type?
 			return FlowInfo.POTENTIALLY_NULL;			// -> use more specific info from the annotation
@@ -136,9 +138,9 @@
 	 * @return a status object representing the severity of mismatching plus optionally a supertype hint
 	 */
 	public static NullAnnotationMatching analyse(TypeBinding requiredType, TypeBinding providedType, TypeBinding providedSubstitute, int nullStatus, CheckMode mode) {
+		if (!requiredType.enterRecursiveFunction())
+			return NullAnnotationMatching.NULL_ANNOTATIONS_OK;
 		try {
-			if (!requiredType.enterRecursiveFunction())
-				return NullAnnotationMatching.NULL_ANNOTATIONS_OK;
 			int severity = 0;
 			TypeBinding superTypeHint = null;
 			NullAnnotationMatching okStatus = NullAnnotationMatching.NULL_ANNOTATIONS_OK;
@@ -418,8 +420,8 @@
 	 * After a method has substituted type parameters, check if this resulted in any contradictory null annotations.
 	 * Problems are either reported directly (if scope != null) or by returning a ProblemMethodBinding.
 	 */
-	public static MethodBinding checkForContraditions(
-			final MethodBinding method, final InvocationSite invocationSite, final Scope scope) {
+	public static MethodBinding checkForContradictions(
+			final MethodBinding method, final Object location, final Scope scope) {
 		
 		class SearchContradictions extends TypeBindingVisitor {
 			ReferenceBinding typeWithContradiction;
@@ -441,19 +443,27 @@
 			}
 		}
 
+		int start = 0, end = 0;
+		if (location instanceof InvocationSite) {
+			start = ((InvocationSite) location).sourceStart();
+			end = ((InvocationSite) location).sourceEnd();
+		} else if (location instanceof ASTNode) {
+			start = ((ASTNode) location).sourceStart;
+			end = ((ASTNode) location).sourceEnd;
+		}
 		SearchContradictions searchContradiction = new SearchContradictions();
 		TypeBindingVisitor.visit(searchContradiction, method.returnType);
 		if (searchContradiction.typeWithContradiction != null) {
 			if (scope == null)
 				return new ProblemMethodBinding(method, method.selector, method.parameters, ProblemReasons.ContradictoryNullAnnotations);
-			scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
+			scope.problemReporter().contradictoryNullAnnotationsInferred(method, start, end, location instanceof FunctionalExpression);
 			// note: if needed, we might want to update the method by removing the contradictory annotations??
 			return method;
 		}
 
 		Expression[] arguments = null;
-		if (invocationSite instanceof Invocation)
-			arguments = ((Invocation)invocationSite).arguments();
+		if (location instanceof Invocation)
+			arguments = ((Invocation)location).arguments();
 		for (int i = 0; i < method.parameters.length; i++) {
 			TypeBindingVisitor.visit(searchContradiction, method.parameters[i]);
 			if (searchContradiction.typeWithContradiction != null) {
@@ -462,10 +472,53 @@
 				if (arguments != null && i < arguments.length)
 					scope.problemReporter().contradictoryNullAnnotationsInferred(method, arguments[i]);
 				else
-					scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
+					scope.problemReporter().contradictoryNullAnnotationsInferred(method, start, end, location instanceof FunctionalExpression);
 				return method;
 			}
 		}
 		return method;
 	}
+
+	public static TypeBinding strongerType(TypeBinding type1, TypeBinding type2, LookupEnvironment environment) {
+		if ((type1.tagBits & TagBits.AnnotationNonNull) != 0)
+			return mergeTypeAnnotations(type1, type2, true, environment);
+		return mergeTypeAnnotations(type2, type1, true, environment); // don't bother to distinguish unannotated vs. @Nullable, since both can accept null
+	}
+
+	public static TypeBinding[] weakerTypes(TypeBinding[] parameters1, TypeBinding[] parameters2, LookupEnvironment environment) {
+		TypeBinding[] newParameters = new TypeBinding[parameters1.length];
+		for (int i = 0; i < newParameters.length; i++) {
+			long tagBits1 = parameters1[i].tagBits;
+			long tagBits2 = parameters2[i].tagBits;
+			if ((tagBits1 & TagBits.AnnotationNullable) != 0)
+				newParameters[i] = mergeTypeAnnotations(parameters1[i], parameters2[i], true, environment);		// @Nullable must be preserved
+			else if ((tagBits2 & TagBits.AnnotationNullable) != 0)
+				newParameters[i] = mergeTypeAnnotations(parameters2[i], parameters1[i], true, environment);		// @Nullable must be preserved
+			else if ((tagBits1 & TagBits.AnnotationNonNull) == 0)
+				newParameters[i] = mergeTypeAnnotations(parameters1[i], parameters2[i], true, environment);		// unannotated must be preserved
+			else
+				newParameters[i] = mergeTypeAnnotations(parameters2[i], parameters1[i], true, environment);		// either unannotated, or both are @NonNull
+		}
+		return newParameters;
+	}
+	private static TypeBinding mergeTypeAnnotations(TypeBinding type, TypeBinding otherType, boolean top, LookupEnvironment environment) {
+		TypeBinding mainType = type;
+		if (!top) {
+			// for all but the top level type superimpose other's type annotation onto type
+			AnnotationBinding[] otherAnnotations = otherType.getTypeAnnotations();
+			if (otherAnnotations != Binding.NO_ANNOTATIONS)
+				mainType = environment.createAnnotatedType(type, otherAnnotations);
+		}
+		if (mainType instanceof ParameterizedTypeBinding && otherType instanceof ParameterizedTypeBinding) {
+			ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) type, otherPTB = (ParameterizedTypeBinding) otherType;
+			TypeBinding[] typeArguments = ptb.arguments;
+			TypeBinding[] otherTypeArguments = otherPTB.arguments;
+			TypeBinding[] newTypeArguments = new TypeBinding[typeArguments.length];
+			for (int i = 0; i < typeArguments.length; i++) {
+				newTypeArguments[i] = mergeTypeAnnotations(typeArguments[i], otherTypeArguments[i], false, environment);
+			}
+			return environment.createParameterizedType(ptb.genericType(), newTypeArguments, ptb.enclosingType());
+		}
+		return mainType;
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 0c6f6a3..1239dc2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -32,6 +32,7 @@
  *							Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
  *							Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
  *							Bug 438945 - [1.8] NullPointerException InferenceContext18.checkExpression in java 8 with generics, primitives, and overloading
+ *							Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contribution for
  *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
  *******************************************************************************/
@@ -62,12 +63,14 @@
 import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
 import org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18;
 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
@@ -80,7 +83,10 @@
 import org.eclipse.jdt.internal.compiler.parser.Parser;
 
 public class ReferenceExpression extends FunctionalExpression implements IPolyExpression, InvocationSite {
-	
+	// secret variable name
+	private static final String SecretReceiverVariableName = " receiver_"; //$NON-NLS-1$
+	// secret variable for codegen
+	public LocalVariableBinding receiverVariable;
 	public Expression lhs;
 	public TypeReference [] typeArguments;
 	public char [] selector;
@@ -130,6 +136,34 @@
 		return copy;
 	}
  
+	private boolean shouldGenerateSecretReceiverVariable() {
+		if (isMethodReference() && this.haveReceiver) {
+			if (this.lhs instanceof Invocation)
+				return true;
+			else {
+				return new ASTVisitor() {
+					boolean accessesnonFinalOuterLocals;
+
+					public boolean visit(SingleNameReference name, BlockScope skope) {
+						Binding local = skope.getBinding(name.getName(), ReferenceExpression.this);
+						if (local instanceof LocalVariableBinding) {
+							LocalVariableBinding localBinding = (LocalVariableBinding) local;
+							if (!localBinding.isFinal() && !localBinding.isEffectivelyFinal()) {
+								this.accessesnonFinalOuterLocals = true;
+							}
+						}
+						return false;
+					}
+
+					public boolean accessesnonFinalOuterLocals() {
+						ReferenceExpression.this.lhs.traverse(this, ReferenceExpression.this.enclosingScope);
+						return this.accessesnonFinalOuterLocals;
+					}
+				}.accessesnonFinalOuterLocals();
+			}
+		}
+		return false;
+	}
 	public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
 		
 		ReferenceExpression copy = copy();
@@ -150,10 +184,17 @@
 			String name = "arg" + (i + parameterShift); //$NON-NLS-1$
 			argv[i] = new SingleNameReference(name.toCharArray(), 0);
 		}
+		boolean generateSecretReceiverVariable = shouldGenerateSecretReceiverVariable();
 		if (isMethodReference()) {
+			if (generateSecretReceiverVariable) {
+				this.lhs.generateCode(currentScope, codeStream, true);
+				codeStream.store(this.receiverVariable, false);
+				codeStream.addVariable(this.receiverVariable);
+			}
 			MessageSend message = new MessageSend();
 			message.selector = this.selector;
-			message.receiver = this.receiverPrecedesParameters ? new SingleNameReference("arg0".toCharArray(), 0) : copy.lhs; //$NON-NLS-1$
+			Expression receiver = generateSecretReceiverVariable ? new SingleNameReference(this.receiverVariable.name, 0) : copy.lhs;
+			message.receiver = this.receiverPrecedesParameters ? new SingleNameReference("arg0".toCharArray(), 0) : receiver; //$NON-NLS-1$
 			message.typeArguments = copy.typeArguments;
 			message.arguments = argv;
 			implicitLambda.setBody(message);
@@ -203,6 +244,10 @@
 			implicitLambda.addSyntheticArgument(outerLocals[i].actualOuterLocalVariable);
 		
 		implicitLambda.generateCode(currentScope, codeStream, valueRequired);
+		if (generateSecretReceiverVariable) {
+			codeStream.removeVariable(this.receiverVariable);
+			this.receiverVariable = null;
+		}
 	}	
 	
 	private boolean shouldGenerateImplicitLambda(BlockScope currentScope) {
@@ -429,6 +474,12 @@
 			if (this.lhs instanceof NameReference) {
 				if ((this.lhs.bits & ASTNode.RestrictiveFlagMASK) == Binding.TYPE) {
 					this.haveReceiver = false;
+				} else if (isConstructorReference()) {
+					scope.problemReporter().invalidType(
+							this.lhs,
+							new ProblemReferenceBinding(((NameReference) this.lhs).getName(), null,
+									ProblemReasons.NotFound));
+					return this.resolvedType = null;
 				}
 			} else if (this.lhs instanceof TypeReference) {
 				this.haveReceiver = false;
@@ -460,6 +511,14 @@
 	            }
 	        	this.binding = this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
 	        }
+			if (isMethodReference() && this.haveReceiver) {
+				this.receiverVariable = new LocalVariableBinding(
+						(SecretReceiverVariableName + this.nameSourceStart).toCharArray(), this.lhs.resolvedType,
+						ClassFileConstants.AccDefault, false);
+				scope.addLocalVariable(this.receiverVariable);
+				this.receiverVariable.setConstant(Constant.NotAConstant); // not inlinable
+				this.receiverVariable.useFlag = LocalVariableBinding.USED;
+			}
 
 	    	if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
 	    		return new PolyTypeBinding(this);
@@ -759,7 +818,7 @@
 		return this.inferenceContexts.get(method);
 	}
 	
-	public ReferenceExpression resolveExpressionExpecting(TypeBinding targetType, Scope scope) {
+	public ReferenceExpression resolveExpressionExpecting(TypeBinding targetType, Scope scope, InferenceContext18 inferenceContext) {
 		if (this.exactMethodBinding != null) { // We may see inference variables in target type.
 			MethodBinding functionType = targetType.getSingleAbstractMethod(scope, true);
 			if (functionType == null)
@@ -803,7 +862,7 @@
 	public InferenceContext18 freshInferenceContext(Scope scope) {
 		if (this.expressionContext != ExpressionContext.VANILLA_CONTEXT) {
 			Expression[] arguments = createPseudoExpressions(this.freeParameters);
-			return new InferenceContext18(scope, arguments, this);
+			return new InferenceContext18(scope, arguments, this, null);
 		}
 		return null; // shouldn't happen, actually
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 912a2f7..d3bf2ce 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -32,6 +32,8 @@
  *								Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *								Bug 430150 - [1.8][null] stricter checking against type variables
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Jesper S Moller - Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *******************************************************************************/
@@ -206,7 +208,7 @@
 	} else if (nullStatus != FlowInfo.NON_NULL) {
 		// if we can't prove non-null check against declared null-ness of the enclosing method:
 		if ((tagBits & TagBits.AnnotationNonNull) != 0) {
-			flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, nullStatus);
+			flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, flowInfo, nullStatus);
 		}
 	}
 }
@@ -361,7 +363,7 @@
 	if (TypeBinding.notEquals(methodType, expressionType)) // must call before computeConversion() and typeMismatchError()
 		scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
 	if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)
-			|| expressionType.isCompatibleWith(methodType)) {
+			|| expressionType.isCompatibleWith(methodType, scope)) {
 
 		this.expression.computeConversion(scope, methodType, expressionType);
 		if (expressionType.needsUncheckedConversion(methodType)) {
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 247780f..354c8f0 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
@@ -32,6 +32,7 @@
  *								Bug 428352 - [1.8][compiler] Resolution errors don't always surface
  *								Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *        Andy Clement - Contributions for
  *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
  *                          Bug 409250 - [1.8][compiler] Various loose ends in 308 code generation
@@ -164,7 +165,7 @@
 					Expression argument = arguments[i];
 					int nullStatus = argument.nullStatus(flowInfo, flowContext); // slight loss of precision: should also use the null info from the receiver.
 					if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
-						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus);
 				}
 			}
 		} 
@@ -175,16 +176,16 @@
 	if (argument instanceof ConditionalExpression && argument.isPolyExpression()) {
 		// drill into both branches using existing nullStatus per branch:
 		ConditionalExpression ce = (ConditionalExpression) argument;
-		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfTrue, ce.ifTrueNullStatus, expectedNonNullness, originalExpected);
-		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfFalse, ce.ifFalseNullStatus, expectedNonNullness, originalExpected);
+		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfTrue, flowInfo, ce.ifTrueNullStatus, expectedNonNullness, originalExpected);
+		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfFalse, flowInfo, ce.ifFalseNullStatus, expectedNonNullness, originalExpected);
 		return;
 	}
 	int nullStatus = argument.nullStatus(flowInfo, flowContext);
-	internalAnalyseOneArgument18(currentScope, flowContext, expectedType, argument, nullStatus,
-									expectedNonNullness, originalExpected);
+	internalAnalyseOneArgument18(currentScope, flowContext, expectedType, argument, flowInfo,
+									nullStatus, expectedNonNullness, originalExpected);
 }
 void internalAnalyseOneArgument18(BlockScope currentScope, FlowContext flowContext, TypeBinding expectedType,
-		Expression argument, int nullStatus, Boolean expectedNonNullness, TypeBinding originalExpected) 
+		Expression argument, FlowInfo flowInfo, int nullStatus, Boolean expectedNonNullness, TypeBinding originalExpected) 
 {
 	// here we consume special case information generated in the ctor of ParameterizedGenericMethodBinding (see there):
 	int statusFromAnnotatedNull = expectedNonNullness == Boolean.TRUE ? nullStatus : 0;  
@@ -198,7 +199,7 @@
 		// immediate reporting:
 		currentScope.problemReporter().nullityMismatchingTypeAnnotation(argument, argument.resolvedType, expectedType, annotationStatus);
 	} else if (annotationStatus.isUnchecked() || (statusFromAnnotatedNull & FlowInfo.POTENTIALLY_NULL) != 0) {
-		flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+		flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus);
 	}
 }
 
@@ -206,20 +207,20 @@
 	if (expression instanceof ConditionalExpression && expression.isPolyExpression()) {
 		// drill into both branches using existing nullStatus per branch:
 		ConditionalExpression ce = (ConditionalExpression) expression;
-		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfTrue, ce.ifTrueNullStatus, flowContext);
-		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfFalse, ce.ifFalseNullStatus, flowContext);
+		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfTrue, ce.ifTrueNullStatus, flowContext, flowInfo);
+		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfFalse, ce.ifFalseNullStatus, flowContext, flowInfo);
 		return;
 	}
 	int nullStatus = expression.nullStatus(flowInfo, flowContext);
-	internalCheckAgainstNullTypeAnnotation(scope, requiredType, expression, nullStatus, flowContext);
+	internalCheckAgainstNullTypeAnnotation(scope, requiredType, expression, nullStatus, flowContext, flowInfo);
 }
 private void internalCheckAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requiredType, Expression expression,
-		int nullStatus, FlowContext flowContext) {
+		int nullStatus, FlowContext flowContext, FlowInfo flowInfo) {
 	NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(requiredType, expression.resolvedType, nullStatus);
 	if (annotationStatus.isDefiniteMismatch()) {
 		scope.problemReporter().nullityMismatchingTypeAnnotation(expression, expression.resolvedType, requiredType, annotationStatus);
 	} else if (annotationStatus.isUnchecked()) {
-		flowContext.recordNullityMismatch(scope, expression, expression.resolvedType, requiredType, nullStatus);
+		flowContext.recordNullityMismatch(scope, expression, expression.resolvedType, requiredType, flowInfo, nullStatus);
 	}
 }
 
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 f11f058..27b11b3 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, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -10,6 +10,7 @@
  *     Stephan Herrmann - Contribution for
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -79,7 +80,10 @@
 		FlowInfo flowInfo) {
 	this(parent, tryStatement, handledExceptions, exceptionToCatchBlockMap, 
 			tryStatement.catchArguments, initializationParent, scope, flowInfo.unconditionalInits());
-	this.initsOnFinally = flowInfo.unconditionalCopy();
+	UnconditionalFlowInfo unconditionalCopy = flowInfo.unconditionalCopy();
+	unconditionalCopy.iNBit = -1L;
+	unconditionalCopy.iNNBit = -1L;
+	this.initsOnFinally = unconditionalCopy;
 }
 ExceptionHandlingFlowContext(
 		FlowContext parent,
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 680fb7d..59de606 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, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -15,6 +15,7 @@
  *								bug 385626 - @NonNull fails across loop boundaries
  *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
  *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Jesper S Moller - Contributions for
  *								bug 404657 - [1.8][compiler] Analysis for effectively final variables fails to consider loops
  *******************************************************************************/
@@ -111,7 +112,7 @@
 					int nullStatus = flowInfo.nullStatus(this.nullLocals[i]);
 					if (nullStatus != FlowInfo.NON_NULL) {
 						this.parent.recordNullityMismatch(scope, (Expression) location,
-								this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus);
+								this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], flowInfo, nullStatus);
 					}
 					break;
 				case IN_UNBOXING:
@@ -423,7 +424,7 @@
 						// never happens
 				}
 			}
-			recordNullReference(local, location, checkType);
+			recordNullReference(local, location, checkType, flowInfo);
 			// prepare to re-check with try/catch flow info
 		}
 	}
@@ -439,7 +440,7 @@
 	}
 
 protected void recordNullReference(LocalVariableBinding local,
-	ASTNode expression, int checkType) {
+	ASTNode expression, int checkType, FlowInfo nullInfo) {
 	if (this.nullCount == 0) {
 		this.nullLocals = new LocalVariableBinding[5];
 		this.nullReferences = new ASTNode[5];
@@ -465,14 +466,14 @@
 	if (nullStatus == FlowInfo.NULL)
 		super.recordUnboxing(scope, expression, nullStatus, flowInfo);
 	else // defer checking:
-		recordNullReference(null, expression, IN_UNBOXING);
+		recordNullReference(null, expression, IN_UNBOXING, flowInfo);
 }
-protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, FlowInfo flowInfo, int nullStatus, TypeBinding expectedType, int checkType) {
 	// cf. decision structure inside FinallyFlowContext.recordUsingNullReference(..)
 	if (nullStatus == FlowInfo.UNKNOWN ||
 			((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0 && nullStatus != FlowInfo.NULL)) {
 		recordProvidedExpectedTypes(providedType, expectedType, this.nullCount);
-		recordNullReference(expression.localVariableBinding(), expression, checkType);
+		recordNullReference(expression.localVariableBinding(), expression, checkType, flowInfo);
 		return true;
 	}
 	return false;
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 79c475b..634d12b 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, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -17,6 +17,7 @@
  *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
  *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
  *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -773,9 +774,10 @@
  *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF}).
  *      <br>
  *      Alternatively, a {@link #IN_UNBOXING} check can e requested.
+ * @param nullInfo the null flow info observed at this first visit of location.
  */
 protected void recordNullReference(LocalVariableBinding local,
-	ASTNode location, int checkType) {
+	ASTNode location, int checkType, FlowInfo nullInfo) {
 	// default implementation: do nothing
 }
 
@@ -986,9 +988,10 @@
  * @param expression the expression violating the specification
  * @param providedType the type of the provided value, i.e., either expression or an element thereof (in ForeachStatements)
  * @param expectedType the declared type of the spec'ed variable, for error reporting.
+ * @param flowInfo the flowInfo observed when visiting expression
  * @param nullStatus the null status of expression at the current location
  */
-public void recordNullityMismatch(BlockScope currentScope, Expression expression, TypeBinding providedType, TypeBinding expectedType, int nullStatus) {
+public void recordNullityMismatch(BlockScope currentScope, Expression expression, TypeBinding providedType, TypeBinding expectedType, FlowInfo flowInfo, int nullStatus) {
 	if (providedType == null) {
 		return; // assume type error was already reported
 	}
@@ -1001,7 +1004,7 @@
 			if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
 				isInsideAssert = FlowContext.HIDE_NULL_COMPARISON_WARNING;
 			}
-			if (currentContext.internalRecordNullityMismatch(expression, providedType, nullStatus, expectedType, ASSIGN_TO_NONNULL | isInsideAssert))
+			if (currentContext.internalRecordNullityMismatch(expression, providedType, flowInfo, nullStatus, expectedType, ASSIGN_TO_NONNULL | isInsideAssert))
 				return;
 			currentContext = currentContext.parent;
 		}
@@ -1010,7 +1013,7 @@
 	char[][] annotationName = currentScope.environment().getNonNullAnnotationName();
 	currentScope.problemReporter().nullityMismatch(expression, providedType, expectedType, nullStatus, annotationName);
 }
-protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, FlowInfo flowInfo, int nullStatus, TypeBinding expectedType, int checkType) {
 	// nop, to be overridden in subclasses
 	return false; // not recorded
 }
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 16cccc6..7b1de3b 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -19,6 +19,7 @@
  *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
  *								bug 406384 - Internal error with I20130413
  *								Bug 415413 - [compiler][null] NullpointerException in Null Analysis caused by interaction of LoopingFlowContext and FinallyFlowContext
+ *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
  *     Jesper S Moller - contributions for
  *								bug 404657 - [1.8][compiler] Analysis for effectively final variables fails to consider loops
  *******************************************************************************/
@@ -66,6 +67,7 @@
 	ASTNode[] nullReferences;	// Expressions for null checking, Statements for resource analysis
 								// cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
 	int[] nullCheckTypes;
+	UnconditionalFlowInfo[] nullInfos;	// detailed null info observed during the first visit of nullReferences[i], or null
 	int nullCount;
 	// see also the related field FlowContext#expectedTypes
 
@@ -160,13 +162,16 @@
 	}
 	this.innerFlowContextsCount = 0;
 	FlowInfo upstreamCopy = this.upstreamNullFlowInfo.copy();
-	UnconditionalFlowInfo flowInfo = this.upstreamNullFlowInfo.
+	UnconditionalFlowInfo incomingInfo = this.upstreamNullFlowInfo.
 		addPotentialNullInfoFrom(callerFlowInfo.unconditionalInitsWithoutSideEffect());
 	if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) {
 		// check only immutable null checks on innermost looping context
 		for (int i = 0; i < this.nullCount; i++) {
 			LocalVariableBinding local = this.nullLocals[i];
 			ASTNode location = this.nullReferences[i];
+			FlowInfo flowInfo =  (this.nullInfos[i] != null)
+									? incomingInfo.copy().addNullInfoFrom(this.nullInfos[i])
+									: incomingInfo;
 			// final local variable
 			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
 				case CAN_ONLY_NON_NULL | IN_COMPARISON_NULL:
@@ -268,7 +273,7 @@
 				case ASSIGN_TO_NONNULL:
 					int nullStatus = flowInfo.nullStatus(local);
 					if (nullStatus != FlowInfo.NON_NULL) {
-						this.parent.recordNullityMismatch(scope, (Expression)location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus);
+						this.parent.recordNullityMismatch(scope, (Expression)location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], flowInfo, nullStatus);
 					}
 					continue; // no more delegation to parent
 				case EXIT_RESOURCE:
@@ -306,6 +311,9 @@
 			ASTNode location = this.nullReferences[i];
 			// final local variable
 			LocalVariableBinding local = this.nullLocals[i];
+			FlowInfo flowInfo =  (this.nullInfos[i] != null)
+					? incomingInfo.copy().addNullInfoFrom(this.nullInfos[i])
+					: incomingInfo;
 			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
 				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
 				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
@@ -418,9 +426,9 @@
 		}
 	}
 	// propagate breaks
-	this.initsOnBreak.addPotentialNullInfoFrom(flowInfo);
+	this.initsOnBreak.addPotentialNullInfoFrom(incomingInfo);
 	for (int i = 0; i < this.breakTargetsCount; i++) {
-		this.breakTargetContexts[i].initsOnBreak.addPotentialNullInfoFrom(flowInfo);
+		this.breakTargetContexts[i].initsOnBreak.addPotentialNullInfoFrom(incomingInfo);
 	}
 }
 
@@ -534,11 +542,12 @@
 	}
 
 protected void recordNullReference(LocalVariableBinding local,
-	ASTNode expression, int checkType) {
+	ASTNode expression, int checkType, FlowInfo nullInfo) {
 	if (this.nullCount == 0) {
 		this.nullLocals = new LocalVariableBinding[5];
 		this.nullReferences = new ASTNode[5];
 		this.nullCheckTypes = new int[5];
+		this.nullInfos = new UnconditionalFlowInfo[5];
 	}
 	else if (this.nullCount == this.nullLocals.length) {
 		System.arraycopy(this.nullLocals, 0,
@@ -547,16 +556,19 @@
 			this.nullReferences = new ASTNode[this.nullCount * 2], 0, this.nullCount);
 		System.arraycopy(this.nullCheckTypes, 0,
 			this.nullCheckTypes = new int[this.nullCount * 2], 0, this.nullCount);
+		System.arraycopy(this.nullInfos, 0,
+			this.nullInfos = new UnconditionalFlowInfo[this.nullCount * 2], 0, this.nullCount);
 	}
 	this.nullLocals[this.nullCount] = local;
 	this.nullReferences[this.nullCount] = expression;
-	this.nullCheckTypes[this.nullCount++] = checkType;
+	this.nullCheckTypes[this.nullCount] = checkType;
+	this.nullInfos[this.nullCount++] = nullInfo.unconditionalCopy();
 }
 public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
 	if (nullStatus == FlowInfo.NULL)
 		super.recordUnboxing(scope, expression, nullStatus, flowInfo);
 	else // defer checking:
-		recordNullReference(null, expression, IN_UNBOXING);
+		recordNullReference(null, expression, IN_UNBOXING, flowInfo);
 }
 
 /** Record the fact that we see an early exit (in 'reference') while 'trackingVar' is in scope and may be unclosed. */
@@ -573,7 +585,7 @@
 		scope.problemReporter().potentiallyUnclosedCloseable(trackingVar, reference);
 		return true; // handled
 	}
-	recordNullReference(trackingVar.binding, reference, EXIT_RESOURCE);
+	recordNullReference(trackingVar.binding, reference, EXIT_RESOURCE, flowInfo);
 	return true; // handled
 }
 
@@ -612,20 +624,20 @@
 				}
 			} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {
 				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291418
+				recordNullReference(local, reference, checkType, flowInfo);
 				flowInfo.markAsDefinitelyNonNull(local);
-				recordNullReference(local, reference, checkType);
 			} else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
 				return; // no reason to complain, since there is definitely some uncertainty making the comparison relevant.
 			} else {
 					// 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|HIDE_NULL_COMPARISON_WARNING_MASK));
+						recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & (CONTEXT_MASK|HIDE_NULL_COMPARISON_WARNING_MASK), flowInfo);
 					} 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|HIDE_NULL_COMPARISON_WARNING_MASK));
+						recordNullReference(local, reference, CAN_ONLY_NULL | checkType & (CONTEXT_MASK|HIDE_NULL_COMPARISON_WARNING_MASK), flowInfo);
 					} else {
-						recordNullReference(local, reference, checkType);
+						recordNullReference(local, reference, checkType, flowInfo);
 					}
 			}
 			return;
@@ -684,7 +696,7 @@
 						break;
 				}
 			}
-			recordNullReference(local, reference, checkType);
+			recordNullReference(local, reference, checkType, flowInfo);
 			return;
 		case MAY_NULL :
 			if (flowInfo.isDefinitelyNonNull(local)) {
@@ -698,7 +710,7 @@
 				scope.problemReporter().localVariablePotentialNullReference(local, location);
 				return;
 			}
-			recordNullReference(local, location, checkType);
+			recordNullReference(local, location, checkType, flowInfo);
 			return;
 		default:
 			// never happens
@@ -742,9 +754,9 @@
 		return this.escapingExceptionCatchSites != null;
 	}
 
-	protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+	protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, FlowInfo flowInfo, int nullStatus, TypeBinding expectedType, int checkType) {
 		recordProvidedExpectedTypes(providedType, expectedType, this.nullCount);
-		recordNullReference(expression.localVariableBinding(), expression, checkType);
+		recordNullReference(expression.localVariableBinding(), expression, checkType, flowInfo);
 		return true;
 	}
 }
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 d8a8369..8b68fd8 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -9,7 +9,7 @@
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
- *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     Stephan Herrmann - Contributions for
  *     						bug 325755 - [compiler] wrong initialization state after conditional expression
  *     						bug 320170 - [compiler] [null] Whitebox issues in null analysis
  *     						bug 292478 - Report potentially null across variable assignment
@@ -19,9 +19,13 @@
  *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *							bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith()
  *							bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
+ *							Bug 454031 - [compiler][null][loop] bug in null analysis; wrong "dead code" detection
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
+import java.util.Arrays;
+
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
@@ -90,12 +94,18 @@
 		1110	prot. null
 		1111	prot. non null
  */
+	public long 
+		iNBit,	// can an incoming null value reach the current point?
+		iNNBit;	// can an incoming nonnull value reach the current point?
 
 	// extra segments
-	public static final int extraLength = 6;
+	public static final int extraLength = 8;
 	public long extra[][];
 		// extra bit fields for larger numbers of fields/variables
 		// extra[0] holds definiteInits values, extra[1] potentialInits, etc.
+		// extra[1+1]... corresponds to nullBits1 ...
+		// extra[IN] is iNBit
+		// extra[INN] is iNNBit
 		// lifecycle is extra == null or else all extra[]'s are allocated
 		// arrays which have the same size
 
@@ -103,6 +113,8 @@
 
 	// Constants
 	public static final int BitCacheSize = 64; // 64 bits in a long.
+	public static final int IN = 6;
+	public static final int INN = 7;
 
 /* fakeInitializedFlowInfo: For Lambda expressions tentative analysis during overload resolution. 
    We presume that any and all outer locals touched by the lambda are definitely assigned and 
@@ -143,6 +155,8 @@
 	// combine null information
 	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
 		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
+//	if ((otherInits.iNNBit | otherInits.iNBit) == 0)
+//		thisHadNulls = false; // suppress incoming null info, if none shines through in other
 	long
 		a1, a2, a3, a4,
 		na1, na2, na3, na4,
@@ -154,6 +168,8 @@
 			this.nullBit2 = otherInits.nullBit2;
 			this.nullBit3 = otherInits.nullBit3;
 			this.nullBit4 = otherInits.nullBit4;
+			this.iNBit = otherInits.iNBit;
+			this.iNNBit = otherInits.iNNBit;
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 1) {
 				  this.nullBit4 = ~0;
@@ -161,12 +177,33 @@
 			}
 		}
 		else {
+			a1 = this.nullBit1;
+			a2 = this.nullBit2;
+			a3 = this.nullBit3;
+			a4 = this.nullBit4;
+
+			// state that breaks the correlation between bits and n or nn, used below:
+			long protNN1111 = a1&a2&a3&a4;
+
+			// filter 'a' using iNBit,iNNBit from otherInits:
+			// this implements that otherInit does not accept certain bits which are known to be superseded by info in otherInits.			
+			long acceptNonNull = otherInits.iNNBit;
+			long acceptNull = otherInits.iNBit
+								| protNN1111; // for 1111 don't bother suppressing incoming null, logic operation would produce wrong result
+			long dontResetToStart = ~protNN1111 | acceptNonNull; // for 1111 & ~acceptNonNull we reset all bits to 0000
+
+			a1 &= dontResetToStart;
+			a2 = dontResetToStart & acceptNull & a2;
+			a3 = dontResetToStart & acceptNonNull & a3;
+			a4 &= dontResetToStart;
+			a1 &= (a2 | a3 | a4);		// translate 1000 (undefined state) to 0000
+			
 			this.nullBit1 = (b1 = otherInits.nullBit1)
-                				| (a1 = this.nullBit1) & ((a3 = this.nullBit3)
-                					& (a4 = this.nullBit4) & (nb2 = ~(b2 = otherInits.nullBit2))
+                				| a1 & (a3
+                					& a4 & (nb2 = ~(b2 = otherInits.nullBit2))
                 					& (nb4 = ~(b4 = otherInits.nullBit4))
                         		| ((na4 = ~a4) | (na3 = ~a3))
-                        			& ((na2 = ~(a2 = this.nullBit2)) & nb2
+                        			& ((na2 = ~a2) & nb2
                         				| a2 & (nb3 = ~(b3 = otherInits.nullBit3)) & nb4));
 			this.nullBit2  = b2 & (nb4 | nb3)
                     			| na3 & na4 & b2
@@ -189,6 +226,10 @@
                           			| na1 & (b4	| (a4 | a2) & b2 & b3))
                       			| (na1 & (na3 & nb3 | na2 & nb2)
                       				| a1 & (nb2 & nb3 | a2 & a3)) & b4;
+
+			// unconditional sequence, must shine through both to shine through in the end:
+			this.iNBit &= otherInits.iNBit;
+			this.iNNBit &= otherInits.iNNBit;
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 2) {
 				  this.nullBit4 = ~0;
@@ -253,6 +294,8 @@
 				for (int j = 2; j < extraLength; j++) {
 					this.extra[j] = new long[otherLength];
 				}
+				System.arraycopy(otherInits.extra[IN], 0, this.extra[IN], 0, otherLength);
+				System.arraycopy(otherInits.extra[INN], 0, this.extra[INN], 0, otherLength);
 				if (COVERAGE_TEST_FLAG) {
 					if (CoverageTestId == 6) {
 						throw new AssertionFailedException("COVERAGE 6"); //$NON-NLS-1$
@@ -285,14 +328,34 @@
 		  	mergeLimit = 0;
 		}
 		for (i = 0; i < mergeLimit; i++) {
+			a1 = this.extra[1 + 1][i];
+			a2 = this.extra[2 + 1][i];
+			a3 = this.extra[3 + 1][i];
+			a4 = this.extra[4 + 1][i];
+			// state that breaks the correlation between bits and n or nn, used below:
+			long protNN1111 = a1&a2&a3&a4;
+
+			// filter 'a' using iNBit,iNNBit from otherInits:
+			// this implements that otherInit does not accept certain bits which are known to be superseded by info in otherInits.			
+			long acceptNonNull = otherInits.extra[INN][i];
+			long acceptNull = otherInits.extra[IN][i]
+								| protNN1111; // for 1111 don't bother suppressing incoming null, logic operation would produce wrong result
+			long dontResetToStart = ~protNN1111 | acceptNonNull; // for 1111 & ~acceptNonNull we reset all bits to 0000
+
+			a1 &= dontResetToStart;
+			a2 = dontResetToStart & acceptNull & a2;
+			a3 = dontResetToStart & acceptNonNull & a3;
+			a4 &= dontResetToStart;
+			a1 &= (a2 | a3 | a4);		// translate 1000 (undefined state) to 0000
+
 			this.extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i])
-                				| (a1 = this.extra[1 + 1][i]) & ((a3 = this.extra[3 + 1][i])
-                					& (a4 = this.extra[4 + 1][i]) & (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
+                				| a1 & (a3 
+                					& a4 & (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
                 					& (nb4 = ~(b4 = otherInits.extra[4 + 1][i]))
                         		| ((na4 = ~a4) | (na3 = ~a3))
-                        			& ((na2 = ~(a2 = this.extra[2 + 1][i])) & nb2
+                        			& ((na2 = ~a2) & nb2
                         				| a2 & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])) & nb4));
-			this.extra[2 + 1][i]  = b2 & (nb4 | nb3)
+			this.extra[2 + 1][i] = b2 & (nb4 | nb3)
                     			| na3 & na4 & b2
                     			| a2 & (nb3 & nb4
                                 			| (nb1 = ~b1) & (na3 | (na1 = ~a1))
@@ -313,6 +376,11 @@
                           			| na1 & (b4	| (a4 | a2) & b2 & b3))
                       			| (na1 & (na3 & nb3 | na2 & nb2)
                       				| a1 & (nb2 & nb3 | a2 & a3)) & b4;
+
+			// unconditional sequence, must shine through both to shine through in the end:
+			this.extra[IN][i] &= otherInits.extra[IN][i];
+			this.extra[INN][i] &= otherInits.extra[INN][i];
+
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 7) {
 				  this.extra[5][i] = ~0;
@@ -430,6 +498,7 @@
     			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
     			| a3 & (a4 & (nb2 | b1 & b3)
             			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
+		// this and then pot.other: leave iNBit & iNNBit untouched
 		if (COVERAGE_TEST_FLAG) {
 			if (CoverageTestId == 9) {
 			  this.nullBit4 = ~0;
@@ -445,6 +514,7 @@
   								(nb1 = ~(b1 = otherInits.nullBit1)));
   		this.nullBit3 = b3 & (nb1 | (nb2 = ~b2));
   		this.nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4) | ~b2 & (b1 & ~b3 | ~b1 & b4);
+		// this and then pot.other: leave iNBit & iNNBit untouched
 		if (COVERAGE_TEST_FLAG) {
 			if (CoverageTestId == 10) {
 			  this.nullBit4 = ~0;
@@ -511,6 +581,7 @@
         			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
         			| a3 & (a4 & (nb2 | b1 & b3)
                 			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
+    		// this and then pot.other: leave iNBit & iNNBit untouched
     		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
     		  	thisHasNulls = true;
     		}
@@ -527,6 +598,7 @@
     								(nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
     		this.extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2));
     		this.extra[4 + 1][i] = ~b1 & ~b3 & (b4 = otherInits.extra[4 + 1][i]) | ~b2 & (b1 & ~b3 | ~b1 & b4);
+    		// this and then pot.other: leave iNBit & iNNBit untouched
     		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
     		  	thisHasNulls = true;
     		}
@@ -646,6 +718,8 @@
 		copy.nullBit3 = this.nullBit3;
 		copy.nullBit4 = this.nullBit4;
 	}
+	copy.iNBit = this.iNBit;
+	copy.iNNBit = this.iNNBit;
 	copy.tagBits = this.tagBits;
 	copy.maxFieldCount = this.maxFieldCount;
 	if (this.extra != null) {
@@ -704,6 +778,8 @@
 		this.nullBit2 &= mask;
 		this.nullBit3 &= mask;
 		this.nullBit4 &= mask;
+		this.iNBit &= mask;
+		this.iNNBit &= mask;
 	}
 	// use extra vector
 	if (this.extra == null) {
@@ -1099,6 +1175,8 @@
 			}
 			this.nullBit1 |= mask;
 			this.nullBit3 |= mask;
+			// it was not null;
+			this.iNBit &= ~mask;
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 15) {
 				  	this.nullBit4 = ~0;
@@ -1157,6 +1235,8 @@
   			}
   			this.extra[1 + 1][vectorIndex] |= mask;
   			this.extra[3 + 1][vectorIndex] |= mask;
+			// it was not null;
+			this.extra[IN][vectorIndex] &= ~mask;
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 18) {
 				  	this.extra[5][vectorIndex] = ~0;
@@ -1193,6 +1273,8 @@
 			}
 			this.nullBit1 |= mask;
 			this.nullBit2 |= mask;
+			// it was null;
+			this.iNNBit &= ~mask;
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 19) {
 				  	this.nullBit4 = ~0;
@@ -1249,6 +1331,8 @@
 			}
 			this.extra[1 + 1][vectorIndex] |= mask;
 			this.extra[2 + 1][vectorIndex] |= mask;
+			// it was null;
+			this.extra[INN][vectorIndex] &= ~mask;
 		}
 	}
 }
@@ -1318,6 +1402,9 @@
     		// clear others
     		this.nullBit2 &= (mask = ~mask);
     		this.nullBit4 &= mask;
+    		// old value no longer shining through
+    		this.iNBit &= mask;
+    		this.iNNBit &= mask;
     		if (COVERAGE_TEST_FLAG) {
     			if(CoverageTestId == 22) {
 	    		  	this.nullBit1 = 0;
@@ -1349,6 +1436,9 @@
     		this.extra[4][vectorIndex] |= mask;
     		this.extra[3][vectorIndex] &= (mask = ~mask);
     		this.extra[5][vectorIndex] &= mask;
+    		// old value no longer shining through
+    		this.extra[IN][vectorIndex] &= mask;
+    		this.extra[INN][vectorIndex] &= mask;
     		if (COVERAGE_TEST_FLAG) {
     			if(CoverageTestId == 23) {
 	    			this.extra[2][vectorIndex] = 0;
@@ -1372,6 +1462,9 @@
     		// clear others
     		this.nullBit3 &= (mask = ~mask);
     		this.nullBit4 &= mask;
+    		// old value no longer shining through
+    		this.iNBit &= mask;
+    		this.iNNBit &= mask;
     		if (COVERAGE_TEST_FLAG) {
     			if(CoverageTestId == 24) {
 	    		  	this.nullBit4 = ~0;
@@ -1403,6 +1496,9 @@
     		this.extra[3][vectorIndex] |= mask;
     		this.extra[4][vectorIndex] &= (mask = ~mask);
     		this.extra[5][vectorIndex] &= mask;
+    		// old value no longer shining through
+    		this.extra[IN][vectorIndex] &= mask;
+    		this.extra[INN][vectorIndex] &= mask;
     		if (COVERAGE_TEST_FLAG) {
     			if(CoverageTestId == 25) {
 	    			this.extra[5][vectorIndex] = ~0;
@@ -1433,6 +1529,9 @@
 			// clear others
 			this.nullBit2 &= (mask = ~mask);
 			this.nullBit3 &= mask;
+    		// old value no longer shining through
+    		this.iNBit &= mask;
+    		this.iNNBit &= mask;
 			if (COVERAGE_TEST_FLAG) {
 				if(CoverageTestId == 26) {
 				  	this.nullBit4 = 0;
@@ -1464,6 +1563,9 @@
 			this.extra[5][vectorIndex] |= mask;
 			this.extra[3][vectorIndex] &= (mask = ~mask);
 			this.extra[4][vectorIndex] &= mask;
+    		// old value no longer shining through
+    		this.extra[IN][vectorIndex] &= mask;
+    		this.extra[INN][vectorIndex] &= mask;
 			if (COVERAGE_TEST_FLAG) {
 				if(CoverageTestId == 27) {
 					this.extra[5][vectorIndex] = 0;
@@ -1484,6 +1586,8 @@
             this.nullBit2 &= mask;
             this.nullBit3 &= mask;
             this.nullBit4 &= mask;
+            this.iNBit &= mask;
+            this.iNNBit &= mask;
         } else {
     		// use extra vector
     		int vectorIndex = (position / BitCacheSize) - 1;
@@ -1497,6 +1601,8 @@
     		this.extra[3][vectorIndex] &= mask;
     		this.extra[4][vectorIndex] &= mask;
     		this.extra[5][vectorIndex] &= mask;
+    		this.extra[IN][vectorIndex] &= mask;
+    		this.extra[INN][vectorIndex] &= mask;
     	}
 	}
 }
@@ -1696,6 +1802,8 @@
 		this.nullBit2 = otherInits.nullBit2;
 		this.nullBit3 = otherInits.nullBit3;
 		this.nullBit4 = otherInits.nullBit4;
+		this.iNBit = otherInits.iNBit;
+		this.iNNBit = otherInits.iNNBit;
 		thisHadNulls = false;
 		thisHasNulls = otherHasNulls;
 		this.tagBits = otherInits.tagBits;
@@ -1740,11 +1848,15 @@
     			}
     		}
     	}
+    	this.iNBit |= otherInits.iNBit;
+    	this.iNNBit |= otherInits.iNNBit;
 	} else if (otherHasNulls) { // only other had nulls
   		this.nullBit1 = 0;
   		this.nullBit2 = (b2 = otherInits.nullBit2) & (nb3 = ~(b3 = otherInits.nullBit3) | (nb1 = ~(b1 = otherInits.nullBit1)));
   		this.nullBit3 = b3 & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1) | b1 & nb2 & ~b4;
   		this.nullBit4 = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
+  		this.iNBit |= otherInits.iNBit;
+  		this.iNNBit |= otherInits.iNNBit;
   		if (COVERAGE_TEST_FLAG) {
   			if(CoverageTestId == 32) {
 	  		  	this.nullBit4 = ~0;
@@ -1809,6 +1921,8 @@
 			}
 			System.arraycopy(otherInits.extra[1], 0,
 				this.extra[1], 0, otherLength);
+			System.arraycopy(otherInits.extra[IN], 0, this.extra[IN], 0, otherLength);
+			System.arraycopy(otherInits.extra[INN], 0, this.extra[INN], 0, otherLength);
 			copyLimit = otherLength;
 			if (COVERAGE_TEST_FLAG) {
 				if(CoverageTestId == 36) {
@@ -1862,6 +1976,8 @@
                 			| na2 & b3 & b4
                 			| a2 & (nb1 & b4 | a3 & na4 & b1) & nb3)
                 	|nb1 & b2 & b3 & b4;
+    		this.extra[IN][i] |= otherInits.extra[IN][i];
+    		this.extra[INN][i] |= otherInits.extra[INN][i];
 			thisHasNulls = thisHasNulls ||
 				this.extra[3][i] != 0 ||
 				this.extra[4][i] != 0 ||
@@ -1877,6 +1993,8 @@
     		this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
     		this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4;
     		this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
+    		this.extra[IN][i] |= otherInits.extra[IN][i];
+    		this.extra[INN][i] |= otherInits.extra[INN][i];
 			thisHasNulls = thisHasNulls ||
 				this.extra[3][i] != 0 ||
 				this.extra[4][i] != 0 ||
@@ -1933,6 +2051,9 @@
 	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
 	copy.definiteInits = this.definiteInits;
 	copy.potentialInits = this.potentialInits;
+	// no nullness known means: any previous nullness could shine through:
+	copy.iNBit = -1L;
+	copy.iNNBit = -1L;
 	copy.tagBits = this.tagBits & ~NULL_FLAG_MASK;
 	copy.maxFieldCount = this.maxFieldCount;
 	if (this.extra != null) {
@@ -1946,6 +2067,9 @@
 		for (int j = 2; j < extraLength; j++) {
 			copy.extra[j] = new long[length];
 		}
+		// no nullness known means: any previous nullness could shine through:
+		Arrays.fill(copy.extra[IN], -1L);
+		Arrays.fill(copy.extra[INN], -1L);
 	}
 	return copy;
 }
@@ -1991,6 +2115,7 @@
 				+ ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
 				+", null: " + this.nullBit1 //$NON-NLS-1$
 					+ this.nullBit2 + this.nullBit3 + this.nullBit4
+				+", incoming: " + this.iNBit + this.iNNBit //$NON-NLS-1$
 				+">"; //$NON-NLS-1$
 		}
 		else {
@@ -2006,7 +2131,8 @@
 				def += "," + this.extra[0][i]; //$NON-NLS-1$
 				pot += "," + this.extra[1][i]; //$NON-NLS-1$
 				nullS += "," + this.extra[2][i] //$NON-NLS-1$
-				    + this.extra[3][i] + this.extra[4][i] + this.extra[5][i];
+				    + this.extra[3][i] + this.extra[4][i] + this.extra[5][i]
+					+", incoming: " + this.extra[IN][i] + this.extra[INN]; //$NON-NLS-1$
 			}
 			if (ceil < this.extra[0].length) {
 				def += ",..."; //$NON-NLS-1$
@@ -2066,6 +2192,8 @@
 		copy.nullBit2 = this.nullBit2 & mask;
 		copy.nullBit3 = this.nullBit3 & mask;
 		copy.nullBit4 = this.nullBit4 & mask;
+		copy.iNBit = this.iNBit & mask;
+		copy.iNNBit = this.iNNBit & mask;
 	}
 	// use extra vector
 	if (this.extra == null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 827e212..c8f8534 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -67,6 +67,7 @@
 	public static final String OPTION_ReportHiddenCatchBlock = "org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnusedLocal = "org.eclipse.jdt.core.compiler.problem.unusedLocal"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnusedParameter = "org.eclipse.jdt.core.compiler.problem.unusedParameter"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedExceptionParameter = "org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnusedParameterWhenImplementingAbstract = "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnusedParameterWhenOverridingConcrete = "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnusedParameterIncludeDocCommentReference = "org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference"; //$NON-NLS-1$
@@ -385,6 +386,7 @@
 	public static final int MissingDefaultCase = IrritantSet.GROUP2 | ASTNode.Bit16;
 	public static final int UnusedTypeParameter = IrritantSet.GROUP2 | ASTNode.Bit17;
 	public static final int NonnullParameterAnnotationDropped = IrritantSet.GROUP2 | ASTNode.Bit18;
+	public static final int UnusedExceptionParameter = IrritantSet.GROUP2 | ASTNode.Bit19;
 
 //{ObjectTeams: OT/J specific problems/irritants:
 	public static final int OTJFlag = IrritantSet.GROUP3;
@@ -685,6 +687,8 @@
 				return OPTION_ReportUnusedLocal;
 			case UnusedArgument :
 				return OPTION_ReportUnusedParameter;
+			case UnusedExceptionParameter :
+				return OPTION_ReportUnusedExceptionParameter;
 			case NoImplicitStringConversion :
 				return OPTION_ReportNoImplicitStringConversion;
 			case AccessEmulation :
@@ -1035,6 +1039,7 @@
 			OPTION_ReportUnusedLocal,
 			OPTION_ReportUnusedObjectAllocation,
 			OPTION_ReportUnusedParameter,
+			OPTION_ReportUnusedExceptionParameter,
 			OPTION_ReportUnusedParameterIncludeDocCommentReference,
 			OPTION_ReportUnusedParameterWhenImplementingAbstract,
 			OPTION_ReportUnusedParameterWhenOverridingConcrete,
@@ -1132,6 +1137,7 @@
 			case RedundantSuperinterface :
 			case UnusedLocalVariable :
 			case UnusedArgument :
+			case UnusedExceptionParameter :
 			case UnusedImport :
 			case UnusedPrivateMember :
 			case UnusedDeclaredThrownException :
@@ -1372,6 +1378,7 @@
 		optionsMap.put(OPTION_ReportHiddenCatchBlock, getSeverityString(MaskedCatchBlock));
 		optionsMap.put(OPTION_ReportUnusedLocal, getSeverityString(UnusedLocalVariable));
 		optionsMap.put(OPTION_ReportUnusedParameter, getSeverityString(UnusedArgument));
+		optionsMap.put(OPTION_ReportUnusedExceptionParameter, getSeverityString(UnusedExceptionParameter));
 		optionsMap.put(OPTION_ReportUnusedImport, getSeverityString(UnusedImport));
 		optionsMap.put(OPTION_ReportSyntheticAccessEmulation, getSeverityString(AccessEmulation));
 		optionsMap.put(OPTION_ReportNoEffectAssignment, getSeverityString(NoEffectAssignment));
@@ -1938,6 +1945,7 @@
 		if ((optionValue = optionsMap.get(OPTION_ReportHiddenCatchBlock)) != null) updateSeverity(MaskedCatchBlock, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedLocal)) != null) updateSeverity(UnusedLocalVariable, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedParameter)) != null) updateSeverity(UnusedArgument, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedExceptionParameter)) != null) updateSeverity(UnusedExceptionParameter, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedImport)) != null) updateSeverity(UnusedImport, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedPrivateMember)) != null) updateSeverity(UnusedPrivateMember, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedDeclaredThrownException)) != null) updateSeverity(UnusedDeclaredThrownException, optionValue);
@@ -2248,6 +2256,7 @@
 		buf.append("\n\t- masked catch block: ").append(getSeverityString(MaskedCatchBlock)); //$NON-NLS-1$
 		buf.append("\n\t- unused local variable: ").append(getSeverityString(UnusedLocalVariable)); //$NON-NLS-1$
 		buf.append("\n\t- unused parameter: ").append(getSeverityString(UnusedArgument)); //$NON-NLS-1$
+		buf.append("\n\t- unused exception parameter: ").append(getSeverityString(UnusedExceptionParameter)); //$NON-NLS-1$
 		buf.append("\n\t- unused import: ").append(getSeverityString(UnusedImport)); //$NON-NLS-1$
 		buf.append("\n\t- synthetic access emulation: ").append(getSeverityString(AccessEmulation)); //$NON-NLS-1$
 		buf.append("\n\t- assignment with no effect: ").append(getSeverityString(NoEffectAssignment)); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index 66fd8fc..9832309 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -215,6 +215,7 @@
 		STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
 		UNUSED
 			.set(CompilerOptions.UnusedArgument)
+			.set(CompilerOptions.UnusedExceptionParameter)
 			.set(CompilerOptions.UnusedPrivateMember)
 			.set(CompilerOptions.UnusedDeclaredThrownException)
 			.set(CompilerOptions.UnusedLabel)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
index b471d58..23ae246 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
@@ -1090,4 +1090,24 @@
 		}
 		return null;
 	}
+
+	public TypeBinding getEquivalentOuterVariable(InferenceVariable variable, InferenceVariable[] outerVariables) {
+		ThreeSets three = this.boundsPerVariable.get(variable);
+		if (three != null) {
+			for (TypeBound bound : three.sameBounds) {
+				for (InferenceVariable iv : outerVariables)
+					if (TypeBinding.equalsEquals(bound.right, iv))
+						return iv;
+			}
+		}
+		for (InferenceVariable iv : outerVariables) {
+			three = this.boundsPerVariable.get(outerVariables);
+			if (three != null) {
+				for (TypeBound bound : three.sameBounds)
+					if (TypeBinding.equalsEquals(bound.right, variable))
+						return iv;
+			}
+		}
+		return null;
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
index af9a341..4d4ce06 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding18.java
@@ -11,6 +11,7 @@
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
 
 /**
@@ -110,16 +111,12 @@
 				// capture of ? extends X[]
 				if (aBound != null && aBound.isArrayType()) {
 					if (!aBound.isCompatibleWith(otherType))
-						continue;
-				}
-				switch (otherType.kind()) {
+						return false;
+				} else switch (otherType.kind()) {
 					case Binding.WILDCARD_TYPE :
 					case Binding.INTERSECTION_TYPE :
 						if (!((WildcardBinding) otherType).boundCheck(aBound))
 							return false;
-						break;
-					default:
-						return false;
 				}
 			}
 			return true;
@@ -128,17 +125,50 @@
 	}
 
 	public boolean isCompatibleWith(TypeBinding otherType, Scope captureScope) {
+		if (TypeBinding.equalsEquals(this, otherType))
+			return true;
 		if (this.inRecursiveFunction)
 			return true;
 		this.inRecursiveFunction = true; 
 		try {
 			if (this.upperBounds != null) {
-				for (int i = 0; i < this.upperBounds.length; i++) {
+				int length = this.upperBounds.length;
+
+				// need to compare two intersection types? (borrowed from IntersectionType18)
+				int rightKind = otherType.kind();
+				TypeBinding[] rightIntersectingTypes = null;
+				if (rightKind == INTERSECTION_TYPE && otherType.boundKind() == Wildcard.EXTENDS) {
+					TypeBinding allRightBounds = ((WildcardBinding) otherType).allBounds();
+					if (allRightBounds instanceof IntersectionTypeBinding18)
+						rightIntersectingTypes = ((IntersectionTypeBinding18) allRightBounds).intersectingTypes;
+				} else if (rightKind == INTERSECTION_TYPE18) {
+					rightIntersectingTypes = ((IntersectionTypeBinding18) otherType).intersectingTypes;
+				}
+				if (rightIntersectingTypes != null) {
+					int numRequired = rightIntersectingTypes.length;
+					TypeBinding[] required = new TypeBinding[numRequired];
+					System.arraycopy(rightIntersectingTypes, 0, required, 0, numRequired);
+					for (int i = 0; i < length; i++) {
+						TypeBinding provided = this.upperBounds[i];
+						for (int j = 0; j < required.length; j++) {
+							if (required[j] == null) continue;
+							if (provided.isCompatibleWith(required[j], captureScope)) {
+								required[j] = null;
+								if (--numRequired == 0)
+									return true;
+								break;
+							}
+						}
+					}
+					return false;
+				}
+
+				for (int i = 0; i < length; i++) {
 					if (this.upperBounds[i].isCompatibleWith(otherType, captureScope))
 						return true;
 				}
 			}
-			return super.isCompatibleWith(otherType, captureScope);
+			return false;
 		} finally {
 			this.inRecursiveFunction = false;
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 44590fa..8b71156 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -21,6 +21,7 @@
  *							Bug 427199 - [1.8][resource] avoid resource leak warnings on Streams that have no resource
  *							Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
  *							Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
+ *							Bug 444024 - [1.8][compiler][null] Type mismatch error in annotation generics assignment which happens "sometimes"
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 415821 - [1.8][compiler] CLASS_EXTENDS target type annotation missing for anonymous classes
  *******************************************************************************/
@@ -2161,32 +2162,39 @@
 			return; // catchup was blocked.
 // SH}
 		SourceTypeBinding sourceType = this.referenceContext.binding;
-		if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
-			sourceType.tagBits |= TagBits.BeginHierarchyCheck;
-			environment().typesBeingConnected.add(sourceType);
-			boolean noProblems = connectSuperclass();
-			noProblems &= connectSuperInterfaces();
-			environment().typesBeingConnected.remove(sourceType);
-			sourceType.tagBits |= TagBits.EndHierarchyCheck;
-			noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
-			sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
-			if (noProblems && sourceType.isHierarchyInconsistent())
-				problemReporter().hierarchyHasProblems(sourceType);
-		}
-//{ObjectTeams: top level source super-team must be fully loaded/connected:
-		ReferenceBinding superType= sourceType.superclass;
-		if (   superType != null
-				&& superType.isTeam()) 
-		{
-			ReferenceBinding superOriginal = (ReferenceBinding) superType.original();
-			if (!superOriginal.isBinaryBinding()) {
-				ClassScope superScope = ((SourceTypeBinding) superOriginal).scope;
-				if (superScope != null)
-					superScope.connectTypeHierarchy();
+		CompilationUnitScope compilationUnitScope = compilationUnitScope();
+		boolean wasAlreadyConnecting = compilationUnitScope.connectingHierarchy;
+		compilationUnitScope.connectingHierarchy = true;
+		try {
+			if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
+				sourceType.tagBits |= TagBits.BeginHierarchyCheck;
+				environment().typesBeingConnected.add(sourceType);
+				boolean noProblems = connectSuperclass();
+				noProblems &= connectSuperInterfaces();
+				environment().typesBeingConnected.remove(sourceType);
+				sourceType.tagBits |= TagBits.EndHierarchyCheck;
+				noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
+				sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
+				if (noProblems && sourceType.isHierarchyInconsistent())
+					problemReporter().hierarchyHasProblems(sourceType);
 			}
-		}
+//{ObjectTeams: top level source super-team must be fully loaded/connected:
+			ReferenceBinding superType= sourceType.superclass;
+			if (   superType != null
+					&& superType.isTeam()) 
+			{
+				ReferenceBinding superOriginal = (ReferenceBinding) superType.original();
+				if (!superOriginal.isBinaryBinding()) {
+					ClassScope superScope = ((SourceTypeBinding) superOriginal).scope;
+					if (superScope != null)
+						superScope.connectTypeHierarchy();
+				}
+			}
 // SH}
-		connectMemberTypes();
+			connectMemberTypes();
+		} finally {
+			compilationUnitScope.connectingHierarchy = wasAlreadyConnecting;
+		}
 		LookupEnvironment env = environment();
 		try {
 			env.missingClassFileLocation = this.referenceContext;
@@ -2234,16 +2242,23 @@
 		if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) != 0)
 			return;
 
-		sourceType.tagBits |= TagBits.BeginHierarchyCheck;
-		environment().typesBeingConnected.add(sourceType);
-		boolean noProblems = connectSuperclass();
-		noProblems &= connectSuperInterfaces();
-		environment().typesBeingConnected.remove(sourceType);
-		sourceType.tagBits |= TagBits.EndHierarchyCheck;
-		noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
-		sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
-		if (noProblems && sourceType.isHierarchyInconsistent())
-			problemReporter().hierarchyHasProblems(sourceType);
+		CompilationUnitScope compilationUnitScope = compilationUnitScope();
+		boolean wasAlreadyConnecting = compilationUnitScope.connectingHierarchy;
+		compilationUnitScope.connectingHierarchy = true;
+		try {
+			sourceType.tagBits |= TagBits.BeginHierarchyCheck;
+			environment().typesBeingConnected.add(sourceType);
+			boolean noProblems = connectSuperclass();
+			noProblems &= connectSuperInterfaces();
+			environment().typesBeingConnected.remove(sourceType);
+			sourceType.tagBits |= TagBits.EndHierarchyCheck;
+			noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
+			sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
+			if (noProblems && sourceType.isHierarchyInconsistent())
+				problemReporter().hierarchyHasProblems(sourceType);
+		} finally {
+			compilationUnitScope.connectingHierarchy = wasAlreadyConnecting;
+		}
 	}
 
 //{ObjectTeams: ROFI (to be overridden in OTClassScope)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 539237f..1f013a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -571,13 +571,8 @@
 public
 // SH}
 void connectTypeHierarchy() {
-	this.connectingHierarchy = true;
-	try {
-		for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
-			this.topLevelTypes[i].scope.connectTypeHierarchy();
-	} finally {
-		this.connectingHierarchy = false;
-	}
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
+		this.topLevelTypes[i].scope.connectTypeHierarchy();
 }
 //{ObjectTeams: support faultInTypes being controlled by Dependencies
 // record when imports have been built:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
index ef47dae..c716b53 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
@@ -79,13 +79,13 @@
 		
 		TypeBinding[] ePrime = null;
 		if (this.left instanceof LambdaExpression) {
-			LambdaExpression lambda = ((LambdaExpression) this.left).resolveExpressionExpecting(this.right, inferenceContext.scope);
+			LambdaExpression lambda = ((LambdaExpression) this.left).resolveExpressionExpecting(this.right, inferenceContext.scope, inferenceContext);
 			if (lambda == null)
 				return TRUE; // cannot make use of this buggy constraint
 			Set<TypeBinding> ePrimeSet = lambda.getThrownExceptions();
 			ePrime = ePrimeSet.toArray(new TypeBinding[ePrimeSet.size()]);
 		} else {
-			ReferenceExpression referenceExpression = ((ReferenceExpression) this.left).resolveExpressionExpecting(this.right, scope);
+			ReferenceExpression referenceExpression = ((ReferenceExpression) this.left).resolveExpressionExpecting(this.right, scope, inferenceContext);
 			MethodBinding method = referenceExpression != null ? referenceExpression.binding : null;
 			if (method != null)
 				ePrime = method.thrownExceptions;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index 2bae5e3..f472d2d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -155,7 +155,7 @@
 					for (int i = 0; i < parameters.length; i++)
 						if (!parameters[i].isProperType(true))
 							return FALSE;
-				lambda = lambda.resolveExpressionExpecting(t, inferenceContext.scope);
+				lambda = lambda.resolveExpressionExpecting(t, inferenceContext.scope, inferenceContext);
 				if (lambda == null)
 					return FALSE; // not strictly unreduceable, but proceeding with TRUE would likely produce secondary errors
 				if (functionType.returnType == TypeBinding.VOID) {
@@ -238,7 +238,7 @@
 		if (functionType == null)
 			return FALSE;
 		// potentially-applicable method for the method reference when targeting T (15.13.1),
-		reference = reference.resolveExpressionExpecting(t, inferenceContext.scope);
+		reference = reference.resolveExpressionExpecting(t, inferenceContext.scope, inferenceContext);
 		MethodBinding potentiallyApplicable = reference != null ? reference.binding : null;
 		if (potentiallyApplicable == null)
 			return FALSE;
@@ -436,7 +436,7 @@
 				if (sam.returnType != TypeBinding.VOID) {
 					// ii)
 					final TypeBinding r = sam.returnType;
-					LambdaExpression resolved = lambda.resolveExpressionExpecting(this.right, context.scope);
+					LambdaExpression resolved = lambda.resolveExpressionExpecting(this.right, context.scope, context);
 					Expression[] resultExpressions = resolved != null ? resolved.resultExpressions() : null;
 					for (int i = 0, length = resultExpressions == null ? 0 : resultExpressions.length; i < length; i++) {
 						variables.addAll(new ConstraintExpressionFormula(resultExpressions[i], r, COMPATIBLE).inputVariables(context));
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index e21bfb3..3f48667 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -120,7 +120,7 @@
 						// recurse to prepare currentSuper
 						checkImplicitNullAnnotations(currentSuper, null, false, scope); // TODO (stephan) complain=true if currentSuper is source method??
 					}
-					checkNullSpecInheritance(currentMethod, srcMethod, needToApplyReturnNonNullDefault, needToApplyParameterNonNullDefault, complain, currentSuper, scope, inheritedNonNullnessInfos);
+					checkNullSpecInheritance(currentMethod, srcMethod, needToApplyReturnNonNullDefault, needToApplyParameterNonNullDefault, complain, currentSuper, null, scope, inheritedNonNullnessInfos);
 					needToApplyNonNullDefault = false;
 				}
 				
@@ -204,16 +204,18 @@
 	{
 		MethodBinding [] ifcMethods = superType.getMethods(selector, suggestedParameterLength);
 		int length = ifcMethods.length;
+		boolean added = false;
 		for  (int i=0; i<length; i++) {
 			MethodBinding currentMethod = ifcMethods[i];
 			if (currentMethod.isStatic())
 				continue;
 			if (MethodVerifier.doesMethodOverride(original, currentMethod, this.environment)) {
 				result.add(currentMethod);
-				return; // at most one method is overridden from any supertype
+				added = true; // when overriding one or more methods from superType don't traverse to transitive superTypes
 			}
 		}
-		findAllOverriddenMethods(original, selector, suggestedParameterLength, superType, ifcsSeen, result);
+		if (!added)
+			findAllOverriddenMethods(original, selector, suggestedParameterLength, superType, ifcsSeen, result);
 	}
 
 	/**
@@ -225,6 +227,7 @@
 	 * @param shouldComplain should we report any errors found? 
 	 *   (see also comment about flows into this method, below).
 	 * @param inheritedMethod one overridden method from a super type
+	 * @param allInheritedMethods look here to see if nonnull-unannotated conflict already exists in one super type
 	 * @param scope provides context for error reporting etc.
 	 * @param inheritedNonNullnessInfos if non-null, this array of non-null elements is used for
 	 * 	 interim recording of nullness information from inheritedMethod rather than prematurely updating currentMethod.
@@ -232,7 +235,7 @@
 	 */
 	void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
 			boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean shouldComplain,
-			MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos) 
+			MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos) 
 	{
 		// Note that basically two different flows lead into this method:
 		// (1) during MethodVerifyer15.checkMethods() we want to report errors (against srcMethod or against the current type)
@@ -336,6 +339,7 @@
 		else if (currentMethod.parameterNonNullness != null)
 			length = currentMethod.parameterNonNullness.length;
 
+		parameterLoop:
 		for (int i = 0; i < length; i++) {
 			if (currentMethod.parameters[i].isBaseType()) continue;
 
@@ -416,6 +420,12 @@
 						continue;
 					} else if (inheritedNonNullNess == Boolean.TRUE) {
 						// not strictly a conflict, but a configurable warning is given anyway:
+						if (allInheritedMethods != null) {
+							// avoid this optional warning if the conflict already existed in one supertype (merging of two methods into one?)
+							for (MethodBinding one : allInheritedMethods)
+								if (TypeBinding.equalsEquals(inheritedMethod.declaringClass, one.declaringClass) && getParameterNonNullness(one, i, useTypeAnnotations) != Boolean.TRUE)
+									continue parameterLoop;
+						}
 						scope.problemReporter().parameterLackingNonnullAnnotation(
 								currentArgument,
 								inheritedMethod.declaringClass,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index 4d0629e..c885c81 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -180,12 +180,13 @@
 	}
 	
 	/** Construct an inference context for an invocation (method/constructor). */
-	public InferenceContext18(Scope scope, Expression[] arguments, InvocationSite site) {
+	public InferenceContext18(Scope scope, Expression[] arguments, InvocationSite site, InferenceContext18 outerContext) {
 		this.scope = scope;
 		this.environment = scope.environment();
 		this.object = scope.getJavaLangObject();
 		this.invocationArguments = arguments;
 		this.currentInvocation = site;
+		this.outerContext = outerContext;
 	}
 
 	public InferenceContext18(Scope scope) {
@@ -241,11 +242,9 @@
 			TypeBinding thetaF = substitute(parameters[i]);
 			if (this.invocationArguments[i].isPertinentToApplicability(parameters[i], method)) {
 				this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
-			} else {
-				if (parameters[i].isPertinentToApplicability(this.invocationArguments[i], method))
-					this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.POTENTIALLY_COMPATIBLE);
-				// else we know it is potentially compatible, no need to assert.
-			}
+			} else if (!isTypeVariableOfCandidate(parameters[i], method)) {
+				this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.POTENTIALLY_COMPATIBLE);
+			} // else we know it is potentially compatible, no need to assert.
 		}
 		if (checkVararg && varArgsType instanceof ArrayBinding) {
 			varArgsType = ((ArrayBinding)varArgsType).elementsType();
@@ -253,11 +252,9 @@
 			for (int i = len; i < this.invocationArguments.length; i++) {
 				if (this.invocationArguments[i].isPertinentToApplicability(varArgsType, method)) {
 					this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
-				} else {
-					if (varArgsType.isPertinentToApplicability(this.invocationArguments[i], method))
-						this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.POTENTIALLY_COMPATIBLE);
-					// else we know it is potentially compatible, no need to assert.
-				}
+				} else if (!isTypeVariableOfCandidate(varArgsType, method)) {
+					this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.POTENTIALLY_COMPATIBLE);
+				} // else we know it is potentially compatible, no need to assert.
 			}
 		}
 		if (numConstraints == 0)
@@ -270,6 +267,18 @@
 		}
 	}
 
+	private boolean isTypeVariableOfCandidate(TypeBinding type, MethodBinding candidate) {
+		// cf. FunctionalExpression.isPertinentToApplicability()
+		if (type instanceof TypeVariableBinding) {
+			Binding declaringElement = ((TypeVariableBinding) type).declaringElement;
+			if (declaringElement == candidate)
+				return true;
+			if (candidate.isConstructor() && declaringElement == candidate.declaringClass)
+				return true;
+		}
+		return false;
+	}
+
 	private InferenceVariable[] addInitialTypeVariableSubstitutions(TypeBinding[] typeVariables) {
 		int len = typeVariables.length;
 		if (len == 0) {
@@ -448,6 +457,7 @@
 		if (expri instanceof FunctionalExpression) {
 			c.add(new ConstraintExceptionFormula((FunctionalExpression) expri, substF));
 			if (expri instanceof LambdaExpression) {
+				// https://bugs.openjdk.java.net/browse/JDK-8038747
 				LambdaExpression lambda = (LambdaExpression) expri;
 				BlockScope skope = lambda.enclosingScope;
 				if (substF.isFunctionalInterface(skope)) { // could be an inference variable.
@@ -457,7 +467,7 @@
 						t = ConstraintExpressionFormula.findGroundTargetType(this, skope, lambda, withWildCards);
 					}
 					MethodBinding functionType;
-					if (t != null && (functionType = t.getSingleAbstractMethod(skope, true)) != null && (lambda = lambda.resolveExpressionExpecting(t, this.scope)) != null) {
+					if (t != null && (functionType = t.getSingleAbstractMethod(skope, true)) != null && (lambda = lambda.resolveExpressionExpecting(t, this.scope, this)) != null) {
 						TypeBinding r = functionType.returnType;
 						Expression[] resultExpressions = lambda.resultExpressions();
 						for (int i = 0, length = resultExpressions == null ? 0 : resultExpressions.length; i < length; i++) {
@@ -490,7 +500,7 @@
 			
 			if (interleaved) {
 				MethodBinding shallowMethod = innerMethod.shallowOriginal();
-				SuspendedInferenceRecord prevInvocation = enterPolyInvocation(invocation, invocation.arguments());
+				SuspendedInferenceRecord prevInvocation = enterPolyInvocation(invocation, arguments);
 				try {
 					this.inferenceKind = applicabilityKind;
 					if (innerContext != null)
@@ -502,7 +512,7 @@
 					resumeSuspendedInference(prevInvocation);
 				}
 			}
-			return addConstraintsToC(invocation.arguments(), c, innerMethod.genericMethod(), applicabilityKind, interleaved);
+			return addConstraintsToC(arguments, c, innerMethod.genericMethod(), applicabilityKind, interleaved);
 		} else if (expri instanceof ConditionalExpression) {
 			ConditionalExpression ce = (ConditionalExpression) expri;
 			return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method, interleaved)
@@ -846,11 +856,18 @@
 	public TypeBinding /*@Nullable*/[] getSolutions(TypeVariableBinding[] typeParameters, InvocationSite site, BoundSet boundSet) {
 		int len = typeParameters.length;
 		TypeBinding[] substitutions = new TypeBinding[len];
+		InferenceVariable[] outerVariables = null;
+		if (this.outerContext != null && this.outerContext.stepCompleted < TYPE_INFERRED)
+			outerVariables = this.outerContext.inferenceVariables;
 		for (int i = 0; i < typeParameters.length; i++) {
 			for (int j = 0; j < this.inferenceVariables.length; j++) {
 				InferenceVariable variable = this.inferenceVariables[j];
 				if (variable.site == site && TypeBinding.equalsEquals(variable.typeParameter, typeParameters[i])) {
-					substitutions[i] = boundSet.getInstantiation(variable, this.environment);
+					TypeBinding outerVar = null;
+					if (outerVariables != null && (outerVar = boundSet.getEquivalentOuterVariable(variable, outerVariables)) != null)
+						substitutions[i] = outerVar;
+					else
+						substitutions[i] = boundSet.getInstantiation(variable, this.environment);
 					break;
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index ff8ec8c..0f96e43 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -31,6 +31,7 @@
  *								Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
  *								Bug 440773 - [1.8][null]DefaultLocation.RETURN_TYPE erroneously affects method parameters in @NonNullByDefault
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -116,7 +117,7 @@
 					this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
 		}
 		if (analyseNullAnnotations && !concreteMethod.isStatic() && !abstractMethod.isStatic()) {
-			checkNullSpecInheritance(concreteMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, abstractMethod, this.type.scope, null);
+			checkNullSpecInheritance(concreteMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, abstractMethod, abstractMethods, this.type.scope, null);
 		}
 	}
 }
@@ -420,12 +421,12 @@
 		boolean hasParameterNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter, useTypeAnnotations);
 		for (int i = length; --i >= 0;)
 			if (!currentMethod.isStatic() && !methods[i].isStatic())
-				checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, methods[i], this.type.scope, null);
+				checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, methods[i], methods, this.type.scope, null);
 	}
 }
 
 void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
-		boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean complain, MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
+		boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean complain, MethodBinding inheritedMethod, MethodBinding[] allInherited, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
 {
 	complain &= !currentMethod.isConstructor();
 	if (!hasReturnNonNullDefault && !hasParameterNonNullDefault && !complain && !this.environment.globalOptions.inheritNullAnnotations) {
@@ -439,7 +440,7 @@
 	{
 		this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, scope);
 	}
-	super.checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
+	super.checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, complain, inheritedMethod, allInherited, scope, inheritedNonNullnessInfos);
 }
 
 void reportRawReferences() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 954382b..c5fff60 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -22,6 +22,7 @@
  *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
  *								Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
  *								Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -278,7 +279,7 @@
 					}
 					if (invocationTypeInferred) {
 						if (compilerOptions.isAnnotationBasedNullAnalysisEnabled)
-							NullAnnotationMatching.checkForContraditions(methodSubstitute, invocationSite, scope);
+							NullAnnotationMatching.checkForContradictions(methodSubstitute, invocationSite, scope);
 //{ObjectTeams: 2nd arg added:
 /* orig:
 						MethodBinding problemMethod = methodSubstitute.boundCheck18(scope, arguments);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index 5be3f28..8c07094 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -727,7 +727,7 @@
 		    	// substitute methods, so as to get updated declaring class at least
 	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
 	            if (useNullTypeAnnotations)
-	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContraditions(parameterizedMethods[i], null, null);
+	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContradictions(parameterizedMethods[i], null, null);
 		    }
 		    if (this.methods == null) {
 				MethodBinding[] temp = new MethodBinding[length];
@@ -1079,7 +1079,7 @@
 		    	// substitute all methods, so as to get updated declaring class at least
 	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
 	            if (useNullTypeAnnotations)
-	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContraditions(parameterizedMethods[i], null, null);
+	            	parameterizedMethods[i] = NullAnnotationMatching.checkForContradictions(parameterizedMethods[i], null, null);
 		    }
 
 		    this.methods = parameterizedMethods;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
index da0a97f..9149909 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
@@ -38,20 +38,10 @@
 	}
 	
 	@Override
-	public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) {
-		return this.expression.isPertinentToApplicability(targetType, method);
-	}
-	
-	@Override
 	public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope) {
 		return this.expression.isPotentiallyCompatibleWith(targetType, scope);
 	}
-	
-	@Override
-	public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method) {
-		return this.expression.isPertinentToApplicability(typeVariable, method);
-	}
-	
+
 	@Override
 	public boolean isPolyType() {
 		return true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReductionResult.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReductionResult.java
index 97a0acc..6ee883b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReductionResult.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReductionResult.java
@@ -26,7 +26,6 @@
 		public Object reduce(InferenceContext18 context) { return this; }
 		public String toString() { return "FALSE"; } //$NON-NLS-1$
 	};
-	/** Used to accept unchecked conversion to make ecj conform with javac bug https://bugs.openjdk.java.net/browse/JDK-8026527 */
 	
 	// Relation kinds, mimic an enum:
 	protected static final int COMPATIBLE = 1;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index 60fe64a..e671d55 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -34,6 +34,8 @@
  *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
  *								Bug 431581 - Eclipse compiles what it should not
  *								Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *      Jesper S Moller - Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -45,9 +47,12 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
 import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
@@ -1679,6 +1684,18 @@
 					return isCompatibleWith(otherLowerBound);
 				}
 			}
+			if (otherType instanceof InferenceVariable) {
+				// may interpret InferenceVariable as a joker, but only when within an outer lambda inference:
+				if (captureScope != null) {
+					MethodScope methodScope = captureScope.methodScope();
+					if (methodScope != null) {
+						ReferenceContext referenceContext = methodScope.referenceContext;
+						if (referenceContext instanceof LambdaExpression
+								&& ((LambdaExpression)referenceContext).inferenceContext != null)
+							return true;
+					}
+				}
+			}
 			//$FALL-THROUGH$
 		case Binding.GENERIC_TYPE :
 		case Binding.TYPE :
@@ -2433,11 +2450,14 @@
 	final LookupEnvironment environment = scope.environment();
 	boolean genericMethodSeen = false;
 	int length = methods.length;
+	boolean analyseNullAnnotations = environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;
 	
 	next:for (int i = length - 1; i >= 0; --i) {
 		MethodBinding method = methods[i], otherMethod = null;
 		if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
 			genericMethodSeen = true;
+		TypeBinding returnType = method.returnType;
+		TypeBinding[] parameters = method.parameters;
 		for (int j = 0; j < length; j++) {
 			if (i == j) continue;
 			otherMethod = methods[j];
@@ -2450,7 +2470,11 @@
 					continue next;
 			}
 			if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment)) 
-				continue next; 
+				continue next;
+			if (analyseNullAnnotations) {
+				returnType = NullAnnotationMatching.strongerType(returnType, otherMethod.returnType, environment);
+				parameters = NullAnnotationMatching.weakerTypes(parameters, otherMethod.parameters, environment);
+			}
 		}
 		// If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ...
 		ReferenceBinding [] exceptions = new ReferenceBinding[0];
@@ -2516,8 +2540,8 @@
 		}
 		this.singleAbstractMethod[index] = new MethodBinding(theAbstractMethod.modifiers | ClassFileConstants.AccSynthetic, 
 				theAbstractMethod.selector, 
-				theAbstractMethod.returnType, 
-				theAbstractMethod.parameters, 
+				returnType, 
+				parameters, 
 				exceptions, 
 				theAbstractMethod.declaringClass);
 	    this.singleAbstractMethod[index].typeVariables = theAbstractMethod.typeVariables;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index c5881f8..ba61fd9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -47,6 +47,8 @@
  *								Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
  *								Bug 434483 - [1.8][compiler][inference] Type inference not picked up with method reference
  *								Bug 441734 - [1.8][inference] Generic method with nested parameterized type argument fails on method reference
+ *								Bug 452194 - Code no longer compiles in 4.4.1, but with confusing error
+ *								Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
  *     Jesper S Moller - Contributions for
  *								Bug 378674 - "The method can be declared as static" is wrong
  *  							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
@@ -816,6 +818,8 @@
 			} else if (!method.isOverriding() || !isOverriddenMethodGeneric(method)) {
 				return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.TypeParameterArityMismatch);
 			}
+		} else if (typeVariables == Binding.NO_TYPE_VARIABLES && method instanceof PolyParameterizedGenericMethodBinding) {
+			return method;
 		}
 
 		if (tiebreakingVarargsMethods) {
@@ -1867,6 +1871,8 @@
 					if (diff1 >= diff2)
 						continue nextMethod;
 				}
+				if (bestGuess != methodBinding && MethodVerifier.doesMethodOverride(bestGuess, methodBinding, this.environment()))
+					continue;
 				bestArgMatches = argMatches;
 				bestGuess = methodBinding;
 			}
@@ -4710,7 +4716,7 @@
 						} else {
 							expressions = ((ReferenceExpression)invocationSite).createPseudoExpressions(argumentTypes);
 						}
-						InferenceContext18 ic18 = new InferenceContext18(this, expressions, null);
+						InferenceContext18 ic18 = new InferenceContext18(this, expressions, null, null);
 						if (!ic18.isMoreSpecificThan(mbj, mbk, levelj == VARARGS_COMPATIBLE, levelk == VARARGS_COMPATIBLE)) {
 							continue nextJ;
 						}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index d8a4bf9..f3ba9bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -40,7 +40,6 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
@@ -572,14 +571,6 @@
 	return (this.tagBits & TagBits.IsBaseType) != 0;
 }
 
-public boolean isPertinentToApplicability(TypeVariableBinding typeVariable, MethodBinding method) {
-	return true;
-}
-
-public boolean isPertinentToApplicability(TypeBinding argument, MethodBinding method) {
-	return true;
-}
-
 /* Answer true if the receiver is a base type other than void or null
  */
 public final boolean isPrimitiveType() {
@@ -1787,8 +1778,4 @@
 public boolean isFunctionalType() {
 	return false;
 }
-
-public boolean isPertinentToApplicability(Expression expression, MethodBinding method) {
-	return true;
-}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 13caa21..1bd1f86 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -38,7 +38,6 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
 import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -613,15 +612,6 @@
 		this.inRecursiveFunction = false;
 	}
 	
-	@Override
-	public boolean isPertinentToApplicability(Expression expression, MethodBinding method) {
-		return expression.isPertinentToApplicability(this, method);
-	}
-	
-	public boolean isPertinentToApplicability(TypeBinding argument, MethodBinding method) {
-		return argument != null && argument.isPertinentToApplicability(this, method);
-	}
-	
 	public boolean isProperType(boolean admitCapture18) {
 		// handle recursive calls:
 		if (this.inRecursiveFunction) // be optimistic, since this node is not an inference variable
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index c18c655..e90e95e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -56,6 +56,7 @@
  *								Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
  *								Bug 439298 - [null] "Missing code implementation in the compiler" when using @NonNullByDefault in package-info.java
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
+ *								Bug 446442 - [1.8] merge null annotations from super methods
  *      Jesper S Moller <jesper@selskabet.org> -  Contributions for
  *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
  *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -291,9 +292,11 @@
 			return CompilerOptions.UnusedLocalVariable;
 
 		case IProblem.ArgumentIsNeverUsed :
-		case IProblem.ExceptionParameterIsNeverUsed:
 			return CompilerOptions.UnusedArgument;
 
+		case IProblem.ExceptionParameterIsNeverUsed :
+			return CompilerOptions.UnusedExceptionParameter;
+
 		case IProblem.NoImplicitStringConversionForCharArrayExpression :
 			return CompilerOptions.NoImplicitStringConversion;
 
@@ -466,6 +469,10 @@
 		case IProblem.UninitializedNonNullFieldHintMissingDefault:
 		case IProblem.ReferenceExpressionParameterNullityMismatch:
 		case IProblem.ReferenceExpressionReturnNullRedef:
+		case IProblem.ContradictoryNullAnnotations:
+		case IProblem.ContradictoryNullAnnotationsOnBound:
+		case IProblem.ContradictoryNullAnnotationsInferred:
+		case IProblem.ContradictoryNullAnnotationsInferredFunctionType:
 			return CompilerOptions.NullSpecViolation;
 
 		case IProblem.ParameterLackingNonNullAnnotation:
@@ -811,6 +818,7 @@
 
 			case CompilerOptions.UnusedLocalVariable :
 			case CompilerOptions.UnusedArgument :
+			case CompilerOptions.UnusedExceptionParameter :
 			case CompilerOptions.UnusedImport :
 			case CompilerOptions.UnusedPrivateMember :
 			case CompilerOptions.UnusedDeclaredThrownException :
@@ -4788,7 +4796,7 @@
 			return;
 		case ProblemReasons.ContradictoryNullAnnotations:
 			problemMethod = (ProblemMethodBinding) method;
-			contradictoryNullAnnotationsInferred(problemMethod.closestMatch, (ASTNode)messageSend);
+			contradictoryNullAnnotationsInferred(problemMethod.closestMatch, messageSend);
 			return;
 		case ProblemReasons.NoError : // 0
 		default :
@@ -13943,12 +13951,9 @@
 }
 
 public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, ASTNode location) {
-	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart, location.sourceEnd);
+	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart, location.sourceEnd, false);
 }
-public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, InvocationSite location) {
-	contradictoryNullAnnotationsInferred(inferredMethod, location.sourceStart(), location.sourceEnd());
-}
-public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, int sourceStart, int sourceEnd) {
+public void contradictoryNullAnnotationsInferred(MethodBinding inferredMethod, int sourceStart, int sourceEnd, boolean isFunctionalExpression) {
 	// when this error is triggered we can safely assume that both annotations have been configured
 	char[][] nonNullAnnotationName = this.options.nonNullAnnotationName;
 	char[][] nullableAnnotationName = this.options.nullableAnnotationName;
@@ -13966,7 +13971,9 @@
 			new String(inferredMethod.selector),
 			typesAsString(inferredMethod, true, true)
 		};
-	this.handle(IProblem.ContradictoryNullAnnotationsInferred, arguments, shortArguments, sourceStart, sourceEnd);
+	this.handle(
+			isFunctionalExpression ? IProblem.ContradictoryNullAnnotationsInferredFunctionType : IProblem.ContradictoryNullAnnotationsInferred, 
+			arguments, shortArguments, sourceStart, sourceEnd);
 }
 
 public void contradictoryNullAnnotationsOnBounds(Annotation annotation, long previousTagBit) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index c410b78..e3d83ee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -830,6 +830,7 @@
 970 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}'', where ''{0}'' is a free type variable
 971 = The explicit type bound 'Object' is not affected by the nullness default for DefaultLocation.TYPE_BOUND.
 972 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as ''{2}'' (mismatching null constraints)
+973 = Contradictory null annotations: function type was inferred as ''{2} ({4})'', but only one of ''@{0}'' and ''@{1}'' can be effective at any location
 
 # Java 8
 1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/MethodSpec.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/MethodSpec.java
index 44a2512..f362984 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/MethodSpec.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/MethodSpec.java
@@ -794,7 +794,7 @@
 			expressions[i].resolvedType = argument.type.resolvedType;
 		}
 
-		return new InferenceContext18(scope, expressions, this);
+		return new InferenceContext18(scope, expressions, this, null);
 	}
 	
 	public ExpressionContext getExpressionContext() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/TypeAnalyzer.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/TypeAnalyzer.java
index e147aac..bd90e61 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/TypeAnalyzer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/TypeAnalyzer.java
@@ -630,7 +630,7 @@
 
 				@Override
 				public InferenceContext18 freshInferenceContext(Scope someScope) {
-					return new InferenceContext18(someScope, fakeArguments, this);
+					return new InferenceContext18(someScope, fakeArguments, this, null);
 				}
 			};
 		}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index dae211b..4e95489 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -105,14 +105,21 @@
 		 */
 		Map bindingKeysToBindings;
 		/**
-		 * This map is used to keep the correspondance between new bindings and the
-		 * compiler bindings as well as new annotation instances to their internal counterpart.
-		 * This is an identity map. We should only create one object for one binding or annotation.
+		 * This map is used to keep the correspondence between new bindings and the
+		 * compiler bindings to their internal counterpart.
+		 * This is an identity map. We should only create one object for one binding.
 		 */
 		Map compilerBindingsToASTBindings;
 
+		/**
+		 * This map is used to keep the correspondence between new annotation instances to their internal counterpart.
+		 * This is an identity map. We should only create one object for one annotation.
+		 */
+		Map compilerAnnotationBindingsToASTBindings;
+
 		BindingTables() {
 			this.compilerBindingsToASTBindings = new ConcurrentHashMap();
+			this.compilerAnnotationBindingsToASTBindings = new ConcurrentHashMap();
 			this.bindingKeysToBindings = new ConcurrentHashMap();
 		}
 
@@ -540,6 +547,21 @@
 		return null;
 	}
 
+	class AnnotationIdentityBinding {
+		org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance;
+		AnnotationIdentityBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance) {
+			this.internalInstance = internalInstance;
+		}
+		@Override
+		public boolean equals(Object o) {
+			return o instanceof AnnotationIdentityBinding && this.internalInstance == ((AnnotationIdentityBinding)o).internalInstance;
+		}
+		@Override
+		public int hashCode() {
+			return this.internalInstance.hashCode();
+		}
+	}
+
 	synchronized IAnnotationBinding getAnnotationInstance(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance) {
 		if (internalInstance == null) return null;
 		ReferenceBinding annotationType = internalInstance.getAnnotationType();
@@ -548,12 +570,13 @@
 				return null;
 			}
 		}
+		Object key =  new AnnotationIdentityBinding(internalInstance);
 		IAnnotationBinding domInstance =
-			(IAnnotationBinding) this.bindingTables.compilerBindingsToASTBindings.get(internalInstance);
+			(IAnnotationBinding) this.bindingTables.compilerAnnotationBindingsToASTBindings.get(key);
 		if (domInstance != null)
 			return domInstance;
 		domInstance = new AnnotationBinding(internalInstance, this);
-		this.bindingTables.compilerBindingsToASTBindings.put(internalInstance, domInstance);
+		this.bindingTables.compilerAnnotationBindingsToASTBindings.put(key, domInstance);
 		return domInstance;
 	}
 
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
index b1c6c5f..9329638 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -10,6 +10,7 @@
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  *******************************************************************************/
 package org.eclipse.jdt.core.formatter;
 
@@ -17,11 +18,12 @@
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.text.edits.TextEdit;
 
+import java.util.Map;
+
 /**
  * Specification for a generic source code formatter.
  *
  * @since 3.0
- * @noextend This class is not intended to be subclassed by clients.
  */
 public abstract class CodeFormatter {
 
@@ -296,4 +298,15 @@
 	public String createIndentationString(int indentationLevel) {
 		return Util.EMPTY_STRING;
 	}
+
+	/**
+	 * Sets the formatting options for this formatter.
+	 * <p>The default implementation ignores the options.
+	 *
+	 * @param options the options for the formatter
+	 * @since 3.11
+	 */
+	public void setOptions(Map<String, String> options) {
+		// Do nothing by default
+	}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index bc181a5..956ccb6 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -1,16 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *     Jesper Steen Moller - Contributions for
  *								bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
+ *     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
@@ -77,14 +78,13 @@
 	}
 
 	public DefaultCodeFormatter(DefaultCodeFormatterOptions defaultCodeFormatterOptions, Map options) {
-		if (options != null) {
-			this.options = options;
-			this.preferences = new DefaultCodeFormatterOptions(options);
-		} else {
+		if (options == null) {
 			this.options = JavaCore.getOptions();
 			this.preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings());
+			setDefaultCompilerOptions();
+		} else {
+			setOptions(options);
 		}
-		this.defaultCompilerOptions = getDefaultCompilerOptions();
 		if (defaultCodeFormatterOptions != null) {
 			this.preferences.set(defaultCodeFormatterOptions.getMap());
 		}
@@ -93,12 +93,12 @@
 	public DefaultCodeFormatter(Map options) {
 		this(null, options);
 	}
-	
+
 	public String createIndentationString(final int indentationLevel) {
 		if (indentationLevel < 0) {
 			throw new IllegalArgumentException();
 		}
-		
+
 		int tabs = 0;
 		int spaces = 0;
 		switch(this.preferences.tab_char) {
@@ -131,7 +131,7 @@
 		}
 		return buffer.toString();
 	}
-	
+
 	/**
 	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, java.lang.String, int, int, int, java.lang.String)
 	 */
@@ -173,7 +173,7 @@
 				return formatExpression(source, indentationLevel, lineSeparator, regions, includeComments);
 			case K_STATEMENTS :
 				return formatStatements(source, indentationLevel, lineSeparator, regions, includeComments);
-//{ObjectTeams: Parameter mappinmg is not handled by formatExpression because of separate parser method "parseParameterMapping" to parse snippets			
+//{ObjectTeams: Parameter mapping is not handled by formatExpression because of separate parser method "parseParameterMapping" to parse snippets			
 			case K_PARAMETER_MAPPING :
 				return formatParameterMapping(source, indentationLevel, lineSeparator, regions, includeComments);
 //jsv} 		
@@ -189,7 +189,7 @@
 	}
 
 	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
-		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
+		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), this.defaultCompilerOptions, true);
 
 		if (bodyDeclarations == null) {
 			// a problem occurred while parsing the source
@@ -227,7 +227,7 @@
 			}
 			this.preferences.initial_indentation_level = indentationLevel;
 			if (this.codeSnippetParsingUtil == null) this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
-			this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
+			this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), this.defaultCompilerOptions, true);
 			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, true);
 			IRegion coveredRegion = getCoveredRegion(regions);
 			int start = coveredRegion.getOffset();
@@ -239,8 +239,8 @@
 	}
 
 	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
-		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
-		
+		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), this.defaultCompilerOptions, true);
+
 		if (lineSeparator != null) {
 			this.preferences.line_separator = lineSeparator;
 		} else {
@@ -249,12 +249,12 @@
 		this.preferences.initial_indentation_level = indentationLevel;
 
 		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
-		
+
 		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
 	}
 
 	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
-		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
+		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), this.defaultCompilerOptions, true);
 
 		if (expression == null) {
 			// a problem occurred while parsing the source
@@ -265,7 +265,7 @@
 
 //{ObjectTeams: separate Method to format ParameterMappings
 	private TextEdit formatParameterMapping(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
-		Expression expression = this.codeSnippetParsingUtil.parseParameterMapping(source.toCharArray(), getDefaultCompilerOptions(), true);
+		Expression expression = this.codeSnippetParsingUtil.parseParameterMapping(source.toCharArray(), this.defaultCompilerOptions, true);
 		
 		if (expression == null) {
 			// a problem occured while parsing the source
@@ -277,7 +277,7 @@
 //jsv}
 	
 	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
-		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
+		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), this.defaultCompilerOptions, true, false);
 
 		if (constructorDeclaration.statements == null) {
 			// a problem occured while parsing the source
@@ -291,10 +291,10 @@
 		if (length == 1) {
 			return regions[0];
 		}
-		
+
 		int offset = regions[0].getOffset();
 		IRegion lastRegion = regions[length - 1];
-		
+
 		return new Region(offset, lastRegion.getOffset() + lastRegion.getLength() - offset);
 	}
 
@@ -305,21 +305,21 @@
 //{ObjectTeams: be nice:
 	@SuppressWarnings("unchecked")
 // SH}
-	private Map getDefaultCompilerOptions() {
+	private void setDefaultCompilerOptions() {
 		if (this.defaultCompilerOptions ==  null) {
 			Map optionsMap = new HashMap(30);
-			optionsMap.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); 
+			optionsMap.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
 			optionsMap.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
 			optionsMap.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE);
 			optionsMap.put(CompilerOptions.OPTION_MethodParametersAttribute, CompilerOptions.DO_NOT_GENERATE);
 			optionsMap.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
-			optionsMap.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.DISABLED); 
-			optionsMap.put(CompilerOptions.OPTION_ReportMethodWithConstructorName, CompilerOptions.IGNORE); 
+			optionsMap.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMethodWithConstructorName, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
-			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); 
-			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); 
+			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
 			optionsMap.put(CompilerOptions.OPTION_ReportHiddenCatchBlock, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.IGNORE);
@@ -328,7 +328,7 @@
 			optionsMap.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportNoEffectAssignment, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.IGNORE);
-			optionsMap.put(CompilerOptions.OPTION_ReportNoImplicitStringConversion, CompilerOptions.IGNORE); 
+			optionsMap.put(CompilerOptions.OPTION_ReportNoImplicitStringConversion, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportIndirectStaticAccess, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, CompilerOptions.IGNORE);
@@ -355,7 +355,7 @@
 			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, CompilerOptions.DISABLED);
 			optionsMap.put(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, CompilerOptions.IGNORE);
 			optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, CompilerOptions.IGNORE);
-			optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, CompilerOptions.DISABLED); 
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, CompilerOptions.DISABLED);
 			optionsMap.put(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, CompilerOptions.IGNORE);
 //{ObjectTeams:
 			optionsMap.put(CompilerOptions.OPTION_Decapsulation, CompilerOptions.REPORT_BINDING);
@@ -381,9 +381,10 @@
 			optionsMap.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
 			optionsMap.put(CompilerOptions.OPTION_TaskPriorities, Util.EMPTY_STRING);
 			optionsMap.put(CompilerOptions.OPTION_TaskCaseSensitive, CompilerOptions.DISABLED);
-			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract, CompilerOptions.DISABLED); 
-			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete, CompilerOptions.DISABLED); 
-			optionsMap.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED); 
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnavoidableGenericTypeProblems, CompilerOptions.ENABLED);
 			optionsMap.put(CompilerOptions.OPTION_MaxProblemPerUnit, String.valueOf(100));
 			optionsMap.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.DISABLED);
 			optionsMap.put(CompilerOptions.OPTION_ShareCommonFinallyBlocks, CompilerOptions.DISABLED);
@@ -407,7 +408,6 @@
 		if (javaOption != null)
 			this.defaultCompilerOptions.put(CompilerOptions.OPTION_PureJavaOnly, javaOption);
 // SH}			
-		return this.defaultCompilerOptions;		
 	}
 
 	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions, boolean includeComments) {
@@ -421,7 +421,7 @@
 		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
 		return this.newCodeFormatter.format(source, bodyDeclarations);
 	}
-	
+
 	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions, boolean includeComments) {
 		if (lineSeparator != null) {
 			this.preferences.line_separator = lineSeparator;
@@ -431,7 +431,7 @@
 		this.preferences.initial_indentation_level = indentationLevel;
 
 		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
-		
+
 		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
 		return textEdit;
 	}
@@ -445,7 +445,7 @@
 		this.preferences.initial_indentation_level = indentationLevel;
 
 		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
-		
+
 		return this.newCodeFormatter.format(source, constructorDeclaration);
 	}
 
@@ -459,16 +459,16 @@
 
 	private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
 		if (PROBING_SCANNER == null) {
-			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT 
+			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT
 			// do not tokenize white spaces to get single comments even with spaces before...
 			PROBING_SCANNER = new Scanner(true, false/*do not tokenize whitespaces*/, false/*nls*/, ClassFileConstants.JDK1_6, ClassFileConstants.JDK1_6, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
 		}
 		PROBING_SCANNER.setSource(source.toCharArray());
-		
+
 		IRegion coveredRegion = getCoveredRegion(regions);
 		int offset = coveredRegion.getOffset();
 		int length = coveredRegion.getLength();
-		
+
 		PROBING_SCANNER.resetTo(offset, offset + length - 1);
 		try {
 			int kind = -1;
@@ -498,19 +498,19 @@
 		PROBING_SCANNER.setSource((char[]) null);
 
 		// probe for expression
-		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
+		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), this.defaultCompilerOptions, true);
 		if (expression != null) {
 			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions, includeComments);
 		}
 
 		// probe for body declarations (fields, methods, constructors)
-		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
+		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), this.defaultCompilerOptions, true);
 		if (bodyDeclarations != null) {
 			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions, includeComments);
 		}
 
 		// probe for statements
-		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
+		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), this.defaultCompilerOptions, true, false);
 		if (constructorDeclaration.statements != null) {
 			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions, includeComments);
 		}
@@ -542,14 +542,28 @@
 			if (lastOffset > current.getOffset()) {
 				return false;
 			}
-			
+
 			if (current.getOffset() < 0 || current.getLength() < 0 || current.getOffset() + current.getLength() > maxLength) {
 				return false;
 			}
-			
+
 			lastOffset = current.getOffset() + current.getLength() - 1;
 		}
 
 		return true;
 	}
+
+	@Override
+	public void setOptions(Map<String, String> options) {
+		this.options = options;
+		Map<String, String> formatterPrefs = new HashMap<String, String>(options.size());
+		for (String key : options.keySet()) {
+			Object value = options.get(key);
+			if (value instanceof String) {
+				formatterPrefs.put(key, (String) value);
+			}
+		}
+		this.preferences = new DefaultCodeFormatterOptions(formatterPrefs);
+		setDefaultCompilerOptions();
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 933350a..53d611f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -103,6 +103,7 @@
  *     Jesper S Moller   - Contributions for bug 381345 : [1.8] Take care of the Java 8 major version
  *                       - added the following constants:
  *									COMPILER_CODEGEN_METHOD_PARAMETERS_ATTR
+ *     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  *     
  *******************************************************************************/
 
@@ -466,6 +467,19 @@
 	 */
 	public static final String COMPILER_PB_UNUSED_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedParameter"; //$NON-NLS-1$
 	/**
+	 * Compiler option ID: Reporting Unused Exception Parameter.
+	 * <p>When enabled, the compiler will issue an error or a warning for unused exception
+	 *    parameters (that is, the thrown exception is never read from).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 * @since 3.11
+	 */
+	public static final String COMPILER_PB_UNUSED_EXCEPTION_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedExceptionParameter"; //$NON-NLS-1$
+	/**
 	 * Compiler option ID: Reporting Unused Parameter if Implementing Abstract Method.
 	 * <p>When enabled, the compiler will signal unused parameters in abstract method implementations.</p>
 	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_UNUSED_PARAMETER}.</p>
@@ -2298,6 +2312,19 @@
 	public static final String TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC = PLUGIN_ID + ".timeoutForParameterNameFromAttachedJavadoc"; //$NON-NLS-1$
 
 	/**
+	 * Core option ID: The ID of the formatter to use in formatting operations.
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.javaFormatter"</code></dd>
+	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.core.defaultJavaFormatter"</code></dd>
+	 * </dl>
+	 * @see #DEFAULT_JAVA_FORMATTER
+	 * @see #JAVA_FORMATTER_EXTENSION_POINT_ID
+	 * @since 3.11
+	 * @category CoreOptionID
+	 */
+	public static final String JAVA_FORMATTER = PLUGIN_ID + ".javaFormatter"; //$NON-NLS-1$
+
+	/**
 	 * @since 2.0
 	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION},
 	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_BLOCK} ,
@@ -2859,6 +2886,23 @@
 // SH}
 
 	/**
+	 * The ID of the Eclipse built-in formatter.
+	 *
+	 * @see #JAVA_FORMATTER
+	 * @see #JAVA_FORMATTER_EXTENSION_POINT_ID
+	 * @since 3.11
+	 */
+	public static final String DEFAULT_JAVA_FORMATTER = PLUGIN_ID + ".defaultJavaFormatter"; //$NON-NLS-1$
+
+	/**
+	 * Name of the extension point for contributing a source code formatter
+	 * @see #JAVA_FORMATTER
+	 * @see #DEFAULT_JAVA_FORMATTER
+	 * @since 3.11
+	 */
+	public static final String JAVA_FORMATTER_EXTENSION_POINT_ID = "javaFormatter" ;  //$NON-NLS-1$
+
+	/**
 	 * Creates the Java core plug-in.
 	 * <p>
 	 * The plug-in instance is created automatically by the
@@ -5672,6 +5716,7 @@
 	 */
 	public void stop(BundleContext context) throws Exception {
 		try {
+			JavaModelManager.unregisterDebugOptionsListener();
 			JavaModelManager.getJavaModelManager().shutdown();
 		} finally {
 			// ensure we call super.stop as the last thing
@@ -5690,6 +5735,7 @@
 	 */
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
+		JavaModelManager.registerDebugOptionsListener(context);
 		JavaModelManager.getJavaModelManager().startup();
 	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
index 5a4f646..d8dc589 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -7,19 +7,18 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  *******************************************************************************/
 package org.eclipse.jdt.core;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
 import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
 import org.eclipse.jdt.core.compiler.IScanner;
 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
 import org.eclipse.jdt.core.formatter.CodeFormatter;
@@ -40,6 +39,14 @@
 import org.eclipse.jdt.internal.core.util.PublicScanner;
 import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
 /**
  * Factory for creating various compiler tools, such as scanners, parsers and compilers.
  * <p>
@@ -140,7 +147,10 @@
 	}
 
 	/**
-	 * Create an instance of the built-in code formatter.
+	 * Creates an instance of a code formatter. A code formatter implementation can be contributed via the extension
+	 * point "org.eclipse.jdt.core.javaFormatter". The formatter id specified in the
+	 * "org.eclipse.jdt.core.javaFormatter" is instantiated. If unable to find a registered extension, the factory will
+	 * default to using the default code formatter.
 	 * <p>The given options should at least provide the source level ({@link JavaCore#COMPILER_SOURCE}),
 	 * the  compiler compliance level ({@link JavaCore#COMPILER_COMPLIANCE}) and the target platform
 	 * ({@link JavaCore#COMPILER_CODEGEN_TARGET_PLATFORM}).
@@ -170,6 +180,35 @@
 			currentOptions.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.FALSE);
 			currentOptions.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.FALSE);
 		}
+		String formatterId = (String) options.get(JavaCore.JAVA_FORMATTER);
+		if (formatterId != null) {
+			IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID,
+					JavaCore.JAVA_FORMATTER_EXTENSION_POINT_ID);
+			if (extension != null) {
+				IExtension[] extensions = extension.getExtensions();
+				for (int i = 0; i < extensions.length; i++) {
+					IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+					for (int j = 0; j < configElements.length; j++) {
+						String initializerID = configElements[j].getAttribute("id"); //$NON-NLS-1$
+						if (initializerID != null && initializerID.equals(formatterId)) {
+							try {
+								Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
+								if (execExt instanceof CodeFormatter) {
+									CodeFormatter formatter = (CodeFormatter) execExt;
+									formatter.setOptions(currentOptions);
+									return formatter;
+								}
+							} catch (CoreException e) {
+								org.eclipse.jdt.internal.core.util.Util.log(e.getStatus());
+								break;
+							}
+						}
+					}
+				}
+			}
+			org.eclipse.jdt.internal.core.util.Util.log(IStatus.WARNING,
+					"Unable to instantiate formatter extension '" + formatterId + "', returning built-in formatter."); //$NON-NLS-1$ //$NON-NLS-2$
+		}
 		return new DefaultCodeFormatter(currentOptions);
 	}
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index 92ac570..28812d7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -73,6 +74,7 @@
 			defaultOptionsMap.put(optionName, entry.getValue());
 			optionNames.add(optionName);
 		}
+		defaultOptionsMap.put(JavaCore.JAVA_FORMATTER, JavaCore.DEFAULT_JAVA_FORMATTER);
 
 		// CodeAssist settings
 		defaultOptionsMap.put(JavaCore.CODEASSIST_VISIBILITY_CHECK, JavaCore.DISABLED);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 27cc4e6..62b0801 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -72,6 +72,10 @@
 import org.eclipse.jdt.internal.core.util.WeakHashSetOfCharArray;
 import org.eclipse.jdt.internal.core.util.LRUCache.Stats;
 import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.prefs.BackingStoreException;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -94,7 +98,7 @@
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 public class JavaModelManager implements ISaveParticipant, IContentTypeChangeListener {
-
+	private static ServiceRegistration<DebugOptionsListener> DEBUG_REGISTRATION;
 	private static final String NON_CHAINING_JARS_CACHE = "nonChainingJarsCache"; //$NON-NLS-1$
 	private static final String INVALID_ARCHIVES_CACHE = "invalidArchivesCache";  //$NON-NLS-1$
 	private static final String EXTERNAL_FILES_CACHE = "externalFilesCache";  //$NON-NLS-1$
@@ -252,6 +256,7 @@
 		public String toString() { return getDescription(); }
 	};
 
+	private static final String DEBUG = JavaCore.PLUGIN_ID + "/debug"; //$NON-NLS-1$
 	private static final String BUFFER_MANAGER_DEBUG = JavaCore.PLUGIN_ID + "/debug/buffermanager" ; //$NON-NLS-1$
 	private static final String INDEX_MANAGER_DEBUG = JavaCore.PLUGIN_ID + "/debug/indexmanager" ; //$NON-NLS-1$
 	private static final String INDEX_MANAGER_ADVANCED_DEBUG = JavaCore.PLUGIN_ID + "/debug/indexmanager/advanced" ; //$NON-NLS-1$
@@ -1674,99 +1679,58 @@
 		}
 	}
 
-	/**
-	 * Configure the plugin with respect to option settings defined in ".options" file
-	 */
-	public void configurePluginDebugOptions(){
-		if(JavaCore.getPlugin().isDebugging()){
-			String option = Platform.getDebugOption(BUFFER_MANAGER_DEBUG);
-			if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(BUILDER_DEBUG);
-			if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(COMPILER_DEBUG);
-			if(option != null) Compiler.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(BUILDER_STATS_DEBUG);
-			if(option != null) JavaBuilder.SHOW_STATS = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(COMPLETION_DEBUG);
-			if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
-			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(CP_RESOLVE_ADVANCED_DEBUG);
-			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(CP_RESOLVE_FAILURE_DEBUG);
-			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(DELTA_DEBUG);
-			if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(DELTA_DEBUG_VERBOSE);
-			if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(DOM_AST_DEBUG);
-			if(option != null) SourceRangeVerifier.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(DOM_AST_DEBUG_THROW);
-			if(option != null) {
-				SourceRangeVerifier.DEBUG_THROW = option.equalsIgnoreCase(TRUE) ;
+	public static void registerDebugOptionsListener(BundleContext context) {
+		// register debug options listener
+		Hashtable<String, String> properties = new Hashtable<String, String>(2);
+		properties.put(DebugOptions.LISTENER_SYMBOLICNAME, JavaCore.PLUGIN_ID);
+		DEBUG_REGISTRATION = context.registerService(DebugOptionsListener.class, new DebugOptionsListener() {
+			@Override
+			public void optionsChanged(DebugOptions options) {
+				boolean debug = options.getBooleanOption(DEBUG, false);
+				BufferManager.VERBOSE = debug && options.getBooleanOption(BUFFER_MANAGER_DEBUG, false);
+				JavaBuilder.DEBUG = debug && options.getBooleanOption(BUILDER_DEBUG, false);
+				Compiler.DEBUG = debug && options.getBooleanOption(COMPILER_DEBUG, false);
+				JavaBuilder.SHOW_STATS = debug && options.getBooleanOption(BUILDER_STATS_DEBUG, false);
+				CompletionEngine.DEBUG = debug && options.getBooleanOption(COMPLETION_DEBUG, false);
+				JavaModelManager.CP_RESOLVE_VERBOSE = debug && options.getBooleanOption(CP_RESOLVE_DEBUG, false);
+				JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED = debug && options.getBooleanOption(CP_RESOLVE_ADVANCED_DEBUG, false);
+				JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE = debug && options.getBooleanOption(CP_RESOLVE_FAILURE_DEBUG, false);
+				DeltaProcessor.DEBUG = debug && options.getBooleanOption(DELTA_DEBUG, false);
+				DeltaProcessor.VERBOSE = debug && options.getBooleanOption(DELTA_DEBUG_VERBOSE, false);
+				SourceRangeVerifier.DEBUG = debug && options.getBooleanOption(DOM_AST_DEBUG, false);
+				SourceRangeVerifier.DEBUG_THROW = debug && options.getBooleanOption(DOM_AST_DEBUG_THROW, false);
 				SourceRangeVerifier.DEBUG |= SourceRangeVerifier.DEBUG_THROW;
+				RewriteEventStore.DEBUG = debug && options.getBooleanOption(DOM_REWRITE_DEBUG, false);
+				TypeHierarchy.DEBUG = debug && options.getBooleanOption(HIERARCHY_DEBUG, false);
+				JobManager.VERBOSE = debug && options.getBooleanOption(INDEX_MANAGER_DEBUG, false);
+				IndexManager.DEBUG = debug && options.getBooleanOption(INDEX_MANAGER_ADVANCED_DEBUG, false);
+				JavaModelManager.VERBOSE = debug && options.getBooleanOption(JAVAMODEL_DEBUG, false);
+				JavaModelCache.VERBOSE = debug && options.getBooleanOption(JAVAMODELCACHE_DEBUG, false);
+				JavaModelOperation.POST_ACTION_VERBOSE = debug && options.getBooleanOption(POST_ACTION_DEBUG, false);
+				NameLookup.VERBOSE = debug && options.getBooleanOption(RESOLUTION_DEBUG, false);
+				BasicSearchEngine.VERBOSE = debug && options.getBooleanOption(SEARCH_DEBUG, false);
+				SelectionEngine.DEBUG = debug && options.getBooleanOption(SELECTION_DEBUG, false);
+				JavaModelManager.ZIP_ACCESS_VERBOSE = debug && options.getBooleanOption(ZIP_ACCESS_DEBUG, false);
+				SourceMapper.VERBOSE = debug && options.getBooleanOption(SOURCE_MAPPER_DEBUG_VERBOSE, false);
+				DefaultCodeFormatter.DEBUG = debug && options.getBooleanOption(FORMATTER_DEBUG, false);
+		
+				// configure performance options
+				if(PerformanceStats.ENABLED) {
+					CompletionEngine.PERF = PerformanceStats.isEnabled(COMPLETION_PERF);
+					SelectionEngine.PERF = PerformanceStats.isEnabled(SELECTION_PERF);
+					DeltaProcessor.PERF = PerformanceStats.isEnabled(DELTA_LISTENER_PERF);
+					JavaModelManager.PERF_VARIABLE_INITIALIZER = PerformanceStats.isEnabled(VARIABLE_INITIALIZER_PERF);
+					JavaModelManager.PERF_CONTAINER_INITIALIZER = PerformanceStats.isEnabled(CONTAINER_INITIALIZER_PERF);
+					ReconcileWorkingCopyOperation.PERF = PerformanceStats.isEnabled(RECONCILE_PERF);
+				}
 			}
-			
-			option = Platform.getDebugOption(DOM_REWRITE_DEBUG);
-			if(option != null) RewriteEventStore.DEBUG = option.equalsIgnoreCase(TRUE) ;
-			
-			option = Platform.getDebugOption(HIERARCHY_DEBUG);
-			if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase(TRUE) ;
+		}, properties);
+	}
 
-			option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
-			if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(INDEX_MANAGER_ADVANCED_DEBUG);
-			if(option != null) IndexManager.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(JAVAMODEL_DEBUG);
-			if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(JAVAMODELCACHE_DEBUG);
-			if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(POST_ACTION_DEBUG);
-			if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(RESOLUTION_DEBUG);
-			if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(SEARCH_DEBUG);
-			if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(SELECTION_DEBUG);
-			if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
-			if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE);
-			if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase(TRUE) ;
-
-			option = Platform.getDebugOption(FORMATTER_DEBUG);
-			if(option != null) DefaultCodeFormatter.DEBUG = option.equalsIgnoreCase(TRUE) ;
-		}
-
-		// configure performance options
-		if(PerformanceStats.ENABLED) {
-			CompletionEngine.PERF = PerformanceStats.isEnabled(COMPLETION_PERF);
-			SelectionEngine.PERF = PerformanceStats.isEnabled(SELECTION_PERF);
-			DeltaProcessor.PERF = PerformanceStats.isEnabled(DELTA_LISTENER_PERF);
-			JavaModelManager.PERF_VARIABLE_INITIALIZER = PerformanceStats.isEnabled(VARIABLE_INITIALIZER_PERF);
-			JavaModelManager.PERF_CONTAINER_INITIALIZER = PerformanceStats.isEnabled(CONTAINER_INITIALIZER_PERF);
-			ReconcileWorkingCopyOperation.PERF = PerformanceStats.isEnabled(RECONCILE_PERF);
-		}
+	public static void unregisterDebugOptionsListener() {
+		// unregister debug options listener
+		DEBUG_REGISTRATION.unregister();
+		DEBUG_REGISTRATION = null;
 	}
 
 	/*
@@ -5000,8 +4964,6 @@
 
 	public void startup() throws CoreException {
 		try {
-			configurePluginDebugOptions();
-
 			// initialize Java model cache
 			this.cache = new JavaModelCache();
 
diff --git a/org.eclipse.jdt.core/plugin.properties b/org.eclipse.jdt.core/plugin.properties
index 8e119a1..8f99944 100644
--- a/org.eclipse.jdt.core/plugin.properties
+++ b/org.eclipse.jdt.core/plugin.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2009 IBM Corporation and others.
+# Copyright (c) 2000, 2014 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
@@ -9,6 +9,7 @@
 #     IBM Corporation - initial API and implementation
 #     Fraunhofer FIRST - extended API and implementation
 #     Technical University Berlin - extended API and implementation
+#     Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
 ###############################################################################
 providerName=Eclipse.org - Object Teams
 pluginName=Object Teams Development Tooling Core
@@ -27,4 +28,5 @@
 javaSourceName=Java Source File
 javaClassName=Java Class File
 jarManifestName=JAR Manifest File
-
+traceComponentLabel=JDT Core
+javaFormatterName=Java Formatter
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
index 5d69788..2f48730 100644
--- a/org.eclipse.jdt.core/plugin.xml
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.0"?>
 <!--
-    Copyright (c) 2004, 2011 IBM Corporation and others.
+    Copyright (c) 2004, 2014 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
@@ -9,6 +9,7 @@
     
     Contributors:
         IBM Corporation - initial API and implementation
+        Harry Terkelsen (het@google.com) - Bug 449262 - Allow the use of third-party Java formatters
  -->
 
 <!-- =================================================================================== -->
@@ -67,6 +68,14 @@
 	schema="schema/annotationProcessorManager.exsd"/>
 
 <!-- =================================================================================== -->
+<!-- Extension Point: Java Source Formatter                                              -->
+<!-- =================================================================================== -->
+
+<extension-point name="%javaFormatterName"
+  id="javaFormatter"
+  schema="schema/javaFormatter.exsd"/>
+
+<!-- =================================================================================== -->
 <!-- Extension: Java Nature                                                              -->
 <!-- =================================================================================== -->
 
@@ -259,4 +268,31 @@
    <modifier class="org.eclipse.jdt.internal.core.JavaCorePreferenceModifyListener"/>
 </extension>
 
+<!-- =================================================================================== -->
+<!-- Extension: Eclipse tracing                                                          -->
+<!-- =================================================================================== -->
+<extension
+      point="org.eclipse.ui.trace.traceComponents">
+   <component
+         id="org.eclipse.jdt.core.trace"
+         label="%traceComponentLabel">
+      <bundle
+            consumed="false"
+            name="org.eclipse.jdt.core">
+      </bundle>
+   </component>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Code Formatter                                                      -->
+<!-- =================================================================================== -->
+<extension
+      point="org.eclipse.jdt.core.javaFormatter">
+   <javaFormatter
+         class="org.eclipse.jdt.internal.formatter.DefaultCodeFormatter"
+         id="org.eclipse.jdt.core.defaultJavaFormatter"
+         name="Eclipse [built-in]">
+   </javaFormatter>
+</extension>
+
 </plugin>
diff --git a/org.eclipse.jdt.core/schema/javaFormatter.exsd b/org.eclipse.jdt.core/schema/javaFormatter.exsd
new file mode 100644
index 0000000..a10d89b
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/javaFormatter.exsd
@@ -0,0 +1,125 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="javaFormatter" name="Java Formatter"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to supply their own Java source code formatter.
+The formatter is expected to use the default formatter&apos;s options.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="1" maxOccurs="unbounded">
+            <element ref="javaFormatter"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="javaFormatter">
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A unique identifier used to reference this Java formatter.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The name of this Java formatter, used to present this formatter in the UI.
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The fully-qualified name of the Java class that extends the org.eclipse.jdt.core.formatter.CodeFormatter abstract class.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.formatter.CodeFormatter:"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         3.11
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of a declaration of a &lt;code&gt;javaFormatter&lt;/code&gt;:
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.jdt.core.javaFormatter&quot;&gt;
+   &lt;javaFormatter
+         class=&quot;myformatter.MyFormatter&quot;
+         id=&quot;myformatter.javaFormatter&quot;
+         name=&quot;My Custom Formatter&quot;&gt;
+   &lt;/javaFormatter&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2014 Google Inc. and others.&lt;br&gt;
+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 
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>