Update jdt.core to I20150428-0800 (M7 warm-up).
Manually merge from origin (bogus lineend changes):
- NullTypeAnnotationTest
- AstConverter18Test (no real change)
- FormatterBugsTests (no real change)
- SpacePreparator
- SourceTypeBinding

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 7936ce0..a1fb1eb 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler;singleton:=true
-Bundle-Version: 3.11.0.qualifier
+Bundle-Version: 3.12.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests.compiler,
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index 1b27e0e..b89dd4a 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
-  <version>3.11.0-SNAPSHOT</version>
+  <version>3.12.0-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericDietRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericDietRecoveryTest.java
index 17e6dd6..f351736 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericDietRecoveryTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericDietRecoveryTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -954,7 +954,7 @@
 		expectedFullUnitToString,
 		expectedCompletionDietUnitToString, testName);
 }
-public void _test0019() {
+public void test0019() {
 
 	String s =
 		"package a;											\n"
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
index 3931ddb..dc9770e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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,8 @@
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
  *								bug 376590 - Private fields with @Inject are ignored by unused field validation
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -44,6 +46,23 @@
 		"@Retention(RUNTIME)\n" + 
 		"public @interface Inject {}\n";
 
+	protected static final String SPRINGFRAMEWORK_AUTOWIRED_NAME = "org/springframework/beans/factory/annotation/Autowired.java";
+	protected static final String SPRINGFRAMEWORK_AUTOWIRED_CONTENT =
+		"package org.springframework.beans.factory.annotation;\n" +
+		"import java.lang.annotation.Documented;\n" +
+		"import java.lang.annotation.ElementType;\n" +
+		"import java.lang.annotation.Retention;\n" +
+		"import java.lang.annotation.RetentionPolicy;\n" +
+		"import java.lang.annotation.Target;\n" +
+		"@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})\n" +
+		"@Retention(RetentionPolicy.RUNTIME)\n" +
+		"@Documented\n" +
+		"public @interface Autowired {\n" +
+		"\n" +
+		"	boolean required() default true;\n" +
+		"\n" +
+		"}";
+
 	public static Test buildComparableTestSuite(Class evaluationTestClass) {
 		Test suite = buildMinimalComplianceTestSuite(evaluationTestClass, F_1_5);
 		TESTS_COUNTERS.put(evaluationTestClass.getName(), new Integer(suite.countTestCases()));
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 2a0d236..67b74ff 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -902,16 +902,17 @@
 			.append(fileName)
 			.append("\" -d \"")
 			.append(EVAL_DIRECTORY);
+		String processAnnot = this.enableAPT ? "" : "-proc:none";
 		if (this.complianceLevel < ClassFileConstants.JDK1_5) {
 			buffer.append("\" -1.4 -source 1.3 -target 1.2");
 		} else if (this.complianceLevel == ClassFileConstants.JDK1_5) {
 			buffer.append("\" -1.5");
 		} else if (this.complianceLevel == ClassFileConstants.JDK1_6) {
-			buffer.append("\" -1.6 -proc:none");
+			buffer.append("\" -1.6 " + processAnnot);
 		} else if (this.complianceLevel == ClassFileConstants.JDK1_7) {
-			buffer.append("\" -1.7 -proc:none");
+			buffer.append("\" -1.7 " + processAnnot);
 		} else if (this.complianceLevel == ClassFileConstants.JDK1_8) {
-			buffer.append("\" -1.8 -proc:none");
+			buffer.append("\" -1.8 " + processAnnot);
 		}
 		buffer
 			.append(" -preserveAllLocals -nowarn -g -classpath \"")
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 34aa40c..17dad44 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -4499,4 +4499,44 @@
 			"The method method(File) is ambiguous for the type AmbiguousTest.AbstractClass\n" + 
 			"----------\n");
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=458563 - invalid ambiguous method error on Java 8 that isn't seen on Java 7 (or with javac)
+public void testBug458563() {
+	runConformTest(
+		new String[] {
+			"X.java",
+			"interface IStoredNode<T> extends INodeHandle<DocumentImpl>, NodeHandle { }\n" + 
+			"interface NodeHandle extends INodeHandle<DocumentImpl> { }\n" + 
+			"class DocumentImpl implements INodeHandle<DocumentImpl> {\n" + 
+			"	public Object getNodeId() {return null;}\n" + 
+			"}\n" + 
+			"interface INodeHandle<D> {\n" + 
+			"    public Object  getNodeId();\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"	public void foo(IStoredNode bar) {\n" + 
+			"		bar.getNodeId();\n" + 
+			"	}\n" + 
+			"}"
+	});
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=458563 - invalid ambiguous method error on Java 8 that isn't seen on Java 7 (or with javac)
+public void testBug458563a() {
+	runConformTest(
+		new String[] {
+			"X.java",
+			"interface IStoredNode<T> extends INodeHandle<DocumentImpl>, NodeHandle { }\n" + 
+			"interface NodeHandle extends INodeHandle<DocumentImpl> { }\n" + 
+			"class DocumentImpl implements INodeHandle<DocumentImpl> {\n" + 
+			"	public Object getNodeId() {return null;}\n" + 
+			"}\n" + 
+			"interface INodeHandle<D> {\n" + 
+			"    public Object  getNodeId();\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"	public void foo(IStoredNode<?> bar) {\n" + 
+			"		bar.getNodeId();\n" + 
+			"	}\n" + 
+			"}"
+	});
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index 32a21f7..676b8ba 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -19,6 +19,8 @@
  *     Jesper S Moller  - Contributions for
  *								bug 384567 - [1.5][compiler] Compiler accepts illegal modifiers on package declaration
  *								bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
 
@@ -11354,6 +11356,7 @@
 	} catch(org.eclipse.jdt.core.util.ClassFormatException cfe) {
 		fail("Error reading classfile");
 	}
+
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
 public void test449330() throws Exception {
@@ -11419,4 +11422,76 @@
 	this.runConformTest(testFiles, "");
 	checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
 }
+//https://bugs.eclipse.org/386692
+public void testBug386692() {
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
+	customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR);
+	this.runNegativeTest(
+		true,
+		new String[] {
+			SPRINGFRAMEWORK_AUTOWIRED_NAME,
+			SPRINGFRAMEWORK_AUTOWIRED_CONTENT,
+			"Example.java",
+			"class Example {\n" +
+			"  private @org.springframework.beans.factory.annotation.Autowired Object o;\n" +
+			"  private Example() {}\n" +
+			"  public Example(Object o) { this.o = o; }\n" +
+			"  private @org.springframework.beans.factory.annotation.Autowired void setO(Object o) { this.o = o;}\n" +
+			"}\n"
+		},
+		null, customOptions,
+		"----------\n" + 
+		"1. ERROR in Example.java (at line 2)\n" + 
+		"	private @org.springframework.beans.factory.annotation.Autowired Object o;\n" + 
+		"	                                                                       ^\n" + 
+		"The value of the field Example.o is not used\n" + 
+		"----------\n" + 
+		"2. ERROR in Example.java (at line 3)\n" + 
+		"	private Example() {}\n" + 
+		"	        ^^^^^^^^^\n" + 
+		"The constructor Example() is never used locally\n" + 
+		"----------\n",
+		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=464977
+public void testBug464977() throws Exception {
+	if (this.complianceLevel < ClassFileConstants.JDK1_6 || this.complianceLevel > ClassFileConstants.JDK1_8) {
+		return; // Enough to run in 3 levels rather!
+	}
+	boolean apt = this.enableAPT;
+	String source = "@Deprecated\n" +
+			"public class DeprecatedClass {\n" +
+			"}";
+	String version = "";
+	if  (this.complianceLevel == ClassFileConstants.JDK1_8) {
+		version = "1.8 : 52.0";
+	} else if  (this.complianceLevel == ClassFileConstants.JDK1_7) {
+		version = "1.7 : 51.0";
+	} else if  (this.complianceLevel == ClassFileConstants.JDK1_6) {
+		version = "1.6 : 50.0";
+	}
+	String expectedOutput = "// Compiled from DeprecatedClass.java (version " + version + ", super bit, deprecated)\n" + 
+							"@Deprecated\n" + 
+							"public class DeprecatedClass {\n" + 
+							"  \n" + 
+							"  // Method descriptor #6 ()V\n" + 
+							"  // Stack: 1, Locals: 1\n" + 
+							"  public DeprecatedClass();\n" + 
+							"    0  aload_0 [this]\n" + 
+							"    1  invokespecial Object() [8]\n" + 
+							"    4  return\n" + 
+							"      Line numbers:\n" + 
+							"        [pc: 0, line: 2]\n" + 
+							"      Local variable table:\n" + 
+							"        [pc: 0, pc: 5] local: this index: 0 type: DeprecatedClass\n" + 
+							"\n" + 
+							"}";
+	try {
+		this.enableAPT = true;
+		checkClassFile("DeprecatedClass", source, expectedOutput, ClassFileBytesDisassembler.DETAILED | ClassFileBytesDisassembler.COMPACT);
+	} finally {
+		this.enableAPT = apt;
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
index e8e16fc..4fe1df1 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2014 IBM Corporation and others.
+ * Copyright (c) 2003, 2015 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
@@ -3185,6 +3185,86 @@
 		assertEquals("Wrong contents", expectedOutput, actualOutput);
 	}
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=461706 [1.8][compiler] "Unnecessary cast" problems for necessary cast in lambda expression
+public void test461706() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_8)
+		return;
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR);
+	this.runConformTest(
+		new String[] {
+			"Bug.java",
+			"import java.util.ArrayList;\n" + 
+			"import java.util.List;\n" + 
+			"public class Bug {\n" + 
+			"	private static class AndCondition implements ICondition {\n" + 
+			"		public AndCondition(ICondition cond1, ICondition cond2) {\n" + 
+			"			// todo\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	private static class SimpleCondition implements ICondition {\n" + 
+			"	}\n" + 
+			"	private static interface ICondition {\n" + 
+			"		ICondition TRUE = new SimpleCondition();\n" + 
+			"		default ICondition and(final ICondition cond) {\n" + 
+			"			return new AndCondition(this, cond);\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	public static void main(final String[] args) {\n" + 
+			"		final List<SimpleCondition> conditions = new ArrayList<>();\n" + 
+			"		conditions.stream()\n" + 
+			"				.map(x -> (ICondition)x)\n" + 
+			"				.reduce((x, y) -> x.and(y))\n" + 
+			"				.orElse(ICondition.TRUE);\n" + 
+			"	}\n" + 
+			"}"
+		},
+		customOptions);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=461706 [1.8][compiler] "Unnecessary cast" problems for necessary cast in lambda expression
+public void test461706a() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_8)
+		return;
+	Map customOptions = getCompilerOptions();
+	customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR);
+	this.runNegativeTest(
+		new String[] {
+			"Bug.java",
+			"import java.util.ArrayList;\n" + 
+			"import java.util.List;\n" + 
+			"public class Bug {\n" + 
+			"	private static class AndCondition implements ICondition {\n" + 
+			"		public AndCondition(ICondition cond1, ICondition cond2) {\n" + 
+			"			// todo\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	static class SimpleCondition implements ICondition {\n" + 
+			"	}\n" + 
+			"	private static interface ICondition {\n" + 
+			"		ICondition TRUE = new SimpleCondition();\n" + 
+			"		default ICondition and(final ICondition cond) {\n" + 
+			"			return new AndCondition(this, cond);\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	public static void main(final String[] args) {\n" + 
+			"		final List<ICondition> conditions = new ArrayList<>();\n" + 
+			"		conditions.stream()\n" + 
+			"				.map(x -> (ICondition)x)\n" + 
+			"				.reduce((x, y) -> x.and(y))\n" + 
+			"				.orElse(ICondition.TRUE);\n" + 
+			"	}\n" + 
+			"}"
+		},
+		"----------\n" +
+		"1. ERROR in Bug.java (at line 20)\n" +
+		"	.map(x -> (ICondition)x)\n" +
+		"	          ^^^^^^^^^^^^^\n" +
+		"Unnecessary cast from Bug.ICondition to Bug.ICondition\n" +
+		"----------\n",
+		null,
+		true,
+		customOptions);
+}
 public static Class testClass() {
 	return CastTest.class;
 }
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 699683f..ac1c66a 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
@@ -5106,4 +5106,125 @@
 			"}\n"
 		});
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=445231, [compiler] IllegalAccessError running Eclipse-compiled class
+public void testBug445231() {
+	runConformTest(
+		true,
+		new String[] {
+		"com/n/Bug.java",
+		"package com.n;\n" +
+		"public class Bug {\n" +
+		"  public static void main(String[] args) {\n" +
+		"    try {\n" +
+		"      new Bug().go();\n" +
+		"      System.err.println(\"Ok\");\n" +
+		"    } catch (IllegalAccessError e) {\n" +
+		"      System.err.println(\"Error\");\n" +
+		"      e.printStackTrace();\n" +
+		"    }\n" +
+		"  }\n" +
+		"  public void go() {\n" +
+		"    Class<?> clazz = Buggered.Foo.class;\n" +
+		"    System.err.println(\"Here we go\");\n" +
+		"    if (clazz.isAnonymousClass()) {\n" +
+		"      System.err.println(\"is anon\");\n" +
+		"    } else {\n" +
+		"      System.err.println(\"not anon\");\n" +
+		"    }\n" +
+		"  }\n" +
+		"}\n",
+		"com/g/Base.java",
+		"package com.g;\n" +
+		"class Base2{}\n" +
+		"class Base {\n" +
+		"	class A {}\n" +
+		"	static class Builder<B extends Builder<B>> {\n" +
+		"		public B setJobName() {\n" +
+		"			return null;\n" +
+		"		}\n" +
+		"		public Base2 setJobName2(B b) {\n" +
+		"			return null;\n" +
+		"		}\n" +
+
+		//  Wildcard
+		"		public void foo(H<? super H<Base3.A>> h) {\n" +
+		"			return;\n" +
+		"  		}\n" +
+		"		private class H<T> {}\n" +
+		"	}\n" +
+		"   static class Builder2 {\n" +
+		"       public <B extends Builder<B>> B setJobName3() {\n" +
+		"	        return null;\n" +
+		"       }\n" +
+		"   }\n" +
+		"	static class R {}\n" +
+		"	public static class Builder3<B extends R> {\n" +
+		"		public B setJobName() {\n" +
+		"			return null;\n" +
+		"		}\n" +
+		"	}\n" +
+		"	public static class Builder4<B extends R> {\n" +
+		"		public <Q extends R> Builder3<Q> setJobName() {\n" +
+		"			return null;\n" +
+		"		}\n" +
+		"	}\n" +
+
+		// Testing Parameters
+		"	static class Builder5 {\n" +
+		"		public <B extends Builder<B>> void  foo(B b) {}\n" +
+		"	}\n" +
+
+		"}\n" +
+
+		"class Base3 {\n" +
+		"	static class A{}\n" +
+		"}\n"
+		,
+
+		"com/g/Child.java",
+		"package com.g;\n" +
+		"import com.g.Base.R;\n" +
+		"public final class Child {\n" +
+		"  public static class Builder<I> extends Base.Builder<Builder<I>> {\n" +
+		"	  public void setDummyName(){}\n" +
+		"  }\n" +
+		"  public static class Builder2 extends Base.Builder2 {}\n" +
+		"  public static class Builder3<I> extends  Base.Builder3<R> {}\n" +
+		"  public static class Builder4<I> extends  Base.Builder4<R> {}\n" +
+
+		"  public static class Builder5 extends Base.Builder5 {} \n" +
+		"}\n",
+		"com/n/Buggered.java",
+		"package com.n;\n" +
+		"import com.g.Child;\n" +
+		"class Z{}\n" +
+		"public final class Buggered {\n" +
+		"  public static final class Foo {}\n" +
+		"  void unused() {\n" +
+		"    Child.Builder<Void> c = new Child.Builder<Void>();\n" +
+		"    c.setJobName();\n" +
+		"    c.setJobName2(new Child.Builder<Void>());\n" +
+		"    Child.Builder<Z> cb = new Child.Builder<Z>();\n" +
+		"    cb.setJobName();\n" +
+		"    cb.setJobName2(new Child.Builder<Z>());\n" +
+		"    Child.Builder2 cb2 = new Child.Builder2();\n" +
+		"    cb2.setJobName3();\n" +
+		"    Child.Builder3<Void> cb3 = new Child.Builder3<Void>();\n" +
+		"    cb3.setJobName();\n" +
+		"    Child.Builder4<Void> cb4 = new Child.Builder4<Void>();\n" +
+		"    cb4.setJobName();\n" +
+
+		"    Child.Builder5 cb5 = new Child.Builder5();\n" +
+		"    cb5.foo(null);\n" +
+
+		//   Wildcard
+		"	c.foo(null);\n" +
+		"  }\n" +
+		"}\n"
+	},
+	null, null,
+	"Here we go\n" +
+	"not anon\n" +
+	"Ok", null);
+}
 }
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 eddb943..1c28ca2 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
@@ -782,6 +782,113 @@
 	"The blank final field value may not have been initialized\n" + 
 	"----------\n");
 }
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526
+// Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement 
+public void testBug463526() {
+	runNegativeTest(new String [] {
+		"Test.java",
+		"public class Test {\n" + 
+		"    public static void main(String[] args) {\n" + 
+		"        Receiver r = new Receiver();\n" + 
+		"        r.accept((l) -> (doItOnTheClass(new Object())));\n" + 
+		"    }\n" + 
+		"    public static void doItOnTheClass(Object o) {\n" + 
+		"        System.out.println(\"done it\");\n" + 
+		"    }\n" + 
+		"    public static class Receiver {\n" + 
+		"        public void accept(Listener l) {\n" + 
+		"            l.doIt(new Object());\n" + 
+		"        }\n" + 
+		"    }\n" + 
+		"    public static interface Listener {\n" + 
+		"        public void doIt(Object o);\n" + 
+		"    }\n" + 
+		"}"
+	},
+	"----------\n" + 
+	"1. ERROR in Test.java (at line 4)\n" + 
+	"	r.accept((l) -> (doItOnTheClass(new Object())));\n" + 
+	"	  ^^^^^^\n" + 
+	"The method accept(Test.Listener) in the type Test.Receiver is not applicable for the arguments ((<no type> l) -> {})\n" +
+	"----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526
+// Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement 
+public void testBug463526b() {
+	runNegativeTest(new String [] {
+		"Test.java",
+		"import java.util.function.Consumer;\n" + 
+		"public class Test {\n" + 
+		"    public static void main(String[] args) {\n" + 
+		"        Receiver r = new Receiver();\n" + 
+		"        r.process((o) -> (new Object()));\n" + 
+		"    }\n" + 
+		"    public static class Receiver {\n" + 
+		"        public void process(Consumer<Object> p) {\n" + 
+		"        }\n" + 
+		"    }\n" + 
+		"}"
+	},
+	"----------\n" + 
+	"1. ERROR in Test.java (at line 5)\n" + 
+	"	r.process((o) -> (new Object()));\n" + 
+	"	  ^^^^^^^\n" + 
+	"The method process(Consumer<Object>) in the type Test.Receiver is not applicable for the arguments ((<no type> o) -> {})\n" +
+	"----------\n" + 
+	"2. ERROR in Test.java (at line 5)\n" + 
+	"	r.process((o) -> (new Object()));\n" + 
+	"	                 ^^^^^^^^^^^^^^\n" + 
+	"Void methods cannot return a value\n" +
+	"----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=463526
+// Parenthesis are incorrectly allowed in lambda when LambdaBody is an expression statement 
+public void testBug463526c() {
+	runNegativeTest(new String [] {
+		"Test.java",
+		"import java.util.function.Consumer;\n" + 
+		"public class Test {\n" + 
+		"    public static void main(String[] args) {\n" + 
+		"        Receiver r = new Receiver();\n" + 
+		"        r.assign((o) -> (o = new Object()));\n" + 
+		"    }\n" + 
+		"    public static class Receiver {\n" + 
+		"        public void assign(Consumer<Object> a) {\n" + 
+		"        }\n" + 
+		"    }\n" + 
+		"}"
+	},
+	"----------\n" + 
+	"1. ERROR in Test.java (at line 5)\n" + 
+	"	r.assign((o) -> (o = new Object()));\n" + 
+	"	  ^^^^^^\n" + 
+	"The method assign(Consumer<Object>) in the type Test.Receiver is not applicable for the arguments ((<no type> o) -> {})\n" + 
+	"----------\n" + 
+	"2. ERROR in Test.java (at line 5)\n" + 
+	"	r.assign((o) -> (o = new Object()));\n" + 
+	"	                ^^^^^^^^^^^^^^^^^^\n" + 
+	"Void methods cannot return a value\n" +
+	"----------\n");
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=464408
+public void testBug464408() {
+	runNegativeTest(new String[]{
+		"test/X.java",
+		"import java.util.ArrayList;\n" +
+		"import java.util.List;\n" +
+		"public class X {\n" +
+		"   void x() {\n" +
+		"       List<List<String>> list = new ArrayList<>();\n" +
+		"       list.stream().toArray(List<String>[]::new);\n" +
+		"   }" +
+		"}"
+	}, "----------\n" + 
+		"1. ERROR in test\\X.java (at line 6)\n" + 
+		"	list.stream().toArray(List<String>[]::new);\n" + 
+		"	                      ^^^^^^^^^^^^^^^^^^^\n" + 
+		"Cannot create a generic array of List<String>\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/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index b31d027..b97f570 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
@@ -8053,4 +8053,474 @@
 		true,
 		customOptions);
 }
+public void testBug462790() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // multi catch used
+	runConformTestWithLibs(
+		new String[] {
+			"EclipseBug.java",
+			"@org.eclipse.jdt.annotation.NonNullByDefault\n" + 
+			"public class EclipseBug {\n" + 
+			"\n" + 
+			"	public void method(Class<? extends String> commandType) {\n" + 
+			"		String command = (String)getCommand(commandType);\n" + 
+			"	}\n" + 
+			"	\n" + 
+			"	public static <T extends String> T getCommand(Class<T> commandType) {\n" + 
+			"		try {\n" + 
+			"			return commandType.newInstance();\n" + 
+			"		} catch (InstantiationException | IllegalAccessException e) {\n" + 
+			"			throw new RuntimeException();\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"}"
+		},
+		getCompilerOptions(),
+		"----------\n" + 
+		"1. WARNING in EclipseBug.java (at line 5)\n" + 
+		"	String command = (String)getCommand(commandType);\n" + 
+		"	                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Unnecessary cast from capture#1-of ? extends String to String\n" + 
+		"----------\n" + 
+		"2. WARNING in EclipseBug.java (at line 8)\n" + 
+		"	public static <T extends String> T getCommand(Class<T> commandType) {\n" + 
+		"	                         ^^^^^^\n" + 
+		"The type parameter T should not be bounded by the final type String. Final types cannot be further extended\n" + 
+		"----------\n" +
+		(this.complianceLevel < ClassFileConstants.JDK1_8
+		?
+		"3. WARNING in EclipseBug.java (at line 10)\n" + 
+		"	return commandType.newInstance();\n" + 
+		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Null type safety: The expression of type \'T\' needs unchecked conversion to conform to \'@NonNull T\'\n" + 
+		"----------\n"
+		:
+		""));
+}
+public void testBug459967_Enum_valueOf() {
+	runConformTestWithLibs(
+		new String[] {
+			"MyEnum.java",
+			"public enum MyEnum { V1, V2 }\n",
+			"X.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"public class X {\n" +
+			"	@NonNull MyEnum forString(String name) {\n" +
+			"		return MyEnum.valueOf(name);\n" +
+			"	}\n" +
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+public void testBug459967_Enum_values() {
+	String[] testFiles = new String[] {
+		"MyEnum.java",
+		"public enum MyEnum { V1, V2 }\n",
+		"X.java",
+		"import org.eclipse.jdt.annotation.*;\n" +
+		"public class X {\n" +
+		(this.complianceLevel < ClassFileConstants.JDK1_8
+		?
+		"	@NonNull MyEnum[] getValues() {\n"
+		:
+		"	MyEnum @NonNull[] getValues() {\n"
+		)+
+		"		return MyEnum.values();\n" +
+		"	}\n" +
+		"	void printAll() {\n" +
+		"		for (@NonNull MyEnum value : MyEnum.values())\n" +
+		"			System.out.println(value);\n" +
+		"	}\n" +
+		"}\n"
+	};
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+		runConformTestWithLibs(
+				testFiles,
+				getCompilerOptions(),
+				"----------\n" + 
+				"1. WARNING in X.java (at line 7)\n" + 
+				"	for (@NonNull MyEnum value : MyEnum.values())\n" + 
+				"	                             ^^^^^^^^^^^^^^^\n" + 
+				"Null type safety: The expression of type \'MyEnum\' needs unchecked conversion to conform to \'@NonNull MyEnum\'\n" + 
+				"----------\n");		
+	} else {
+		runConformTestWithLibs(
+				testFiles,
+				getCompilerOptions(),
+				"");
+	}
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=407414
+// Incorrect warning on a primitive type being null.
+public void test407414a()  {
+	 String testCode = "package p1;\n" +
+			 "public class Test {\n" +
+			 "	void fooI(int i) { \n" +
+			 "		barI(i);\n" +
+			 "	}\n" +
+			 "	void fooB(boolean i) {\n" +
+			 "		barB(i);\n" +
+			 "	}\n" +
+			 "	void fooBy(byte i) {\n" +
+			 "		barBy(i);\n" +
+			 "	}\n" +
+			 "	void fooF(float i) {\n" +
+			 "		barF(i);\n" +
+			 "	}\n" +
+			 "	void fooL(long i) {\n" +
+			 "		barL(i);\n" +
+			 "	}\n" +
+			 "	void fooC(char i) {\n" +
+			 "		barC(i);\n" +
+			 "	}\n" +
+			 "	void fooS(short i) {\n" +
+			 "		barS(i);\n" +
+			 "	}\n" +
+			 "	static void barI(Integer i) {}\n" +
+			 "	static void barB(Boolean i) {}\n" +
+			 "	static void barBy(Byte i) {}\n" +
+			 "	static void barF(Float i) {}\n" +
+			 "	static void barL(Long i) {}\n" +
+			 "	static void barC(Character i) {}\n" +
+			 "	static void barS(Short i) {}\n" +
+			 "}";
+	 String pcode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			 "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=407414
+// Incorrect warning on a primitive type being null.
+// The information that boxing is happening at i2 = i
+// and therefore there cannot be null values in i2 is
+// not flowing down to access of i2.
+// The test case also illustrates array access and Qualified access.
+public void test407414b() {
+	 String testCode = "package p1;\n" +
+			 "  public class Test {\n" +
+			 "  class Y {\n" +
+			 "		class Z {\n" +
+			 "			int i;\n" +
+			 "          int a[];\n" +
+			 "      	Z() {\n" +
+			 "				a = new int[0];\n" +
+			 "      	}\n" +
+			 "		}\n" +
+			 "  }\n" +
+			 "	void foo(int i) {\n" +
+			 "		Integer i2 = i;\n" +
+			 "		bar(i2);\n" +
+			 "	}\n" +
+			 "	void fooA(int a[], int i) {\n" +
+			 "		Integer i2 = a[i];\n" +
+			 "		bar(i2);\n" +
+			 "	}\n" +
+			 "  void fooQ(Y.Z yz, int i) {\n" +
+			 "		Integer i2 = yz.i;\n" +
+			 "		bar(i2);\n" +
+			 "      i2 = yz.a[i];\n" +
+			 "      bar(i2);\n" +
+			 "  }\n" +
+			 "	static void bar(Integer i) { }\n" +
+			 "}";
+	 String pcode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			 "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+public void test407414b2() {
+	 String testCode = "package p1;\n" +
+			 "  public class Test {\n" +
+			 "  int a[];\n" +
+			 "  Test() {\n" +
+			 "		a = new int[0];\n" +
+			 "      a[0] = 0;\n" +
+			 "  }\n" +
+			 "	void fooA(int i) {\n" +
+			 "		Integer i2 = a[i];\n" +
+			 "		bar(i2);\n" +
+			 "	}\n" +
+			 "	static void bar(Integer i) { }\n" +
+			 "}";
+	 String pcode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			 "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// FieldReference.
+public void test407414b3() {
+	 String testCode = "package p1;\n" +
+			 "public class Test {\n" +
+			 "  class Z {\n" +
+			 "		int a[];\n" +
+			 "		Z() {\n" +
+			 "	  		a = new int[0];\n" +
+			 "	  		a[0] = 0;\n" +
+			 "		}\n" +
+			 "  }\n" +
+			 "  class Y {\n" +
+			 "		Z[] z;\n" +
+			 "		Y () {\n" +
+			 "	 		z = new Z[0];\n" +
+			 "		}\n" +
+			 "  }\n" +
+			 "  void fooQ(Y y, int i) {\n" +
+			 "		Integer i2 = y.z[i].a[i];\n" +
+			 "		bar(i2);\n" +
+			 "  }\n" +
+			 "  static void bar(Integer i) { }\n" +
+			 "}";
+	 String pcode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			 "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// arrayRefrence
+public void test407414b4() {
+	 String testCode = "package p1;\n" +
+			 "public class Test {\n" +
+			 "  class Y {\n" +
+			 "		int a[];\n" +
+			 "		Y() {\n" +
+			 "		  a = new int[0];\n" +
+			 "		  a[0] = 0;\n" +
+			 "		}\n" +
+			 "  }\n" +
+			 "  void fooQ(Y[] y, int i) {\n" +
+			 "		Integer i2 = y[i].a[i];\n" +
+			 "		bar(i2);\n" +
+			 "  }\n" +
+			 "  static void bar(Integer i) { }\n" +
+			 "}";
+	 String pcode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			 "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// value of a (compound) assignment
+public void testBug407414c() {
+	runConformTestWithLibs(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"  int fI;\n" +
+			"  @org.eclipse.jdt.annotation.NonNull Integer test1(int i) {\n" +
+			"		return fI = i;\n" +
+			"  }\n" + 
+			"  @org.eclipse.jdt.annotation.NonNull Integer test2(int i) {\n" +
+			"		return fI += i;\n" +
+			"  }\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// primitive cast
+public void testBug407414d() {
+	runConformTestWithLibs(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"  @org.eclipse.jdt.annotation.NonNull Long test(int i) {\n" +
+			"		return (long)i;\n" +
+			"  }\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// conditional
+public void testBug407414e() {
+	runConformTestWithLibs(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"  @org.eclipse.jdt.annotation.NonNull Long test(long l, boolean b) {\n" +
+			"		return b ? l : 3;\n" +
+			"  }\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// operators
+public void testBug407414f() {
+	runConformTestWithLibs(
+		new String[] {
+			"X.java",
+			"public class X {\n" +
+			"  @org.eclipse.jdt.annotation.NonNull Long test1(long l) {\n" +
+			"		return l + 3;\n" +
+			"  }\n" + 
+			"  @org.eclipse.jdt.annotation.NonNull Long test2(long l) {\n" +
+			"		return l << 3;\n" +
+			"  }\n" + 
+			"  @org.eclipse.jdt.annotation.NonNull Long test3(long l) {\n" +
+			"		return l++;\n" +
+			"  }\n" +
+			"  @org.eclipse.jdt.annotation.NonNull Long test4(long l) {\n" +
+			"		return -l;\n" +
+			"  }\n" +
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=428104
+// Null annotation heuristics does not understand autoboxed primitives to be non-null.
+public void test428104() {
+	 String testCode = "package p1;\n" +
+			 "import org.eclipse.jdt.annotation.NonNull;\n" +
+			 "public class Test {\n" +
+			 "    @NonNull\n" +
+			 "    Boolean case1Parent() {\n" +
+			 "        return case1Child();\n" +
+			 "    }\n" +
+			 "    boolean case1Child() {\n" +
+			 "        return Math.random() > 0.5;\n" +
+			 "    }\n" +
+			 "}\n";
+	 String pcode = "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=424702
+// Warning at an assignment of a boolean-Variable to an Boolean-Variable
+public void test424702() {
+	 String testCode = "package p1;\n" +
+			 "import org.eclipse.jdt.annotation.NonNull;\n" +
+			 "public class Test {\n" +
+			 "    private @NonNull Boolean t = true;\n" +
+			 "    Boolean foo() {\n" +
+			 "		boolean y = false;\n" +
+			 "      t = y;\n" +
+			 "		return t;\n" +
+			 "    }\n" +
+			 "}\n";
+	 String pcode = "package p1;";
+	 runConformTestWithLibs(
+		new String[] {
+			"p1/package-info.java",
+			pcode,
+			"p1/Test.java",
+			testCode
+		},
+		getCompilerOptions(),
+		"");
+}
+
+public void testBug237236() {
+	runConformTestWithLibs(
+		new String[] {
+			"X.java",
+			"@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+			"public class X {\n" +
+			"  public void x(Long l) {}\n" + 
+			"  public long z() { return 0L; }\n" + 
+			"  public void y() { x(z()); }\n" +
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+public void testBug418236() {
+	runConformTestWithLibs(
+		new String[] {
+			"MyClass.java",
+			"@org.eclipse.jdt.annotation.NonNullByDefault\n" + 
+			"public class MyClass {\n" + 
+			"  private static final int CONSTANT = 24;\n" + 
+			"\n" + 
+			"  public Integer returnConstant() {\n" + 
+			"    return CONSTANT; // <-- incorrect error. Integer.valueOf is declared as non-null.\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public Integer returnInteger() {\n" + 
+			"    return 24; // <-- no error reported here\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		getCompilerOptions(),
+		"");
+}
+public void testBug461878() {
+	Map compilerOptions = getCompilerOptions();
+	compilerOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "javax.annotation.Nonnull");
+	runNegativeTest(
+		new String[] {
+			"javax/annotation/Nonnull.java",
+			"package javax.annotation;\n" + 
+			"import java.lang.annotation.Retention;\n" + 
+			"import java.lang.annotation.RetentionPolicy;\n" + 
+			"@Retention(RetentionPolicy.RUNTIME)\n" + 
+			"public @interface Nonnull {\n" + 
+			"}\n",
+			"edu/umd/cs/findbugs/annotations/PossiblyNull.java",
+			"package edu.umd.cs.findbugs.annotations;\n" + 
+			"@javax.annotation.Nonnull // <-- error!!!\n" + 
+			"public @interface PossiblyNull {\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. WARNING in edu\\umd\\cs\\findbugs\\annotations\\PossiblyNull.java (at line 2)\n" + 
+		"	@javax.annotation.Nonnull // <-- error!!!\n" + 
+		"	^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"The nullness annotation \'Nonnull\' is not applicable at this location\n" + 
+		"----------\n",
+		null,
+		true,
+		compilerOptions);
+}
 }
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 1e3fba1..cf625da 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
@@ -1212,7 +1212,7 @@
 				"1. ERROR in Y1.java (at line 5)\n" + 
 				"	X1<@Nullable String> maybeStrings;\n" + 
 				"	   ^^^^^^^^^^^^^^^^\n" + 
-				"Null constraint mismatch: The type \'@Nullable String\' is not a valid substitute for the type parameter \'@NonNull T extends @NonNull Object\'\n" + 
+				"Null constraint mismatch: The type \'@Nullable String\' is not a valid substitute for the type parameter \'T extends @NonNull Object\'\n" + 

 				"----------\n" + 
 				"2. ERROR in Y1.java (at line 6)\n" + 
 				"	X2<@NonNull String> strings;\n" + 
@@ -1222,7 +1222,7 @@
 				"3. ERROR in Y1.java (at line 8)\n" + 
 				"	x.<Y1, @NonNull Object>foo(this, new Object());\n" + 
 				"	       ^^^^^^^^^^^^^^^\n" + 
-				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'@Nullable V extends @Nullable Object'\n" + 
+				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'V extends @Nullable Object'\n" + 

 				"----------\n"
 				);
 	}
@@ -1288,7 +1288,7 @@
 				"1. ERROR in Y1.java (at line 3)\n" + 
 				"	p.X1<java.lang.@Nullable String> maybeStrings;\n" + 
 				"	     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-				"Null constraint mismatch: The type \'@Nullable String\' is not a valid substitute for the type parameter \'@NonNull T extends @NonNull Object\'\n" + 
+				"Null constraint mismatch: The type \'@Nullable String\' is not a valid substitute for the type parameter \'T extends @NonNull Object\'\n" + 

 				"----------\n" + 
 				"2. ERROR in Y1.java (at line 4)\n" + 
 				"	p.X2<java.lang.@NonNull String> strings;\n" + 
@@ -1298,7 +1298,7 @@
 				"3. ERROR in Y1.java (at line 6)\n" + 
 				"	x.<Y1, java.lang.@NonNull Object>foo(this, new Object());\n" + 
 				"	       ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'@Nullable V extends @Nullable Object\'\n" + 
+				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'V extends @Nullable Object\'\n" + 

 				"----------\n"
 				);
 	}
@@ -1342,7 +1342,7 @@
 				"1. ERROR in Y1.java (at line 5)\n" + 
 				"	x.<@NonNull Y1, @NonNull Object>foo(this, new Object())\n" + 
 				"	                ^^^^^^^^^^^^^^^\n" + 
-				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'@Nullable V extends @Nullable Object\'\n" + 
+				"Null constraint mismatch: The type \'@NonNull Object\' is not a valid substitute for the type parameter \'V extends @Nullable Object\'\n" + 

 				"----------\n" + 
 				"2. ERROR in Y1.java (at line 6)\n" + 
 				"	.get(0).put(null, null);\n" + 
@@ -4860,7 +4860,12 @@
 		"	       ^^^^\n" + 
 		"Null type mismatch: required \'@NonNull T\' but the provided value is null\n" + 
 		"----------\n" + 
-		"2. ERROR in X.java (at line 11)\n" + 
+		"2. ERROR in X.java (at line 10)\n" + 

+		"	void test(Inner<Number> inum) {\n" + 

+		"	                ^^^^^^\n" + 

+		"Null constraint mismatch: The type \'Number\' is not a valid substitute for the type parameter \'@NonNull T\'\n" + 

+		"----------\n" + 

+		"3. ERROR in X.java (at line 11)\n" + 

 		"	@NonNull Number nnn = inum.process(null); // ERR on argument\n" + 
 		"	                                   ^^^^\n" + 
 		"Null type mismatch: required \'@NonNull Number\' but the provided value is null\n" + 
@@ -4918,7 +4923,7 @@
 			" 		}\n" +
 			"	}\n" +
 			"	void test(Inner inner) {\n" +
-			"		@NonNull Number nnn = inner.process(Integer.MAX_VALUE, new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" +
+			"		@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" +

 			"	}\n" +
 			"}\n"
 		},
@@ -4930,12 +4935,12 @@
 		"Null type mismatch: required \'T extends @NonNull Number\' but the provided value is null\n" + 
 		"----------\n" + 
 		"2. WARNING in X.java (at line 13)\n" + 
-		"	@NonNull Number nnn = inner.process(Integer.MAX_VALUE, new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 
-		"	                                    ^^^^^^^^^^^^^^^^^\n" + 
-		"Null type safety (type annotations): The expression of type \'int\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" + 
+		"	@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 

+		"	                                    ^^^^^^^^^^^^^^^^^^\n" + 

+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" + 

 		"----------\n" + 
 		"3. ERROR in X.java (at line 13)\n" + 
-		"	@NonNull Number nnn = inner.process(Integer.MAX_VALUE, new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 
+		"	@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 

 		"	                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
 		"Null type mismatch (type annotations): required \'List<? extends @NonNull Number>\' but this expression has type \'ArrayList<@Nullable Integer>\', corresponding supertype is \'List<@Nullable Integer>\'\n" + 
 		"----------\n");
@@ -5187,16 +5192,16 @@
 			"import java.util.*;\n" +
 			"public class Y {\n" +
 			"	void test(X.Inner inner) {\n" +
-			"		@NonNull Number nnn = inner.process(Integer.MAX_VALUE, new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" +
+			"		@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" +

 			"	}\n" +
 			"}\n"
 		},
 		getCompilerOptions(),
 		"----------\n" +  // FIXME: this should not be a warning, a case of unrecognized boxing
 		"1. WARNING in Y.java (at line 5)\n" + 
-		"	@NonNull Number nnn = inner.process(Integer.MAX_VALUE, new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 
-		"	                                    ^^^^^^^^^^^^^^^^^\n" + 
-		"Null type safety (type annotations): The expression of type \'int\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" + 
+		"	@NonNull Number nnn = inner.process(Integer.valueOf(3), new ArrayList<@Nullable Integer>()); // WARN on 1. arg; ERR on 2. arg\n" + 

+		"	                                    ^^^^^^^^^^^^^^^^^^\n" + 

+		"Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" + 

 		"----------\n");
 }
 public void testBug431269() {
@@ -6984,7 +6989,7 @@
 		"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" + 
+		"Contradictory null annotations: method was inferred as \'@Nullable @NonNull String a(@Nullable @NonNull String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n");
 }
 public void testBug446442_comment2a() {
@@ -7312,17 +7317,17 @@
 		"		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" + 
+		"Contradictory null annotations: function type was inferred as \'ArrayList<@NonNull @Nullable Integer> (ArrayList<@Nullable @NonNull 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" + 
+		"Contradictory null annotations: method was inferred as \'boolean add(@Nullable @NonNull 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" + 
+		"Contradictory null annotations: method was inferred as \'@Nullable @NonNull Integer get(int)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n");
 }
 public void testBug453475() {
@@ -7532,7 +7537,7 @@
 		"2. ERROR in Optional.java (at line 5)\n" + 
 		"	public static <@NonNull T> Optional<T> of(T value) { return new Optional<T>(value); }\n" + 
 		"	                                                            ^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Contradictory null annotations: method was inferred as \'void <init>(@NonNull @Nullable T)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"Contradictory null annotations: method was inferred as \'void <init>(@Nullable @NonNull T)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n" + 
 		"3. ERROR in Optional.java (at line 5)\n" + 
 		"	public static <@NonNull T> Optional<T> of(T value) { return new Optional<T>(value); }\n" + 
@@ -7548,12 +7553,12 @@
 		"2. ERROR in OTest.java (at line 6)\n" + 
 		"	@NonNull String s = os1.get();\n" + 
 		"	                    ^^^^^^^^^\n" + 
-		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable String get()\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"Contradictory null annotations: method was inferred as \'@Nullable @NonNull String get()\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n" + 
 		"3. ERROR in OTest.java (at line 7)\n" + 
 		"	@Nullable String ns = os1.orElse(null);\n" + 
 		"	                      ^^^^^^^^^^^^^^^^\n" + 
-		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable String orElse(@NonNull @Nullable String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"Contradictory null annotations: method was inferred as \'@Nullable @NonNull String orElse(@Nullable @NonNull String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n" + 
 		"4. ERROR in OTest.java (at line 10)\n" + 
 		"	Optional<String> os = Optional.of(null);\n" + 
@@ -7568,7 +7573,7 @@
 		"6. ERROR in OTest.java (at line 11)\n" + 
 		"	@NonNull String s = os.orElse(null);\n" + 
 		"	                    ^^^^^^^^^^^^^^^\n" + 
-		"Contradictory null annotations: method was inferred as \'@NonNull @Nullable String orElse(@NonNull @Nullable String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 
+		"Contradictory null annotations: method was inferred as \'@Nullable @NonNull String orElse(@Nullable @NonNull String)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" + 

 		"----------\n");
 }
 public void testBug454182() {
@@ -7739,4 +7744,171 @@
 		"1->2\n" +
 		"1->2");
 }
+public void testBug459967_Array_constructor() {

+	runConformTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"interface FI<T> {\n" +

+			"	T @NonNull[] getArray(int size);" +

+			"}\n" +

+			"public class X {\n" +

+			"	void consumer(FI<String> fis) {}\n" +

+			"	void test() {\n" +

+			"		consumer(String[]::new);\n" +

+			"	}\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"");

+}

+public void testBug459967_Array_constructor_b() {

+	runNegativeTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"interface FI<T> {\n" +

+			"	@NonNull T @NonNull[] getArray(int size);" +

+			"}\n" +

+			"public class X {\n" +

+			"	void consumer(FI<String> fis) {}\n" +

+			"	void test() {\n" +

+			"		consumer(String[]::new);\n" +

+			"	}\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. WARNING in X.java (at line 7)\n" + 

+		"	consumer(String[]::new);\n" + 

+		"	         ^^^^^^^^^^^^^\n" + 

+		"Null type safety at method return type: Method descriptor FI<String>.getArray(int) promises \'@NonNull String @NonNull[]\' but referenced method provides \'String @NonNull[]\'\n" + 

+		"----------\n");

+}

+public void testBug459967_Array_clone() {

+	runConformTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"interface FI<T> {\n" +

+			"	T @NonNull[] getArray(T[] orig);" +

+			"}\n" +

+			"public class X {\n" +

+			"	void consumer(FI<String> fis) {}\n" +

+			"	void test() {\n" +

+			"		consumer(String[]::clone);\n" +

+			"	}\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"");

+}

+public void testBug459967_Array_clone_b() {

+	runNegativeTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"interface FI<T> {\n" +

+			"	@NonNull T @NonNull[] getArray(T[] orig);" +

+			"}\n" +

+			"public class X {\n" +

+			"	void consumer(FI<String> fis) {}\n" +

+			"	void test() {\n" +

+			"		consumer(String[]::clone);\n" +

+			"	}\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. WARNING in X.java (at line 7)\n" + 

+		"	consumer(String[]::clone);\n" + 

+		"	         ^^^^^^^^^^^^^^^\n" + 

+		"Null type safety at method return type: Method descriptor FI<String>.getArray(String[]) promises \'@NonNull String @NonNull[]\' but referenced method provides \'String @NonNull[]\'\n" + 

+		"----------\n");

+}

+public void testBug448709_allocationExpression1() {

+	// inference prioritizes constraint (<@Nullable T>) over expected type (@NonNull String), hence a null type mismatch results

+	runNegativeTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"interface F0<T> {}\n" +

+			"class FI<@Nullable T> implements F0<T> {\n" +

+			"}\n" +

+			"public abstract class X {\n" +

+			"	abstract <Z> Z zork(F0<Z> f);\n" +

+			"	@NonNull String test() {\n" +

+			"		 return zork(new FI<>());\n" +

+			"	}\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. ERROR in X.java (at line 8)\n" + 

+		"	return zork(new FI<>());\n" + 

+		"	            ^^^^^^^^^^\n" + 

+		"Null type mismatch (type annotations): required \'F0<@NonNull String>\' but this expression has type \'FI<@Nullable String>\', corresponding supertype is \'F0<@Nullable String>\'\n" + 

+		"----------\n");

+}

+public void testBug448709_allocationExpression2() {

+	runNegativeTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"class F {\n" +

+			"	<@Nullable U> F(U arg1, U arg2) {}\n" +

+			"}\n" +

+			"public class X {\n" +

+			"	F f = new <@NonNull Integer>F(1,2);\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. ERROR in X.java (at line 6)\n" + 

+		"	F f = new <@NonNull Integer>F(1,2);\n" + 

+		"	           ^^^^^^^^^^^^^^^^\n" + 

+		"Null constraint mismatch: The type \'@NonNull Integer\' is not a valid substitute for the type parameter \'@Nullable U\'\n" + 

+		"----------\n");

+}

+public void testBug448709_allocationExpression3() {

+	runNegativeTestWithLibs(

+		new String[] {

+			"X.java",

+			"import org.eclipse.jdt.annotation.*;\n" +

+			"public class X {\n" +

+			"	class F {\n" +

+			"		<@Nullable U> F(U arg1, U arg2) {}\n" +

+			"	}\n" +

+			"	F f = this.new <@NonNull Integer>F(1,2);\n" +

+			"}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. ERROR in X.java (at line 6)\n" + 

+		"	F f = this.new <@NonNull Integer>F(1,2);\n" + 

+		"	                ^^^^^^^^^^^^^^^^\n" + 

+		"Null constraint mismatch: The type \'@NonNull Integer\' is not a valid substitute for the type parameter \'@Nullable U\'\n" + 

+		"----------\n");

+}

+public void testBug465513() {

+	runConformTestWithLibs(

+		new String[] {

+			"pack1/A.java",

+			"package pack1;\r\n" + 

+			"import java.math.BigInteger;\r\n" + 

+			"\r\n" + 

+			"interface A { Object m(Class c); }\r\n" + 

+			"interface B<S extends Number> { Object m(Class<S> c); }\r\n" + 

+			"interface C<T extends BigInteger> { Object m(Class<T> c); }\r\n" + 

+			"@FunctionalInterface\r\n" + 

+			"interface D<S,T> extends A, B<BigInteger>, C<BigInteger> {}\n"

+		},

+		getCompilerOptions(),

+		"----------\n" + 

+		"1. WARNING in pack1\\A.java (at line 4)\n" + 

+		"	interface A { Object m(Class c); }\n" + 

+		"	                       ^^^^^\n" + 

+		"Class is a raw type. References to generic type Class<T> should be parameterized\n" + 

+		"----------\n");

+}

 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index b622ff9..aaa5457 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -49,7 +49,7 @@
 	"}\n";
 
 static {
-//	TESTS_NAMES = new String[] { "testBug415790" };
+//	TESTS_NAMES = new String[] { "testBug462371_shouldWarn" };
 //	TESTS_NUMBERS = new int[] { 50 };
 //	TESTS_RANGE = new int[] { 11, -1 };
 }
@@ -4850,4 +4850,587 @@
 		},
 		options);
 }
+public void testBug371614_comment0() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runNegativeTest(
+		new String[] {
+			"C.java",
+			"import java.io.FileInputStream;\n" + 
+			"import java.io.IOException;\n" + 
+			"import java.io.InputStream;\n" + 
+			"\n" + 
+			"public class C {\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		FileInputStream fileInputStream= null;\n" + 
+			"		try {\n" + 
+			"			fileInputStream = new FileInputStream(args[0]);\n" + 
+			"			while (true) {\n" + 
+			"				if (fileInputStream.read() == -1) {\n" + 
+			"					System.out.println(\"done\");\n" + 
+			"// Resource leak: 'fileInputStream' is not closed at this location\n" + 
+			"					return;\n" + 
+			"				}\n" + 
+			"			}\n" + 
+			"		} catch (IOException e) {\n" + 
+			"			e.printStackTrace();\n" + 
+			"			return;\n" + 
+			"		} finally {\n" + 
+			"			closeStream(fileInputStream);\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"	\n" + 
+			"	private static void closeStream(InputStream stream) {\n" + 
+			"		if (stream != null) {\n" + 
+			"			try {\n" + 
+			"				stream.close();\n" + 
+			"			} catch (IOException e) {\n" + 
+			"				e.printStackTrace();\n" + 
+			"			}\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"}\n" + 
+			"\n"
+		},
+		"----------\n" + 
+		"1. ERROR in C.java (at line 14)\n" + 
+		"	return;\n" + 
+		"	^^^^^^^\n" + 
+		"Potential resource leak: \'fileInputStream\' may not be closed at this location\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
+public void testBug371614_comment2() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"ResourceLeak.java",
+			"import java.io.FileInputStream;\n" + 
+			"import java.io.IOException;\n" + 
+			"import java.io.InputStreamReader;\n" + 
+			"import java.io.Reader;\n" + 
+			"\n" + 
+			"public class ResourceLeak {\n" + 
+			"\n" + 
+			"  boolean check(final Reader r) throws IOException {\n" + 
+			"    final int i = r.read();\n" + 
+			"    return (i != -1);\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public void test1() throws IOException {\n" + 
+			"    try (Reader r = new InputStreamReader(System.in);) {\n" + 
+			"      while (check(r)) {\n" + 
+			"        if (check(r))\n" + 
+			"          throw new IOException(\"fail\");\n" + 
+			"        if (!check(r))\n" + 
+			"          throw new IOException(\"fail\");\n" + 
+			"      }\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public void test2() throws IOException {\n" + 
+			"    try (Reader r = new InputStreamReader(new FileInputStream(\"test.txt\"));) {\n" + 
+			"      while (check(r)) {\n" + 
+			"        if (check(r))\n" + 
+			"          throw new IOException(\"fail\");\n" + 
+			"        if (!check(r))\n" + 
+			"          throw new IOException(\"fail\");\n" + 
+			"      }\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug371614_comment8() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"import java.net.*;\n" +
+			"public class X {\n" +
+			"	Socket fSocket;\n" +
+			"	void test() {\n" +
+			"    try (InputStreamReader socketIn = new InputStreamReader(fSocket.getInputStream())) {\n" + 
+			"         while (true) {\n" + 
+			"             if (socketIn.read(new char[1024]) < 0)\n" + 
+			"                 throw new IOException(\"Error\");\n" + 
+			"         }           \n" + 
+			"     } catch (IOException e) {\n" + 
+			"     }" +
+			"	}\n" +
+			"}\n"
+		},
+		options);
+}
+public void testBug462371_orig() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"interface IFile {\n" +
+			"	InputStream getContents();\n" +
+			"	boolean exists();\n" +
+			"}\n" +
+			"public class X {\n" +
+			"	public static String getAnnotatedSignature(String typeName, IFile file, String selector, String originalSignature) {\n" + 
+			"		if (file.exists()) {\n" + 
+			"			try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()))) {\n" + 
+			"				reader.readLine();\n" + 
+			"				while (true) {\n" + 
+			"					String line = reader.readLine(); \n" + 
+			"					// selector:\n" + 
+			"					if (selector.equals(line)) {\n" + 
+			"						// original signature:\n" + 
+			"						line = reader.readLine();\n" + 
+			"						if (originalSignature.equals(\"\")) {\n" + 
+			"							// annotated signature:\n" + 
+			"							return reader.readLine();\n" + 
+			"						}\n" + 
+			"					}\n" + 
+			"					if (line == null)\n" + 
+			"						break;\n" + 
+			"				}\n" + 
+			"			} catch (IOException e) {\n" + 
+			"				return null;\n" + 
+			"			}\n" + 
+			"		}\n" + 
+			"		return null;\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		options);
+}
+public void _testBug462371_shouldWarn() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runNegativeTest(
+		new String[] {
+			"X.java",
+			"import java.io.*;\n" +
+			"interface IFile {\n" +
+			"	InputStream getContents();\n" +
+			"	boolean exists();\n" +
+			"}\n" +
+			"public class X {\n" +
+			"	public static String getAnnotatedSignature(String typeName, IFile file, String selector, String originalSignature) {\n" + 
+			"		if (file.exists()) {\n" + 
+			"			try  {\n" + 
+			"				BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents())); \n" + 
+			"				reader.readLine();\n" + 
+			"				while (true) {\n" + 
+			"					String line = reader.readLine(); \n" + 
+			"					// selector:\n" + 
+			"					if (selector.equals(line)) {\n" + 
+			"						// original signature:\n" + 
+			"						line = reader.readLine();\n" + 
+			"						if (originalSignature.equals(\"\")) {\n" + 
+			"							// annotated signature:\n" + 
+			"							return reader.readLine();\n" + 
+			"						}\n" + 
+			"					}\n" + 
+			"					if (line == null)\n" + 
+			"						break;\n" + 
+			"				}\n" + 
+			"			} catch (IOException e) {\n" + 
+			"				return null;\n" + 
+			"			}\n" + 
+			"		}\n" + 
+			"		return null;\n" + 
+			"	}\n" +
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in C.java (at line 14)\n" + 
+		"	return;\n" + 
+		"	^^^^^^^\n" + 
+		"Potential resource leak: \'fileInputStream\' may not be closed at this location\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
+public void testBug421035() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"Test.java",
+			"import java.io.BufferedReader;\n" + 
+			"import java.io.FileNotFoundException;\n" + 
+			"import java.io.FileReader;\n" + 
+			"import java.io.IOException;\n" + 
+			"import java.io.Reader;\n" + 
+			"\n" + 
+			"public class Test {\n" + 
+			"  void test() throws FileNotFoundException {\n" + 
+			"    Reader a = (Reader)new BufferedReader(new FileReader(\"a\"));\n" + 
+			"    try {\n" + 
+			"		a.close();\n" + 
+			"	} catch (IOException e) {\n" + 
+			"		e.printStackTrace();\n" + 
+			"	}\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug444964() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"Bug444964.java",
+			"import java.io.*;\n" + 
+			"\n" + 
+			"public class Bug444964 {\n" + 
+			"  void wrong() {\n" + 
+			"    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {\n" + 
+			"      for (;;) {\n" + 
+			"        return;\n" + 
+			"      }\n" + 
+			"    } catch (Exception e) {\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"  void right() {\n" + 
+			"    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {\n" + 
+			"      while (true) {\n" + 
+			"        return;\n" + 
+			"      }\n" + 
+			"    } catch (Exception e) {\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug397204() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"HostIdTest.java",
+			"import java.io.*;\n" + 
+			"import java.net.InetAddress;\n" + 
+			"import java.net.NetworkInterface;\n" + 
+			"import java.util.Enumeration;\n" + 
+			"import java.util.Formatter;\n" + 
+			"import java.util.Locale;\n" + 
+			"\n" + 
+			"\n" + 
+			"public class HostIdTest {\n" + 
+			"\n" + 
+			"    public final void primaryNetworkInterface() throws IOException {\n" + 
+			"        System.out.println(InetAddress.getLocalHost());\n" + 
+			"        System.out.println(InetAddress.getLocalHost().getHostName());\n" + 
+			"        System.out.println(hostId());\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    String hostId() throws IOException {\n" + 
+			"        try (StringWriter s = new StringWriter(); PrintWriter p = new PrintWriter(s)) {\n" + 
+			"            p.print(InetAddress.getLocalHost().getHostName());\n" + 
+			"            p.print('/');\n" + 
+			"            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();\n" + 
+			"            while (e.hasMoreElements()) {\n" + 
+			"                NetworkInterface i = e.nextElement();\n" + 
+			"                System.out.println(i);\n" + 
+			"                if (i.getHardwareAddress() == null || i.getHardwareAddress().length == 0)\n" + 
+			"                    continue;\n" + 
+			"                for (byte b : i.getHardwareAddress())\n" + 
+			"                    p.printf(\"%02x\", b);\n" + 
+			"                return s.toString();\n" + 
+			"            }\n" + 
+			"            throw new RuntimeException(\"Unable to determine Host ID\");\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    public void otherHostId() throws Exception {\n" + 
+			"        InetAddress addr = InetAddress.getLocalHost();\n" + 
+			"        byte[] ipaddr = addr.getAddress();\n" + 
+			"        if (ipaddr.length == 4) {\n" + 
+			"            int hostid = ipaddr[1] << 24 | ipaddr[0] << 16 | ipaddr[3] << 8 | ipaddr[2];\n" + 
+			"            StringBuilder sb = new StringBuilder();\n" + 
+			"            try (Formatter formatter = new Formatter(sb, Locale.US)) {\n" + 
+			"                formatter.format(\"%08x\", hostid);\n" + 
+			"                System.out.println(sb.toString());\n" + 
+			"            }\n" + 
+			"        } else {\n" + 
+			"            throw new Exception(\"hostid for IPv6 addresses not implemented yet\");\n" + 
+			"        }\n" + 
+			"    }\n" + 
+			"    \n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug397204_comment4() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"HostIdTest.java",
+			"import java.io.*;\n" + 
+			"\n" + 
+			"public class HostIdTest {\n" + 
+			"\n" + 
+			"  void simple() throws Exception {\n" + 
+			"    try (InputStream x = new ByteArrayInputStream(null)) {\n" + 
+			"      while (Math.abs(1) == 1)\n" + 
+			"        if (Math.abs(1) == 1)\n" + 
+			"            return;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug433510() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runConformTest(
+		new String[] {
+			"Bug433510.java",
+			"import java.io.*;\n" + 
+			"\n" + 
+			"public class Bug433510 {\n" + 
+			"\n" + 
+			"	void test() throws Exception {\n" + 
+			"		try (Reader r = new StringReader(\"Hello World!\")) {\n" + 
+			"			int c;\n" + 
+			"			while ((c = r.read()) != -1) {\n" + 
+			"				if (c == ' ')\n" + 
+			"					throw new IOException(\"Unexpected space\");\n" + 
+			"			}\n" + 
+			"		}\n" + 
+			"	}\n" + 
+			"}\n"
+		},
+		options);
+}
+public void testBug440282() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	runNegativeTest(
+		new String[] {
+			"ResourceLeakFalseNegative.java",
+			"import java.io.FileInputStream;\n" + 
+			"import java.io.IOException;\n" + 
+			"import java.io.InputStreamReader;\n" + 
+			"\n" + 
+			"public final class ResourceLeakFalseNegative {\n" + 
+			"\n" + 
+			"  private static final class Foo implements AutoCloseable {\n" + 
+			"    final InputStreamReader reader;\n" + 
+			"\n" + 
+			"    Foo(final InputStreamReader reader) {\n" + 
+			"      this.reader = reader;\n" + 
+			"    }\n" + 
+			"    \n" + 
+			"    public int read() throws IOException {\n" + 
+			"      return reader.read();\n" + 
+			"    }\n" + 
+			"\n" + 
+			"    public void close() throws IOException {\n" + 
+			"      reader.close();\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  private static final class Bar {\n" + 
+			"    final int read;\n" + 
+			"\n" + 
+			"    Bar(final InputStreamReader reader) throws IOException {\n" + 
+			"      read = reader.read();\n" + 
+			"    }\n" + 
+			"    \n" + 
+			"    public int read() {\n" + 
+			"      return read;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public final static int foo() throws IOException {\n" + 
+			"    final FileInputStream in = new FileInputStream(\"/dev/null\");\n" + 
+			"    final InputStreamReader reader = new InputStreamReader(in);\n" + 
+			"    try {\n" + 
+			"      return new Foo(reader).read();\n" + 
+			"    } finally {\n" + 
+			"      // even though Foo is not closed, no potential resource leak is reported.\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public final static int bar() throws IOException {\n" + 
+			"    final FileInputStream in = new FileInputStream(\"/dev/null\");\n" + 
+			"    final InputStreamReader reader = new InputStreamReader(in);\n" + 
+			"    try {\n" + 
+			"      final Bar bar = new Bar(reader);\n" + 
+			"      return bar.read();\n" + 
+			"    } finally {\n" + 
+			"      // Removing the close correctly reports potential resource leak as a warning,\n" + 
+			"      // because Bar does not implement AutoCloseable.\n" + 
+			"      reader.close();\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"\n" + 
+			"  public static void main(String[] args) throws IOException {\n" + 
+			"    for (;;) {\n" + 
+			"      foo();\n" + 
+			"      bar();\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in ResourceLeakFalseNegative.java (at line 39)\n" + 
+		"	return new Foo(reader).read();\n" + 
+		"	       ^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
+public void testBug390064() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // generics used
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+	runNegativeTest(
+		new String[] {
+			"Redundant.java",
+			"public class Redundant\n" + 
+			"{\n" + 
+			"   private static class A<T> implements AutoCloseable\n" + 
+			"   {\n" + 
+			"      public void close()\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"\n" + 
+			"   private static class B extends A<Object>\n" + 
+			"   {\n" + 
+			"      \n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static class C implements AutoCloseable\n" + 
+			"   {\n" + 
+			"      public void close()\n" + 
+			"      {\n" + 
+			"      }\n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   private static class D extends C\n" + 
+			"   {\n" + 
+			"      \n" + 
+			"   }\n" + 
+			"   \n" + 
+			"   public static void main(String[] args)\n" + 
+			"   {\n" + 
+			"      new B();\n" + 
+			"      \n" + 
+			"      new D();\n" + 
+			"   }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Redundant.java (at line 29)\n" + 
+		"	new B();\n" + 
+		"	^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n" + 
+		"2. ERROR in Redundant.java (at line 31)\n" + 
+		"	new D();\n" + 
+		"	^^^^^^^\n" + 
+		"Resource leak: \'<unassigned Closeable value>\' is never closed\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
+public void testBug396575() {
+	Map options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+	runNegativeTest(
+		new String[] {
+			"Bug396575.java",
+			"import java.io.*;\n" + 
+			"\n" + 
+			"public class Bug396575 {\n" + 
+			"  void test1(File myFile) {\n" + 
+			"   OutputStream out = null;\n" + 
+			"   BufferedWriter bw = null;\n" + 
+			"   try {\n" + 
+			"       // code...\n" + 
+			"       out = new FileOutputStream(myFile);\n" + 
+			"       OutputStreamWriter writer = new OutputStreamWriter(out);\n" + 
+			"       bw = new BufferedWriter(writer);\n" + 
+			"       // more code...\n" + 
+			"   } catch (Exception e) {\n" + 
+			"       try {\n" + 
+			"           bw.close(); // WARN: potential null pointer access\n" + 
+			"       } catch (Exception ignored) {}\n" + 
+			"       return;  // WARN: resource leak - bw may not be closed\n" + 
+			"   }\n" + 
+			"  }\n" + 
+			"  \n" + 
+			"  void test2(File myFile) {\n" + 
+			"       BufferedWriter bw = null;\n" + 
+			"   try {\n" + 
+			"       // code...\n" + 
+			"                                                       // declare \"out\" here inside try-catch as a temp variable\n" + 
+			"       OutputStream out = new FileOutputStream(myFile); // WARN: out is never closed.\n" + 
+			"       OutputStreamWriter writer = new OutputStreamWriter(out);\n" + 
+			"       bw = new BufferedWriter(writer);\n" + 
+			"       // more code...\n" + 
+			"   } catch (Exception e) {\n" + 
+			"       try {\n" + 
+			"           bw.close(); // WARN: potential null pointer access\n" + 
+			"       } catch (Exception ignored) {}\n" + 
+			"       return;  // WARN: resource leak - bw may not be closed\n" + 
+			"   }\n" + 
+			"  }\n" + 
+			"}\n"
+		},
+		"----------\n" + 
+		"1. ERROR in Bug396575.java (at line 11)\n" + 
+		"	bw = new BufferedWriter(writer);\n" + 
+		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'bw\' is never closed\n" + 
+		"----------\n" + 
+		"2. ERROR in Bug396575.java (at line 28)\n" + 
+		"	bw = new BufferedWriter(writer);\n" + 
+		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'bw\' is never closed\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
index 9c65b46..259c8ab 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2014 IBM Corporation and others.
+ * Copyright (c) 2010, 2015 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
@@ -21,6 +21,7 @@
 import java.util.Map;
 
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTParser;
@@ -349,6 +350,185 @@
 			fileY.delete();
 		}
 	}
+	
+	/**
+	 * @deprecated
+	 * @throws IOException
+	 */
+	public void testBug415066_001() throws IOException {
+		File rootDir = new File(System.getProperty("java.io.tmpdir"));
+		ASTParser parser = ASTParser.newParser(AST.JLS4);
+		parser.setEnvironment(null, null, null, true);
+		parser.setResolveBindings(true);
+		parser.setStatementsRecovery(true);
+		parser.setBindingsRecovery(true);
+		parser.setCompilerOptions(getCompilerOptions());
+
+		final String key = "Lp/C;";
+		final IBinding[] bindings = new IBinding[2];
+
+		String contents = 
+			"package p;\n" + 
+			"public class A{}\n" + 
+			"class B{}";
+		
+		File packageDir = new File(rootDir, "p");
+		packageDir.mkdir();
+		File file = new File(packageDir, "A.java");
+		Writer writer = null;
+		try {
+			writer = new BufferedWriter(new FileWriter(file));
+			writer.write(contents);
+		} finally {
+			if (writer != null) {
+				try {
+					writer.close();
+				} catch(IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		String contents2 =
+			"package p;\n" + 
+			"public class C extends B {}";
+		File fileY = new File(packageDir, "C.java");
+		Writer writer2 = null;
+		try {
+			writer2 = new BufferedWriter(new FileWriter(fileY));
+			writer2.write(contents2);
+		} finally {
+			if (writer2 != null) {
+				try {
+					writer2.close();
+				} catch(IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		try {
+			final String canonicalPath = fileY.getCanonicalPath();
+			final CompilationUnit[] units = new CompilationUnit[1];
+	
+			FileASTRequestor requestor = new FileASTRequestor() {
+				public void acceptBinding(String bindingKey, IBinding binding) {
+					if (key.equals(bindingKey)) {
+						bindings[0] = binding;
+						IBinding[] temp = createBindings(new String[] {"Lp/C;"});
+						for (int i = 0; i < temp.length; ++i) {
+							bindings[i + 1] = temp[i];
+						}
+					}
+				}
+				public void acceptAST(String sourceFilePath, CompilationUnit ast) {
+					if (canonicalPath.equals(sourceFilePath)) {
+						units[0] = ast;
+					}
+				}
+			};
+	
+			parser.setEnvironment(null, new String[] { rootDir.getCanonicalPath() }, null, true);
+			org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.MAX_AT_ONCE = 0;
+			parser.createASTs(new String[] {canonicalPath}, null, new String[] {key}, requestor, null);
+			assertNotNull("No ast", units[0]);
+			assertEquals("No problem", 0, units[0].getProblems().length);
+		} finally {
+			file.delete();
+			fileY.delete();
+		}
+	}
+
+	/**
+	 * Negative test case
+	 * @deprecated
+	 * @throws IOException
+	 */
+	public void testBug415066_002() throws IOException {
+		File rootDir = new File(System.getProperty("java.io.tmpdir"));
+		ASTParser parser = ASTParser.newParser(AST.JLS4);
+		parser.setEnvironment(null, null, null, true);
+		parser.setResolveBindings(true);
+		parser.setStatementsRecovery(true);
+		parser.setBindingsRecovery(true);
+		parser.setCompilerOptions(getCompilerOptions());
+
+		final String key = "Lp/C;";
+		final IBinding[] bindings = new IBinding[2];
+
+		String contents = 
+			"package p;\n" + 
+			"public class A{}\n" + 
+			"class B{}";
+		
+		File packageDir = new File(rootDir, "p");
+		packageDir.mkdir();
+		File file = new File(packageDir, "A.java");
+		Writer writer = null;
+		try {
+			writer = new BufferedWriter(new FileWriter(file));
+			writer.write(contents);
+		} finally {
+			if (writer != null) {
+				try {
+					writer.close();
+				} catch(IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		String contents2 =
+			"package q;\n" +
+			"import p.*;\n" +
+			"public class C extends B {}";
+		File fileY = new File(packageDir, "C.java");
+		Writer writer2 = null;
+		try {
+			writer2 = new BufferedWriter(new FileWriter(fileY));
+			writer2.write(contents2);
+		} finally {
+			if (writer2 != null) {
+				try {
+					writer2.close();
+				} catch(IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		try {
+			final String canonicalPath = fileY.getCanonicalPath();
+			final CompilationUnit[] units = new CompilationUnit[1];
+	
+			FileASTRequestor requestor = new FileASTRequestor() {
+				public void acceptBinding(String bindingKey, IBinding binding) {
+					if (key.equals(bindingKey)) {
+						bindings[0] = binding;
+						IBinding[] temp = createBindings(new String[] {"Lq/C;"});
+						for (int i = 0; i < temp.length; ++i) {
+							bindings[i + 1] = temp[i];
+						}
+					}
+				}
+				public void acceptAST(String sourceFilePath, CompilationUnit ast) {
+					if (canonicalPath.equals(sourceFilePath)) {
+						units[0] = ast;
+					}
+				}
+			};
+	
+			parser.setEnvironment(null, new String[] { rootDir.getCanonicalPath() }, null, true);
+			parser.createASTs(new String[] {canonicalPath}, null, new String[] {key}, requestor, null);
+			assertNotNull("No ast", units[0]);
+			IProblem[] problems = units[0].getProblems();
+			assertEquals("No problem", 1, problems.length);
+			assertEquals("Pb(3) The type B is not visible", problems[0].toString());
+		} finally {
+			file.delete();
+			fileY.delete();
+		}
+	}
 
 	public void test7() throws IOException {
 		File rootDir = new File(System.getProperty("java.io.tmpdir"));
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index 6d16f79..100e1d5 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.9.4.qualifier
+Bundle-Version: 3.10.0.qualifier
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jdt.core.tests,
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index 7f16f09..7d592ab 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.core.tests.model</artifactId>
-  <version>3.9.4-SNAPSHOT</version>
+  <version>3.10.0-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index 9d4bd69..07e1a7a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -27,6 +27,7 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.core.ResolvedBinaryMethod;
 
 @SuppressWarnings({"rawtypes"})
@@ -1579,7 +1580,8 @@
 		assertEquals("vlambda -> {\n  return 200;\n}\n", lambdaExpression.toString());
 		assertTrue(lambdaExpression.parameters().size() == 1);
 		IMethodBinding binding = lambdaExpression.resolveMethodBinding();
-		assertEquals("private static int lambda$0(int) ", binding.toString());
+		assertEquals("public int foo(int) ", binding.toString());
+		assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers());
 		VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0);
 		assertTrue(variableDeclaration instanceof VariableDeclarationFragment);
 		fragment = (VariableDeclarationFragment)variableDeclaration;
@@ -1614,7 +1616,8 @@
 		LambdaExpression lambdaExpression = (LambdaExpression)expression;
 		assertEquals("vlambda -> 200", lambdaExpression.toString());
 		IMethodBinding binding = lambdaExpression.resolveMethodBinding();
-		assertEquals("private static int lambda$0(int) ", binding.toString());
+		assertEquals("public int foo(int) ", binding.toString());
+		assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers());
 		assertTrue(lambdaExpression.parameters().size() == 1);
 		VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0);
 		assertTrue(variableDeclaration instanceof VariableDeclarationFragment);
@@ -1648,7 +1651,8 @@
 		LambdaExpression lambdaExpression = (LambdaExpression)expression;
 		assertEquals("(int[] ia) -> {\n  return ia.clone();\n}\n", lambdaExpression.toString());
 		IMethodBinding binding = lambdaExpression.resolveMethodBinding();
-		assertEquals("private static java.lang.Object lambda$0(int[]) ", binding.toString());
+		assertEquals("public java.lang.Object foo(int[]) ", binding.toString());
+		assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers());
 		assertTrue(lambdaExpression.parameters().size() == 1);
 		VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0);
 		assertTrue(variableDeclaration instanceof SingleVariableDeclaration);
@@ -1690,7 +1694,8 @@
 		LambdaExpression lambdaExpression = (LambdaExpression)expression;
 		assertEquals("() -> {\n  System.out.println(this);\n  I j=() -> {\n    System.out.println(this);\n    I k=() -> {\n      System.out.println(this);\n    }\n;\n  }\n;\n}\n", lambdaExpression.toString());
 		IMethodBinding binding = lambdaExpression.resolveMethodBinding();
-		assertEquals("private void lambda$0() ", binding.toString());
+		assertEquals("public void doit() ", binding.toString());
+		assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers());
 		assertTrue(lambdaExpression.parameters().size() == 0);
 	}
 
@@ -1943,7 +1948,8 @@
 		LambdaExpression lambdaExpression = (LambdaExpression)expression;
 		assertEquals("() -> () -> 10", lambdaExpression.toString());
 		IMethodBinding binding = lambdaExpression.resolveMethodBinding();
-		assertEquals("private static test399793.J lambda$0() ", binding.toString());
+		assertEquals("public test399793.J foo() ", binding.toString());
+		assertEquals("real modifiers", ClassFileConstants.AccPublic, binding.getModifiers());
 		assertTrue(lambdaExpression.parameters().size() == 0);
 	}	
 	
@@ -4938,7 +4944,7 @@
  * 
  * @throws JavaModelException
  */
-public void _testBug425601_001() throws JavaModelException {
+public void testBug425601_001() throws JavaModelException {
 	this.workingCopy = getWorkingCopy("/Converter18/src/testBug425601_001/Outer.java",
 			true/* resolve */);
 	String contents = "package testBug425601_001;\n" +
@@ -4983,7 +4989,7 @@
  * 
  * @throws JavaModelException
  */
-public void _testBug425601_002() throws JavaModelException {
+public void testBug425601_002() throws JavaModelException {
 	this.workingCopy = getWorkingCopy("/Converter18/src/testBug425601_002/Outer.java",
 			true/* resolve */);
 	String contents = "package testBug425601_002;\n" +
@@ -5137,4 +5143,53 @@
 		assertTrue("Test Failed", false);
 	}
 }
+/**
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=429813
+ * 
+ * @throws JavaModelException
+ */
+public void test429813() throws JavaModelException {
+	this.workingCopy = getWorkingCopy("/Converter18/src/test429813/Snippet.java",
+			true/* resolve */);
+	String contents = "package test429813;"
+			+ "public class Snippet {\n"
+			+ "		Function<Integer, int[]> m1L = n -> new int[n];\n"
+			+ "}"
+			+ "interface Function<T, R> {\n"
+			+ "   public R apply(T t);\n"
+			+ "}\n";
+	CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+	TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 0);
+	FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0);
+	VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0);
+	Expression expression = fragment.getInitializer();
+	assertTrue(expression instanceof LambdaExpression);
+	LambdaExpression lambdaExpression = (LambdaExpression)expression;
+	IMethodBinding binding = lambdaExpression.resolveMethodBinding();
+	IJavaElement element = binding.getJavaElement();
+	assertEquals("Not a method", IJavaElement.METHOD, element.getElementType());
+	assertFalse("Should not be a synthetic", binding.isSynthetic());
+}
+
+public void test429813a() throws JavaModelException {
+	this.workingCopy = getWorkingCopy("/Converter18/src/test429813/Snippet.java",
+			true/* resolve */);
+	String contents = "package test429813;"
+			+ "interface FTest {\n"
+			+ "		Object foo (int[]... ints);\n"
+			+ "};"
+			+ "class TestX {"
+			+ "		FTest fi= ints -> null;\n"
+			+ "}\n";
+	CompilationUnit cu = (CompilationUnit) buildAST(contents, this.workingCopy);
+	TypeDeclaration typedeclaration = (TypeDeclaration) getASTNode(cu, 1);
+	FieldDeclaration fieldDeclaration = (FieldDeclaration) typedeclaration.bodyDeclarations().get(0);
+	VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclaration.fragments().get(0);
+	Expression expression = fragment.getInitializer();
+	assertTrue(expression instanceof LambdaExpression);
+	LambdaExpression lambdaExpression = (LambdaExpression)expression;
+	IMethodBinding binding = lambdaExpression.resolveMethodBinding();
+	assertTrue("Should be a varargs", binding.isVarargs());
+}
+
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
index 0fd7a86..512b9fa 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * Copyright (c) 2004, 2015 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,10 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								Bug 463330 - [dom] DOMFinder doesn't find the VariableBinding corresponding to a method argument
+ *								Bug 464463 - [dom] DOMFinder doesn't find an ITypeParameter
+ *								Bug 464615 - [dom] ASTParser.createBindings() ignores parameterization of a method invocation
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.dom;
 
@@ -1062,6 +1066,36 @@
 
 	/*
 	 * Ensures that the correct IBindings are created for a given set of IJavaElement
+	 * (type parameter with bound)
+	 */
+	public void testCreateBindings14a() throws JavaModelException {
+		IBinding[] bindings = createBindings(
+			"public class X<T extends java.lang.Number> {\n" +
+			"}",
+			this.workingCopy.getType("X").getTypeParameter("T")
+		);
+		assertBindingsEqual(
+			"LX;:TT;",
+			bindings);
+	}
+
+	/*
+	 * Ensures that the correct IBindings are created for a given set of IJavaElement
+	 * (type parameter with parameterized bound)
+	 */
+	public void testCreateBindings14b() throws JavaModelException {
+		IBinding[] bindings = createBindings(
+			"public class X<T extends java.util.List<String>> {\n" +
+			"}",
+			this.workingCopy.getType("X").getTypeParameter("T")
+		);
+		assertBindingsEqual(
+			"LX;:TT;",
+			bindings);
+	}
+
+	/*
+	 * Ensures that the correct IBindings are created for a given set of IJavaElement
 	 * (binary type)
 	 */
 	public void testCreateBindings15() throws CoreException {
@@ -1222,6 +1256,83 @@
 	}
 
 	/*
+	 * Ensures that the correct IBindings are created for a given set of IJavaElement
+	 * (method arguments)
+	 */
+	public void testCreateBindings25() throws JavaModelException {
+		this.workingCopy.getBuffer().setContents(
+				"public class X {\n" +
+				"  void foo(String str, int i) {}\n" +
+				"}");
+		this.workingCopy.makeConsistent(null);
+		IMethod method = this.workingCopy.getType("X").getMethod("foo", new String[]{"QString;", "I"});
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setProject(getJavaProject("P"));
+		IBinding[] bindings = parser.createBindings(method.getParameters(), null);
+		assertBindingsEqual(
+			"LX;.foo(Ljava/lang/String;I)V#str\n" +
+			"LX;.foo(Ljava/lang/String;I)V#i",
+			bindings);
+	}
+
+	/*
+	 * Ensures that the correct IBindings are created for a given set of IJavaElement
+	 * (binary method arguments)
+	 */
+	public void testCreateBindings26() throws CoreException {
+		createClassFile("/P/lib", "A.class",
+				"public class A {\n" +
+				"  void foo(String str, int i) {}\n" +
+				"}");
+		IMethod method = getClassFile("/P/lib/A.class").getType().getMethod("foo", new String[] {"Ljava.lang.String;", "I"});
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setProject(getJavaProject("P"));
+		IBinding[] bindings = parser.createBindings(method.getParameters(), null);
+		assertBindingsEqual(
+			"LA;.foo(Ljava/lang/String;I)V#str\n" +
+			"LA;.foo(Ljava/lang/String;I)V#i",
+			bindings);
+	}
+
+	/*
+	 * Ensures that the correct IBindings are created for a given set of IJavaElement
+	 * (invocation of a generic method - binary)
+	 */
+	public void testCreateBinding27() throws Exception {
+		createClassFile("/P/lib", "p/A.class",
+				"package p;\n" +
+				"public class A {\n" +
+				"  public static <T> T foo(T[] arg) { return arg[0]; }\n" +
+				"}");
+		this.workingCopies = new ICompilationUnit[1];
+		String xSource = "public class X {\n" +
+						"  public String test(String[] args) {\n" +
+						"    return p.A.foo(args);\n" +
+						"  }\n" +
+						"}";
+		this.workingCopies[0] = getWorkingCopy(
+			"/P/src/X.java",
+			xSource,
+			this.wcOwner
+		);
+
+		IJavaElement elem= this.workingCopies[0].codeSelect(xSource.indexOf("foo"), 0)[0];
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setProject(getJavaProject("P"));
+		IBinding[] bindings = parser.createBindings(new IJavaElement[]{ elem }, null);
+		assertBindingsEqual(
+			"Lp/A;.foo<T:Ljava/lang/Object;>([TT;)TT;%<Ljava/lang/String;>",
+			bindings);
+		IMethodBinding method = (IMethodBinding) bindings[0];
+		assertBindingsEqual(
+			"[Ljava/lang/String;",
+			method.getParameterTypes());
+			assertBindingsEqual(
+				"Ljava/lang/String;",
+				new IBinding[] {method.getReturnType()});
+	}
+
+	/*
 	 * Ensures that the IJavaElement of an IBinding representing a field is correct.
 	 */
 	public void testField1() throws JavaModelException {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugs18Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugs18Tests.java
index b9559ec..f9dcb0a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugs18Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugs18Tests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 IBM Corporation and others.
+ * Copyright (c) 2014, 2015 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
@@ -145,5 +145,96 @@
 			"}\n"
 			);
 }
+public void testBug433177() throws Exception {
+	String source =
+			"interface Function<T, R> {\n" +
+		"	R apply(T t);\n" +
+		"}\n" +
+		"\n" +
+		"public class X {\n" +
+		"\n" +
+		"	  public Function<String, String> testOK() {\n" +
+		"	    return foo((s) -> {\n" +
+		"	      // nothing\n" +
+		"	      System.out.println(\"\");\n" +
+		"	      return \"\";\n" +
+		"	    });\n" +
+		"	  }\n" +
+		"\n" +
+		"	  public Function<String, String> testBad() {\n" +
+		"	    return this.foo((s) -> {\n" +
+		"	      // nothing\n" +
+		"	        System.out.println(\"\");\n" +
+		"	        return \"\";\n" +
+		"	      });\n" +
+		"	  }\n" +
+		"\n" +
+		"	  public Function<String, String> foo(Function<String, String> f) {\n" +
+		"	    return null;\n" +
+		"	  }\n" +
+		"\n" +
+		"	}\n";
+	String expected = "interface Function<T, R> {\n" +
+			"	R apply(T t);\n" +
+			"}\n" +
+			"\n" +
+			"public class X {\n" +
+			"\n" +
+			"	public Function<String, String> testOK() {\n" +
+			"		return foo((s) -> {\n" +
+			"			// nothing\n" +
+			"			System.out.println(\"\");\n" +
+			"			return \"\";\n" +
+			"		} );\n" +
+			"	}\n" +
+			"\n" +
+			"	public Function<String, String> testBad() {\n" +
+			"		return this.foo((s) -> {\n" +
+			"			// nothing\n" +
+			"			System.out.println(\"\");\n" +
+			"			return \"\";\n" +
+			"		} );\n" +
+			"	}\n" +
+			"\n" +
+			"	public Function<String, String> foo(Function<String, String> f) {\n" +
+			"		return null;\n" +
+			"	}\n" +
+			"\n" +
+			"}\n";
+
+	formatSource(source,expected);
+}
+public void testBug434821() throws Exception {
+	String source ="public class FormatterTest {\n"+
+			"	public void doNothing() {\n"+
+			"		new Thread(() -> {\n"+
+			"			synchronized (this) {\n"+
+			"				try {\n"+
+			"					Thread.sleep(0); // blah\n"+
+			"			} catch (final InterruptedException e2) {\n"+
+			"				e2.printStackTrace();\n"+
+			"			}\n"+
+			"		}\n"+
+			"\n"+
+			"	}	).start();\n"+
+			"	}\n"+
+			"}\n";
+	String expected = "public class FormatterTest {\n"+
+			"	public void doNothing() {\n"+
+			"		new Thread(() -> {\n"+
+			"			synchronized (this) {\n"+
+			"				try {\n"+
+			"					Thread.sleep(0); // blah\n"+
+			"				} catch (final InterruptedException e2) {\n"+
+			"					e2.printStackTrace();\n"+
+			"				}\n"+
+			"			}\n"+
+			"\n"+
+			"		} ).start();\n"+
+			"	}\n"+
+			"}\n";
+
+	formatSource(source,expected);
+}
 
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index c32d48a..8d214ac 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -10,6 +10,7 @@
  *     Ray V. (voidstar@gmail.com) - Contribution for bug 282988
  *     Robin Stocker - Bug 49619 - [formatting] comment formatter leaves whitespace in comments
  *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
+ *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] IndexOutOfBoundsException in TokenManager - https://bugs.eclipse.org/462945
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.formatter;
 
@@ -10640,4 +10641,84 @@
 	
 	// K_COMPILATION_UNIT is tested by FormatterRegressionTests#test512() and #test643()
 }
+/**
+ * @bug 462945 - [formatter] IndexOutOfBoundsException in TokenManager
+ * @test no exception is thrown for malformed code
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=462945"
+ */
+public void testBug462945() throws Exception {
+	String source =
+		"package p1;\n" + 
+		"enum ReviewResult {\n" + 
+		"	Good{, Bad\n" + 
+		"}\n";
+	formatSource(source,
+		"package p1;\n" + 
+		"\n" + 
+		"enum ReviewResult {\n" + 
+		"	Good{, Bad\n" + 
+		"}\n"
+	);
+}
+public void testBug407629() throws Exception {
+	String source =
+			"public class X {\n" +
+		"	/**\n" +
+		"	 * Builds a {@link Level}.\n" +
+		"	 * <p>\n" +
+		"	 * Does <b>not</b> set :\n" +
+		"	 * <ul>\n" +
+		"	 * <li>{@link Level#setA(Boolean)</li>\n" +
+		"	 * <li>{@link Level#setB(Long)}</li>\n" +
+		"	 * <li>{@link Level#setC(Integer)}</li>\n" +
+		"	 * </ul>\n" +
+		"	 * </p>\n" +
+		"	 */\n" +
+		"	public static Level buildLevel() {\n" +
+		"		return null;\n" +
+		"	}\n" +
+		"	 \n" +
+		"}\n" +
+		"\n" +
+		"class Level {\n" +
+		"	void setA(Boolean b) {}\n" +
+		"	void setB(Long l) {}\n" +
+		"	void setC(Integer i){}\n" +
+		"}\n";
+	String expected = "public class X {\n" +
+			"	/**\n" +
+			"	 * Builds a {@link Level}.\n" +
+			"	 * <p>\n" +
+			"	 * Does <b>not</b> set :\n" +
+			"	 * <ul>\n" +
+			"	 * <li>{@link Level#setA(Boolean)</li>\n" +
+			"	 * <li>{@link Level#setB(Long)}</li>\n" +
+			"	 * <li>{@link Level#setC(Integer)}</li>\n" +
+			"	 * </ul>\n" +
+			"	 * </p>\n" +
+			"	 */\n" +
+			"	public static Level buildLevel() {\n" +
+			"		return null;\n" +
+			"	}\n" +
+			"\n" +
+			"}\n" +
+			"\n" +
+			"class Level {\n" +
+			"	void setA(Boolean b) {\n" +
+			"	}\n" +
+			"\n" +
+			"	void setB(Long l) {\n" +
+			"	}\n" +
+			"\n" +
+			"	void setC(Integer i) {\n" +
+			"	}\n" +
+			"}\n";
+	formatSource(source, expected);
+}
+
+public void testBug464312() throws Exception {
+	String source = "/**/int f;";
+	formatSource(source, source, CodeFormatter.K_STATEMENTS);
+}
+
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index eaffd2b..adbde74 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -66,6 +66,7 @@
 	static {
 //		TESTS_NUMBERS = new int[] { 783 };
 //		TESTS_RANGE = new int[] { 734, -1 };
+//		TESTS_NAMES = new String[] {"testBug432593"};
 	}
 	public static Test suite() {
 		return buildModelTestSuite(FormatterRegressionTests.class);
@@ -13053,4 +13054,25 @@
 		"}\n"
 	);
 }
+
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=432593
+public void testBug432593() throws IOException {
+	ICompilationUnit sourceUnit;
+	try {
+		sourceUnit = getCompilationUnit("Formatter" , "", "test432593", getIn("A.java"));
+		String src = sourceUnit.getSource();
+		assertNotNull(src);
+		String source = src.toString();
+		final Map options = JavaCore.getOptions();
+		options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
+		options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
+		options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
+		final CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);
+		final TextEdit edit = codeFormatter.format(CodeFormatter.K_COMPILATION_UNIT, source, 0, source.length(), 0, "\r\n");
+		assertTrue(edit != null);
+	} catch (JavaModelException e) {
+		e.printStackTrace();
+	} 
+}
+
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 3806875..a04e279 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -1013,6 +1013,22 @@
 			assertTrue("Element should not be present after deletion: " + elementToDelete, !elementToDelete.exists());
 		}
 	}
+	protected void assertDeltas(String message, String expected, DeltaListener listener) {
+		assertDeltas(message, expected, expected.length() > 0/*wait for resource delta iff a delta is expected*/, listener);
+	}
+	protected void assertDeltas(String message, String expected, boolean waitForResourceDelta, DeltaListener listener) {
+		if (waitForResourceDelta)
+			listener.waitForResourceDelta();
+		String actual = listener.toString();
+		if (!expected.equals(actual)) {
+			System.out.println(displayString(actual, 2));
+			System.err.println(listener.stackTraces());
+		}
+		assertEquals(
+			message,
+			expected,
+			actual);
+	}
 	protected void assertDeltas(String message, String expected) {
 		assertDeltas(message, expected, expected.length() > 0/*wait for resource delta iff a delta is expected*/);
 	}
@@ -1131,6 +1147,9 @@
 	/**
 	 * Empties the current deltas.
 	 */
+	public void clearDeltas(DeltaListener listener) {
+		listener.flush();
+	}
 	public void clearDeltas() {
 		this.deltaListener.flush();
 	}
@@ -2993,6 +3012,22 @@
 	/**
 	 * Starts listening to element deltas, and queues them in fgDeltas.
 	 */
+	public void startDeltas(DeltaListener listener) {
+		clearDeltas(listener);
+		JavaCore.addElementChangedListener(listener);
+		getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
+	}
+	/**
+	 * Stops listening to element deltas, and clears the current deltas.
+	 */
+	public void stopDeltas(DeltaListener listener) {
+		getWorkspace().removeResourceChangeListener(listener);
+		JavaCore.removeElementChangedListener(listener);
+		clearDeltas(listener);
+	}
+	/**
+	 * Starts listening to element deltas, and queues them in fgDeltas.
+	 */
 	public void startDeltas() {
 		clearDeltas();
 		JavaCore.addElementChangedListener(this.deltaListener);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
index 5b178dc..970c74f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
@@ -7213,7 +7213,7 @@
 		map = proj1.getOptions(false);
 		map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1);
 		proj1.setOptions(map);
-
+		waitForManualRefresh();
 		assertMarkers("Unexpected markers",
 				"Incompatible .class files version in required binaries. Project \'P1\' is targeting a 1.1 runtime, but is compiled against \'P1/abc.jar\' which requires a 1.4 runtime", proj1);
 		 eclipsePreferences.removePreferenceChangeListener(prefListener);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
index ac5f4d8..9d47a59 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests18.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014 IBM Corporation and others.
+ * Copyright (c) 2014, 2015 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
@@ -931,7 +931,10 @@
 	String completeBehind = "try";
 	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
 	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
-	assertResults("tryit[LOCAL_VARIABLE_REF]{tryit, null, I, null, null, tryit, null, [99, 102], 27}", requestor.getResults());
+	assertResults(
+			"tryit[LOCAL_VARIABLE_REF]{tryit, null, I, null, null, tryit, null, [99, 102], 27}\n" +
+			"try[KEYWORD]{try, null, null, null, null, try, null, [99, 102], 28}", 
+			requestor.getResults());
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=422901, [1.8][code assist] Code assistant sensitive to scope.referenceContext type identity.
 public void test422901() throws JavaModelException {
@@ -2334,4 +2337,109 @@
 				  "localmethod2[METHOD_REF]{localmethod2(), LLambdaBug;, ()V, null, null, localmethod2, null, [282, 291], 17}", requestor.getResults());
 	
 }
+public void testBug459189_001() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/X.java",
+			"public class X {\n"+
+			"	Integer foo(){\n"+
+			"		I <Integer, X> i2 = (x) -> {ret /* type ctrl-space after ret */};\n"+
+			"		return 0;\n"+
+			"	}\n"+
+			"	Integer bar(Integer x) { return null;}\n"+
+			"}\n"+
+			"interface I <T,R> {\n"+
+			"	R apply(T t);\n"+
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "ret";
+	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertResults(
+			"Retention[TYPE_REF]{java.lang.annotation.Retention, java.lang.annotation, Ljava.lang.annotation.Retention;, null, null, 14}\n"+
+			"RetentionPolicy[TYPE_REF]{java.lang.annotation.RetentionPolicy, java.lang.annotation, Ljava.lang.annotation.RetentionPolicy;, null, null, 14}\n"+
+			"return[KEYWORD]{return, null, null, return, null, 24}",
+			requestor.getResults());
+}
+public void testBug459189_002() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/X.java",
+			"	Integer bar(Integer x) { return null;}\n"+
+			"public class X {\n"+
+			"	Integer foo(){\n"+
+			"		I <Integer, X> i2 = (x) -> {/* HERE */ret /* type ctrl-space after ret */};\n"+
+			"		return 0;\n"+
+			"	}\n"+
+			"}\n"+
+			"interface I <T,R> {\n"+
+			"	R apply(T t);\n"+
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "/* HERE */ret";
+	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertResults(
+			"Retention[TYPE_REF]{java.lang.annotation.Retention, java.lang.annotation, Ljava.lang.annotation.Retention;, null, null, 14}\n"+
+			"RetentionPolicy[TYPE_REF]{java.lang.annotation.RetentionPolicy, java.lang.annotation, Ljava.lang.annotation.RetentionPolicy;, null, null, 14}\n" +
+			"return[KEYWORD]{return, null, null, return, null, 24}",
+			requestor.getResults());
+}
+public void testBug459189_003() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/X.java",
+			"public class X {\n"+
+			"	Integer foo(){\n"+
+			"		I <Integer, X> i2 = (x) -> {try{} /* HERE */\n"+
+			"		return 0;\n"+
+			"	}\n"+
+			"	Integer bar(Integer x) { return null;}\n"+
+			"}\n"+
+			"interface I <T,R> {\n"+
+			"	R apply(T t);\n"+
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "/* HERE */";
+	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertResults(
+			"catch[KEYWORD]{catch, null, null, catch, null, 24}\n"+
+			"finally[KEYWORD]{finally, null, null, finally, null, 24}",
+			requestor.getResults());
+}
+public void testBug459189_004() throws JavaModelException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy(
+			"/Completion/src/X.java",
+			"public class X {\n"+
+			"	Integer foo(){\n"+
+			"		I <Integer, X> i2 = (x) -> {do{} /* HERE */\n"+
+			"		return 0;\n"+
+			"	}\n"+
+			"	Integer bar(Integer x) { return null;}\n"+
+			"}\n"+
+			"interface I <T,R> {\n"+
+			"	R apply(T t);\n"+
+			"}\n");
+
+	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+	requestor.allowAllRequiredProposals();
+	String str = this.workingCopies[0].getSource();
+	String completeBehind = "/* HERE */";
+	int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+	assertResults(
+			"while[KEYWORD]{while, null, null, while, null, 24}",
+			requestor.getResults());
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
index ce59caf..d3fd949 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -54,14 +54,13 @@
 //		TESTS_RANGE = new int[] { 21, 38 };
 }
 public static Test suite() {
-	return buildModelTestSuite(CopyMoveElementsTests.class);
+	return buildModelTestSuite(CopyMoveElementsTests.class, BYTECODE_DECLARATION_ORDER);
 }
 /**
  * Cleanup after the previous test.
  */
 public void tearDown() throws Exception {
 	this.deleteProject("P");
-
 	super.tearDown();
 }
 public void tearDownSuite() throws Exception {
@@ -394,9 +393,9 @@
 	}
 	dests[1] = fieldsSource[0]; //invalid destination
 	dests[2]=  fieldsSource[0];
-
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		boolean e= false;
 		try {
 			typeDest.getJavaModel().copy(fieldsSource, dests, null, null, false, null);
@@ -415,18 +414,19 @@
 			"			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" +
 			"				Y[*]: {CHILDREN | FINE GRAINED}\n" +
 			"					foo[+]: {}"
-		);
+		, listener);
 
 		IJavaElement copy= generateHandle(fieldsSource[0], null, typeDest);
 		assertTrue("Copy should exist", copy.exists());
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 /**
  * Ensures that a multi status exception is generated when copying fields.
  */
 public void testCopyFieldsMultiStatusInDifferentProject() throws CoreException {
+	DeltaListener listener = new DeltaListener();
 	try {
 		this.createFile(
 			"/P/src/X.java",
@@ -454,7 +454,7 @@
 		dests[1] = fieldsSource[0]; //invalid destination
 		dests[2]=  fieldsSource[0];
 
-		startDeltas();
+		startDeltas(listener);
 		boolean e= false;
 		try {
 			typeDest.getJavaModel().copy(fieldsSource, dests, null, null, false, null);
@@ -473,12 +473,12 @@
 			"			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" +
 			"				Y[*]: {CHILDREN | FINE GRAINED}\n" +
 			"					foo[+]: {}"
-		);
+		, listener);
 
 		IJavaElement copy= generateHandle(fieldsSource[0], null, typeDest);
 		assertTrue("Copy should exist", copy.exists());
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 		this.deleteProject("P2");
 	}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
index 0a4f576..076c201 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -33,8 +33,9 @@
  * encountered are thrown.
  */
 public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 
 		// if forcing, ensure that a name collision exists
 		if (force) {
@@ -78,7 +79,7 @@
 				assertTrue("Did not find package decl", found);
 			}
 		}
-		IJavaElementDelta destDelta = this.deltaListener.getDeltaFor(container, true);
+		IJavaElementDelta destDelta = listener.getDeltaFor(container, true);
 		assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
 		IJavaElementDelta[] deltas = null;
 		if (force) {
@@ -96,7 +97,7 @@
 		assertTrue("Added children not correct for element copy", found);
 		return copy;
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 
@@ -106,8 +107,9 @@
  * encountered are thrown.
  */
 public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 
 		// if forcing, ensure that a name collision exists
 		int i;
@@ -169,14 +171,14 @@
 			}
 			IJavaElementDelta destDelta = null;
 			if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
-				destDelta = this.deltaListener.getDeltaFor(moved.getParent());
+				destDelta = listener.getDeltaFor(moved.getParent());
 				assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
 				IJavaElementDelta[] deltas = destDelta.getAddedChildren();
 				assertTrue("Added children not correct for element copy", deltas[0].getElement().equals(moved));
 				assertTrue("flag should be F_MOVED_FROM", (deltas[0].getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
 				assertTrue("moved from handle should be original", deltas[0].getMovedFromElement().equals(element));
 			} else {
-				destDelta = this.deltaListener.getDeltaFor(destinations[i], true);
+				destDelta = listener.getDeltaFor(destinations[i], true);
 				assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
 				IJavaElementDelta[] deltas = destDelta.getAddedChildren();
 				for (int j = 0; j < deltas.length - 1; j++) {
@@ -189,12 +191,12 @@
 				assertTrue("Added children not correct for element copy", pkgDelta.getElement().equals(moved));
 				assertTrue("flag should be F_MOVED_FROM", (pkgDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
 				assertTrue("moved from handle shoud be original", pkgDelta.getMovedFromElement().equals(element));
-				IJavaElementDelta sourceDelta = this.deltaListener.getDeltaFor(element, true);
+				IJavaElementDelta sourceDelta = listener.getDeltaFor(element, true);
 				assertTrue("moved to handle should be original", sourceDelta.getMovedToElement().equals(moved));
 			}
 		}
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 /**
@@ -815,6 +817,7 @@
  * existing CU.
  */
 public void testMoveCU03() throws CoreException {
+	DeltaListener listener = new DeltaListener();
 	try {
 		this.createFolder("/P/src/p1");
 		this.createFile(
@@ -833,7 +836,7 @@
 			"}"
 		);
 		IPackageFragment pkgDest = getPackage("/P/src/p2");
-		startDeltas();
+		startDeltas(listener);
 		movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, null, true, false, null);
 			assertDeltas(
 					"Incorrect delta",
@@ -842,10 +845,10 @@
 							+ "		p1[*]: {CHILDREN}\n"
 							+ "			X.java[-]: {MOVED_TO(X.java [in p2 [in src [in P]]])}\n"
 							+ "		p2[*]: {CHILDREN}\n"
-							+ "			X.java[*]: {CONTENT | PRIMARY RESOURCE}");
+							+ "			X.java[*]: {CONTENT | PRIMARY RESOURCE}", listener);
 	}
 	finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 /**
@@ -872,6 +875,7 @@
  * be renamed, overwriting an existing resource.
  */
 public void testMoveCU05() throws CoreException {
+	DeltaListener listener = new DeltaListener();
 	try {
 		this.createFolder("/P/src/p1");
 		this.createFile(
@@ -890,7 +894,7 @@
 			"}"
 		);
 		IPackageFragment pkgDest = getPackage("/P/src/p2");
-		startDeltas();
+		startDeltas(listener);
 		movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, new String[]{"Y.java"}, true, false, null);
 		assertDeltas(
 					"Incorrect delta",
@@ -900,10 +904,10 @@
 							+ "			X.java[-]: {MOVED_TO(Y.java [in p2 [in src [in P]]])}\n"
 							+ "		p2[*]: {CHILDREN}\n"
 							+ "			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n"
-							+ "				Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}");
+							+ "				Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}", listener);
 	}
 	finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 /**
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
index 8832d85..1ec3a80 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -59,10 +59,10 @@
 		IJavaElement collision = generateHandle(element, rename, container);
 		assertTrue("Collision does not exist", collision.exists());
 	}
-
+	DeltaListener listener = new DeltaListener();
 	IJavaElement copy;
 	try {
-		startDeltas();
+		startDeltas(listener);
 
 		// copy
 	 	((ISourceManipulation) element).copy(container, sibling, rename, force, null);
@@ -106,12 +106,12 @@
 		}
 		if (copy.getElementType() == IJavaElement.IMPORT_DECLARATION)
 			container = ((ICompilationUnit) container).getImportContainer();
-		IJavaElementDelta destDelta = this.deltaListener.getDeltaFor(container, true);
+		IJavaElementDelta destDelta = listener.getDeltaFor(container, true);
 		assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
 		IJavaElementDelta[] deltas = destDelta.getAddedChildren();
 		assertTrue("Added children not correct for element copy", deltas[0].getElement().equals(copy));
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 	return copy;
 }
@@ -276,9 +276,9 @@
 			assertTrue("Collision does not exist", collision.exists());
 		}
 	}
-
+	DeltaListener listener = new DeltaListener();
 	try {
-		if(checkDelta)	startDeltas();
+		if(checkDelta)	startDeltas(listener);
 
 		// move
 		getJavaModel().move(elements, destinations, siblings, names, force, monitor);
@@ -347,23 +347,23 @@
 			if(checkDelta) {
 				IJavaElementDelta destDelta = null;
 				if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
-					destDelta = this.deltaListener.getDeltaFor(moved.getParent());
+					destDelta = listener.getDeltaFor(moved.getParent());
 					assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
 					assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
 					assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent()));
 				} else {
-					destDelta = this.deltaListener.getDeltaFor(destinations[i], true);
+					destDelta = listener.getDeltaFor(destinations[i], true);
 					assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
 					IJavaElementDelta[] deltas = destDelta.getAddedChildren();
 					assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
 					assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
-					IJavaElementDelta sourceDelta= this.deltaListener.getDeltaFor(element, false);
+					IJavaElementDelta sourceDelta= listener.getDeltaFor(element, false);
 					assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED);
 				}
 			}
 		}
 	} finally {
-		if(checkDelta)	stopDeltas();
+		if(checkDelta)	stopDeltas(listener);
 	}
 }
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java
index a9eef33..cd1e1f2 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java
@@ -108,6 +108,52 @@
 		}
 	}
 
+	public void test1Full_ProjectRoot() throws Exception {
+		// cf. testLibsWithFields but with annotations at the project root:
+		myCreateJavaProject("TestLibs");
+		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "/TestLibs", new String[] {
+				"/UnannotatedLib/libs/Lib1.java",
+				"package libs;\n" + 
+				"\n" +
+				"public interface Lib1 {\n" + 
+				"	String one = \"1\";\n" + 
+				"	String none = null;\n" + 
+				"}\n"
+			}, null);
+		createFileInProject("libs", "Lib1.eea", 
+				"class libs/Lib1\n" +
+				"\n" + 
+				"one\n" + 
+				" Ljava/lang/String;\n" + 
+				" L1java/lang/String;\n" + 
+				"\n" + 
+				"none\n" + 
+				" Ljava/lang/String;\n" +
+				" L0java/lang/String;\n" +
+				"\n");
+		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
+		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
+				"package tests;\n" + 
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"\n" + 
+				"import libs.Lib1;\n" + 
+				"\n" + 
+				"public class Test1 {\n" + 
+				"	@NonNull String test0() {\n" + 
+				"		return Lib1.none;\n" + 
+				"	}\n" +
+				"	@NonNull String test1() {\n" + 
+				"		return Lib1.one;\n" + 
+				"	}\n" +
+				"}\n",
+				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
+		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
+		IProblem[] problems = reconciled.getProblems();
+		assertProblems(problems, new String[] {
+			"Pb(933) Null type mismatch: required '@NonNull String' but the provided value is specified as @Nullable",
+		}, new int[] { 8 });
+	}
+
 	/** Reconcile an individual CU. */
 	public void test1Reconcile() throws Exception {
 		setupJavaProject("Test1");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
index 059530b..a5b6fd3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java
@@ -717,9 +717,9 @@
 			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
 			"Pb(964) Null constraint mismatch: The type '@NonNull String' is not a valid substitute for the type parameter '@Nullable U extends Object'",
 			"Pb(964) Null constraint mismatch: The type 'String' is not a valid substitute for the type parameter '@NonNull V extends Object'",
-			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter '@NonNull W extends @NonNull U extends Object'", // FIXME(stephan): @NonNull before W is bogus, see https://bugs.eclipse.org/456532
+			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter 'W extends @NonNull U extends Object'",
 			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter '@NonNull X extends Object'",
-			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter '@NonNull Y extends @NonNull CharSequence'", // FIXME(see above)
+			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter 'Y extends @NonNull CharSequence'",
 		}, new int[] { 8, 16, 17, 18, 20, 20 });
 	}
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
index cb1114d..43c9805 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -11,19 +11,25 @@
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.util.Hashtable;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.eclipse.core.internal.runtime.RuntimeLog;
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ILogListener;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.jdt.core.*;
@@ -656,21 +662,21 @@
 	IJavaProject project= getJavaProject("JavaProjectTests");
 	IContainer underLyingResource = (IContainer)project.getUnderlyingResource();
 	IFolder folder= underLyingResource.getFolder(new Path("output"));
-
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		project.setOutputLocation(folder.getFullPath(), null);
 		assertDeltas(
 			"Unexpected delta 1",
 			"JavaProjectTests[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
 			"	<project root>[*]: {CHILDREN}\n" +
 			"		bin[+]: {}\n" +
-			"	ResourceDelta(/JavaProjectTests/.classpath)[*]"
-		);
+			"	ResourceDelta(/JavaProjectTests/.classpath)[*]",
+			listener);
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 		try {
-			startDeltas();
+			startDeltas(listener);
 			folder= underLyingResource.getFolder(new Path("bin"));
 			project.setOutputLocation(folder.getFullPath(), null);
 			assertDeltas(
@@ -678,10 +684,10 @@
 				"JavaProjectTests[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
 				"	<project root>[*]: {CHILDREN}\n" +
 				"		bin[-]: {}\n" +
-				"	ResourceDelta(/JavaProjectTests/.classpath)[*]"
-			);
+				"	ResourceDelta(/JavaProjectTests/.classpath)[*]",
+				listener);
 		} finally {
-			stopDeltas();
+			stopDeltas(listener);
 		}
 	}
 }
@@ -724,8 +730,8 @@
 	IWorkspaceDescription description = workspace.getDescription();
 	description.setAutoBuilding(true);
 	workspace.setDescription(description);
-
-	startDeltas();
+	DeltaListener listener = new DeltaListener();
+	startDeltas(listener);
 	IPackageFragment frag = getPackageFragment("JavaProjectTests", "", "x.y");
 	IFolder folder = (IFolder) frag.getUnderlyingResource();
 	try {
@@ -734,10 +740,10 @@
 			"Unexpected delta",
 			"JavaProjectTests[*]: {CHILDREN}\n" +
 			"	<project root>[*]: {CHILDREN}\n" +
-			"		x.y[-]: {}"
-		);
+			"		x.y[-]: {}",
+		listener);
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 
 		// turn autobuild off
 		description.setAutoBuilding(autoBuild);
@@ -931,15 +937,16 @@
 public void testFolderWithDotName() throws JavaModelException, CoreException {
 	IPackageFragmentRoot root= getPackageFragmentRoot("JavaProjectTests", "");
 	IContainer folder= (IContainer)root.getCorrespondingResource();
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		folder.getFolder(new Path("org.eclipse")).create(false, true, null);
 		assertDeltas(
 			"Unexpected delta", 
 			"JavaProjectTests[*]: {CONTENT}\n" + 
-			"	ResourceDelta(/JavaProjectTests/org.eclipse)[+]"
-		);
-		stopDeltas();
+			"	ResourceDelta(/JavaProjectTests/org.eclipse)[+]",
+		listener);
+		stopDeltas(listener);
 
 		IJavaElement[] children = root.getChildren();
 		IPackageFragment bogus = root.getPackageFragment("org.eclipse");
@@ -1165,15 +1172,15 @@
 	// as a package fragment
 	IContainer underLyingResource = (IContainer)root.getUnderlyingResource();
 	IFolder newFolder= underLyingResource.getFolder(new Path("bin")).getFolder(new Path("nested"));
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		newFolder.create(false, true, null);
 		assertDeltas(
 			"Unexpected delta", 
-			""
-		);
+			"", listener);
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 		deleteResource(newFolder);
 	}
 }
@@ -1760,17 +1767,17 @@
 	IJavaProject jproject= getJavaProject("JavaProjectTests");
 	IProject project= jproject.getProject();
 	project.close(null);
-
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		project.open(null);
 		assertDeltas(
 			"Unexpected delta 2",
 			"JavaProjectTests[*]: {OPENED}\n" +
-			"ResourceDelta(/JavaProjectTests)"
+			"ResourceDelta(/JavaProjectTests)", listener
 		);
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 	}
 }
 /**
@@ -1795,17 +1802,17 @@
 public void testProjectClose() throws JavaModelException, CoreException {
 	IJavaProject jproject= getJavaProject("JavaProjectTests");
 	IProject project= jproject.getProject();
-
+	DeltaListener listener = new DeltaListener();
 	try {
-		startDeltas();
+		startDeltas(listener);
 		project.close(null);
 		assertDeltas(
 			"Unexpected delta 1",
 			"JavaProjectTests[*]: {CLOSED}\n" +
-			"ResourceDelta(/JavaProjectTests)"
+			"ResourceDelta(/JavaProjectTests)", listener
 		);
 	} finally {
-		stopDeltas();
+		stopDeltas(listener);
 		project.open(null);
 	}
 }
@@ -2586,4 +2593,47 @@
 		this.deleteProject("P");
 	}
 }
+/**
+ * Test that conflicting rules between refreshLocal and IProject.touch() invoked by
+ * JDT don't cause an IAE.
+ * 
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=462756"
+ */
+@SuppressWarnings("rawtypes")
+public void testBug462756() throws CoreException {
+	Hashtable javaCoreOptions = JavaCore.getOptions();
+	try {
+		IJavaProject proj = this.createJavaProject("P", new String[] {"src"}, new String[]{}, "bin");
+		proj.getProject().open(null);
+		createFolder("/P/.settings");
+		String content = "org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7\n" +
+				"org.eclipse.jdt.core.compiler.compliance=1.7\n" +
+				"org.eclipse.jdt.core.compiler.source=1.7\n";
+
+		IFile file = getFile("/P/.settings/org.eclipse.jdt.core.prefs");
+		try (BufferedWriter output = new BufferedWriter(new FileWriter(file.getLocation().toFile()))) {
+			output.write(content);
+			output.flush();
+		} catch(Exception e) {
+		}
+		final StringBuffer buffer = new StringBuffer();
+		RuntimeLog.addLogListener(new ILogListener() {
+			@Override
+			public void logging(IStatus status, String plugin) {
+				if (status.getSeverity() == IStatus.ERROR && status.toString().contains("java.lang.IllegalArgumentException")) {
+					buffer.append("Should not throw IllegalArgumentException");
+				}
+			}
+		});
+		proj.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+		waitForManualRefresh();
+		if (buffer.length() > 0) {
+			fail(buffer.toString());
+		}
+		assertEquals("Compliance should be updated", "1.7", proj.getOption("org.eclipse.jdt.core.compiler.compliance", true));
+	} finally {
+		 this.deleteProject("P");
+		 JavaCore.setOptions(javaCoreOptions);
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
index aa9bf62..a529c77 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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,10 +7,16 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Terry Parker <tparker@google.com> - Enable the Java model caches to recover from IO errors - https://bugs.eclipse.org/455042
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
 import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
 
 import org.eclipse.core.resources.IWorkspaceRunnable;
 import org.eclipse.core.runtime.CoreException;
@@ -18,7 +24,10 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
 import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
+import org.eclipse.jdt.internal.core.JavaModelManager;
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.core.NameLookup;
 
@@ -345,5 +354,83 @@
 		deleteProject("P2");
 	}
 }
+/*
+ * A test for bug 162621. Tests that a library jar that is initially invalid but transitions
+ * to being valid becomes visible in name lookup. Previously the jar would stay in the invalid
+ * archive cache until a classpath change was generated, and would not make it into the project's
+ * JavaProjectElementInfo cache without restarting Eclipse or closing and reopening the project.
+ */
+public void testTransitionFromInvalidToValidJar() throws CoreException, IOException {
+	/*
+	 * Since it is difficult to test intermittent IO errors, simulate it
+	 * by creating two jars of equal size, one of which has an invalid format.
+	 * Set up the classpath with the invalid jar, and then swap in the valid jar
+	 * and reset its timestamp to be the same as the original file.
+	 */
+	String goodJar = getExternalPath() + "goodJar.jar";
+	String transitioningJar = getExternalPath() + "transitioningJar.jar";
+	java.nio.file.Path goodJarPath = FileSystems.getDefault().getPath(goodJar);
+	java.nio.file.Path transitioningJarPath = FileSystems.getDefault().getPath(transitioningJar);
+	IPath transitioningIPath = Path.fromOSString(transitioningJar);
+
+	try {
+		Util.createJar(
+				new String[] {
+						"test1/IResource.java", //$NON-NLS-1$
+						"package test1;\n" + //$NON-NLS-1$
+						"public class IResource {\n" + //$NON-NLS-1$
+						"}" //$NON-NLS-1$
+					},
+				new String[] {
+					"META-INF/MANIFEST.MF",
+					"Manifest-Version: 1.0\n"
+				},
+				goodJar,
+				JavaCore.VERSION_1_4);
+		char[] invalidContents = new char[(int) goodJarPath.toFile().length()];
+		Arrays.fill(invalidContents, ' ');
+		Util.createFile(transitioningJar, String.copyValueOf(invalidContents));
+
+		// Set up the project with the invalid jar and allow all of the classpath validation
+		// and delta processing to complete.
+		JavaProject proj = (JavaProject) createJavaProject("P", new String[] {}, new String[] {transitioningJar}, "bin");
+		JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(null, null);
+		waitForAutoBuild();
+
+		assertTrue("The invalid archive cache should report that the jar is invalid",
+				JavaModelManager.getJavaModelManager().isInvalidArchive(transitioningIPath));
+		IType type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
+		assertEquals("Name lookup should fail when the jar is invalid", null, type);
+
+		// Substitute the good jar, maintaining the timestamp.
+		FileTime fileTime = Files.getLastModifiedTime(transitioningJarPath);
+		Files.move(goodJarPath, transitioningJarPath, StandardCopyOption.REPLACE_EXISTING);
+		Files.setLastModifiedTime(transitioningJarPath, fileTime);
+
+		// Since the timestamp hasn't changed, an external archive refresh isn't going
+		// to update the caches or cause name lookups to work.
+		JavaModelManager.getJavaModelManager().getJavaModel().refreshExternalArchives(null, null);
+		assertTrue("External archive refresh sees no changes, so the invalid archive cache should be unchanged",
+				JavaModelManager.getJavaModelManager().isInvalidArchive(transitioningIPath));
+		type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
+		assertEquals("External archive refresh sees no changes, so the project cache should be unchanged",
+				null, type);
+
+		// Re-validating the jar via validateClasspathEntry() forces eviction from the
+		// invalid archive cache more quickly than waiting for the time-based eviction,
+		// allowing the test to run more quickly.
+		IClasspathEntry transitioningEntry = JavaCore.newLibraryEntry(transitioningIPath, null, null);
+		ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false);
+
+		assertFalse("The invalid archive cache should no longer report the jar as invalid",
+				JavaModelManager.getJavaModelManager().isInvalidArchive(transitioningIPath));
+		type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
+		assertFalse("Name lookup should be able to find types in the valid jar", type == null);
+	} finally {
+		Files.deleteIfExists(goodJarPath);
+		Files.deleteIfExists(transitioningJarPath);
+		deleteProject("P");
+	}
+}
 }
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SignatureTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SignatureTests.java
index d3e3fe7..ac3fec1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SignatureTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SignatureTests.java
@@ -857,6 +857,18 @@
 		"List<java.lang.String>\n",
 		Signature.getSimpleNames("java.util.List<java.lang.String>"));
 }
+public void testGetSignaturesSimpleName01() {
+	assertEquals(
+		"Unexpected simple names",
+		"? extends CharSequence",
+		Signature.getSignatureSimpleName("+Ljava.lang.CharSequence;"));
+}
+public void testGetSignaturesSimpleName02() {
+	assertEquals(
+		"Unexpected simple names",
+		"? extends CharSequence",
+		Signature.getSignatureSimpleName("+QCharSequence;"));
+}
 /**
  * @see Signature
  */
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test432593/A_in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test432593/A_in.java
new file mode 100644
index 0000000..85b808b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test432593/A_in.java
@@ -0,0 +1,44 @@
+package com.ibm.icu.util; public class LocaleMatcher {private static final boolean DEBUG=false;private static final double DEFAULT_THRESHOLD=0.5D;private final ULocale defaultLanguage;java.util.Map<ULocale, com.ibm.icu.impl.Row.R2<ULocale, Double>> maximizedLanguageToWeight=new java.util.LinkedHashMap();LanguageMatcherData matcherData;private static LanguageMatcherData defaultWritten=LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$3(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(LanguageMatcherData.access$2(new LanguageMatcherData().addDistance("no","nb",100,"The language no is normally taken as nb in content; we might alias this for lookup."),"nn","nb",96),"nn","no",96).addDistance("da","no",90,"Danish and norwegian are reasonably close."),"da","nb",90).addDistance("hr","br",96,"Serbo-croatian variants are all very close."),"sh","br",96),"sr","br",96),"sh","hr",96),"sr","hr",96),"sh","sr",96).addDistance("sr-Latn","sr-Cyrl",90,"Most serbs can read either script."),"*-Hans","*-Hant",85,true,"Readers of simplified can read traditional much better than reverse.").addDistance("*-Hant","*-Hans",75,true).addDistance("en-*-US","en-*-CA",98,"US is different than others, and Canadian is inbetween."),"en-*-US","en-*-*",97),"en-*-CA","en-*-*",98),"en-*-*","en-*-*",99).addDistance("es-*-ES","es-*-ES",100,"Latin American Spanishes are closer to each other. Approximate by having es-ES be further from everything else."),"es-*-ES","es-*-*",93).addDistance("*","*",1,"[Default value -- must be at end!] Normally there is no comprehension of different languages.").addDistance("*-*","*-*",20,"[Default value -- must be at end!] Normally there is little comprehension of different scripts.").addDistance("*-*-*","*-*-*",96,"[Default value -- must be at end!] Normally there are small differences across regions.").freeze();private static java.util.HashMap<String, String> canonicalMap=new java.util.HashMap();static {LocaleMatcher.canonicalMap.put("iw","he");LocaleMatcher.canonicalMap.put("mo","ro");LocaleMatcher.canonicalMap.put("tl","fil");}public LocaleMatcher(LocalePriorityList languagePriorityList){this(languagePriorityList,LocaleMatcher.defaultWritten);}public LocaleMatcher(String languagePriorityListString){this(LocalePriorityList.add(languagePriorityListString).build());}public LocaleMatcher(LocalePriorityList languagePriorityList,LanguageMatcherData matcherData){this.matcherData=matcherData;r4=languagePriorityList.iterator();while (r4.hasNext()){ULocale language=(ULocale)r4.next();super.add(language,languagePriorityList.getWeight(language));}java.util.Iterator<ULocale> it=languagePriorityList.iterator();this.defaultLanguage=it.hasNext()?(ULocale)it.next():null;}public double match(ULocale desired,ULocale desiredMax,ULocale supported,ULocale supportedMax){return this.matcherData.match(desired,desiredMax,supported,supportedMax);}public ULocale canonicalize(ULocale ulocale){String lang=ulocale.getLanguage();String lang2=(String)LocaleMatcher.canonicalMap.get(lang);String script=ulocale.getScript();String script2=(String)LocaleMatcher.canonicalMap.get(script);String region=ulocale.getCountry();String region2=(String)LocaleMatcher.canonicalMap.get(region);if (lang2 != null || script2 != null || region2 != null)return new ULocale(lang2 == null?lang:lang2,script2 == null?script:script2,region2 == null?region:region2);return ulocale;}public ULocale getBestMatch(LocalePriorityList languageList){double bestWeight=0.0D;ULocale bestTableMatch=null;r6=languageList.iterator();while (r6.hasNext()){ULocale language=(ULocale)r6.next();com.ibm.icu.impl.Row.R2<ULocale, Double> matchRow=super.getBestMatchInternal(language);double weight=((Double)matchRow.get1()).doubleValue() * languageList.getWeight(language).doubleValue();if (weight <= bestWeight){}bestWeight=weight;bestTableMatch=(ULocale)matchRow.get0();}if (bestWeight < 0.5D)bestTableMatch=this.defaultLanguage;return bestTableMatch;}public ULocale getBestMatch(String languageList){return this.getBestMatch(LocalePriorityList.add(languageList).build());}public ULocale getBestMatch(ULocale ulocale){return (ULocale)super.getBestMatchInternal(ulocale).get0();}public String toString(){return "{" + this.defaultLanguage + ", " + this.maximizedLanguageToWeight + "}";}private com.ibm.icu.impl.Row.R2<ULocale, Double> getBestMatchInternal(ULocale languageCode){languageCode=this.canonicalize(languageCode);ULocale maximized=super.addLikelySubtags(languageCode);double bestWeight=0.0D;ULocale bestTableMatch=null;r7=this.maximizedLanguageToWeight.keySet().iterator();while (r7.hasNext()){ULocale tableKey=(ULocale)r7.next();com.ibm.icu.impl.Row.R2<ULocale, Double> row=(com.ibm.icu.impl.Row.R2)this.maximizedLanguageToWeight.get(tableKey);double match=this.match(languageCode,maximized,tableKey,(ULocale)row.get0());double weight=match * ((Double)row.get1()).doubleValue();if (weight <= bestWeight){}bestWeight=weight;bestTableMatch=tableKey;}if (bestWeight < 0.5D)bestTableMatch=this.defaultLanguage;return com.ibm.icu.impl.Row.R2.of(bestTableMatch,Double.valueOf(bestWeight));}private void add(ULocale language,Double weight){language=this.canonicalize(language);com.ibm.icu.impl.Row.R2<ULocale, Double> row=com.ibm.icu.impl.Row.of(super.addLikelySubtags(language),weight);this.maximizedLanguageToWeight.put(language,row);}private ULocale addLikelySubtags(ULocale languageCode){ULocale result=ULocale.addLikelySubtags(languageCode);if (result == null || result.equals(languageCode)){String language=languageCode.getLanguage();String script=languageCode.getScript();String region=languageCode.getCountry();return new ULocale((language.length() == 0?"und":language) + "_" + (script.length() == 0?"Zzzz":script) + "_" + (region.length() == 0?"ZZ":region));}return result;}public static class LanguageMatcherData implements Freezable<LanguageMatcherData>{ScoreData languageScores=new ScoreData(Level.language);ScoreData scriptScores=new ScoreData(Level.script);ScoreData regionScores=new ScoreData(Level.region);private boolean frozen=false;private static int[] $SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level;public double match(ULocale a,ULocale aMax,ULocale b,ULocale bMax){double diff=0.0D;diff=diff + this.languageScores.getScore(a,aMax,a.getLanguage(),aMax.getLanguage(),b,bMax,b.getLanguage(),bMax.getLanguage());diff=diff + this.scriptScores.getScore(a,aMax,a.getScript(),aMax.getScript(),b,bMax,b.getScript(),bMax.getScript());diff=diff + this.regionScores.getScore(a,aMax,a.getCountry(),aMax.getCountry(),b,bMax,b.getCountry(),bMax.getCountry());if (!a.getVariant().equals(b.getVariant()))diff=diff + 1.0D;if (diff < 0.0D)diff=0.0D; else if (diff > 1.0D)diff=1.0D;return 1.0D - diff;}private LanguageMatcherData addDistance(String desired,String supported,int percent){return super.addDistance(desired,supported,percent,false,null);}public LanguageMatcherData addDistance(String desired,String supported,int percent,String comment){return super.addDistance(desired,supported,percent,false,comment);}public LanguageMatcherData addDistance(String desired,String supported,int percent,boolean oneway){return super.addDistance(desired,supported,percent,oneway,null);}private LanguageMatcherData addDistance(String desired,String supported,int percent,boolean oneway,String comment){double score=1.0D - (double)percent / 100.0D;LocalePatternMatcher desiredMatcher=new LocalePatternMatcher(desired);Level desiredLen=desiredMatcher.getLevel();LocalePatternMatcher supportedMatcher=new LocalePatternMatcher(supported);Level supportedLen=supportedMatcher.getLevel();if (desiredLen != supportedLen)throw new IllegalArgumentException();com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data=com.ibm.icu.impl.Row.of(desiredMatcher,supportedMatcher,Double.valueOf(score));com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data2=oneway?null:com.ibm.icu.impl.Row.of(supportedMatcher,desiredMatcher,Double.valueOf(score));switch (desiredLen){case language:String dlanguage=desiredMatcher.getLanguage();String slanguage=supportedMatcher.getLanguage();this.languageScores.addDataToScores(dlanguage,slanguage,data);if (!oneway)this.languageScores.addDataToScores(slanguage,dlanguage,data2);break;case script:String dscript=desiredMatcher.getScript();String sscript=supportedMatcher.getScript();this.scriptScores.addDataToScores(dscript,sscript,data);if (!oneway)this.scriptScores.addDataToScores(sscript,dscript,data2);break;case region:String dregion=desiredMatcher.getRegion();String sregion=supportedMatcher.getRegion();this.regionScores.addDataToScores(dregion,sregion,data);if (!oneway)this.regionScores.addDataToScores(sregion,dregion,data2);break;}return this;}public LanguageMatcherData cloneAsThawed(){LanguageMatcherData result=(LanguageMatcherData)this.clone();result.languageScores=this.languageScores.cloneAsThawed();result.scriptScores=this.scriptScores.cloneAsThawed();result.regionScores=this.regionScores.cloneAsThawed();result.frozen=false;return result;}public LanguageMatcherData freeze(){return this;}public boolean isFrozen(){return this.frozen;}public Object cloneAsThawed(){return this.cloneAsThawed();}public Object freeze(){return this.freeze();}static LanguageMatcherData access$2(LanguageMatcherData arg0,String arg1,String arg2,int arg3){return arg0.addDistance(arg1,arg2,arg3);}static LanguageMatcherData access$3(LanguageMatcherData arg0,String arg1,String arg2,int arg3,boolean arg4,String arg5){return arg0.addDistance(arg1,arg2,arg3,arg4,arg5);}static int[] $SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level(){if (LanguageMatcherData.$SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level == null){}r0=new int[Level.values().length];r0[Level.language.ordinal()]=1;r0[Level.region.ordinal()]=3;r0[Level.script.ordinal()]=2;return LanguageMatcherData.$SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level=r0;}}private static class ScoreData implements Freezable<ScoreData>{java.util.LinkedHashSet<com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double>> scores=new java.util.LinkedHashSet();final double worst;final Level level;private boolean frozen=false;public ScoreData(Level level){this.level=level;this.worst=(double)(1 - (level == Level.language?90:level == Level.script?20:4)) / 100.0D;}void addDataToScores(String desired,String supported,com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data){this.scores.add(data);}double getScore(ULocale desiredLocale,ULocale dMax,String desiredRaw,String desiredMax,ULocale supportedLocale,ULocale sMax,String supportedRaw,String supportedMax){boolean desiredChange=desiredRaw.equals(desiredMax);boolean supportedChange=supportedRaw.equals(supportedMax);if (!desiredMax.equals(supportedMax)){double distance=super.getRawScore(dMax,sMax);if (desiredChange == supportedChange)distance=distance * 0.75D;if (desiredChange)distance=distance * 0.5D;} else if (desiredChange == supportedChange)double distance=0.0D; else double distance=0.25D * this.worst;return distance;}private double getRawScore(ULocale desiredLocale,ULocale supportedLocale){r4=this.scores.iterator();while (r4.hasNext()){com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> datum=(com.ibm.icu.impl.Row.R3)r4.next();if (((LocalePatternMatcher)datum.get0()).matches(desiredLocale) && ((LocalePatternMatcher)datum.get1()).matches(supportedLocale))return ((Double)datum.get2()).doubleValue();}return this.worst;}public String toString(){return this.level + ", " + this.scores;}public ScoreData cloneAsThawed(){ScoreData result=(ScoreData)this.clone();result.scores=(java.util.LinkedHashSet)result.scores.clone();result.frozen=false;return result;}public ScoreData freeze(){return this;}public boolean isFrozen(){return this.frozen;}public Object cloneAsThawed(){return this.cloneAsThawed();}public Object freeze(){return this.freeze();}}private static class LocalePatternMatcher {private String lang;private String script;private String region;private Level level;static java.util.regex.Pattern pattern=java.util.regex.Pattern.compile("([a-zA-Z]{1,8}|\\\\*)(?:-([a-zA-Z]{4}|\\\\*))?(?:-([a-zA-Z]{2}|[0-9]{3}|\\\\*))?");public LocalePatternMatcher(String toMatch){java.util.regex.Matcher matcher=LocalePatternMatcher.pattern.matcher(toMatch);if (!matcher.matches())throw new IllegalArgumentException("Bad pattern: " + toMatch);this.lang=matcher.group(1);this.script=matcher.group(2);this.region=matcher.group(3);this.level=this.region != null?Level.region:this.script != null?Level.script:Level.language;if (this.lang.equals("*"))this.lang=null;if (this.script != null && this.script.equals("*"))this.script=null;if (this.region != null && this.region.equals("*"))this.region=null;}boolean matches(ULocale ulocale){if (this.lang != null && !this.lang.equals(ulocale.getLanguage()))return false;if (this.script != null && !this.script.equals(ulocale.getScript()))return false;if (this.region != null && !this.region.equals(ulocale.getCountry()))return false;return true;}public Level getLevel(){return this.level;}public String getLanguage(){return this.lang == null?"*":this.lang;}public String getScript(){return this.script == null?"*":this.script;}public String getRegion(){return this.region == null?"*":this.region;}public String toString(){String result=this.getLanguage();if (this.level != Level.language){result=result + "-" + this.getScript();if (this.level != Level.script)result=result + "-" + this.getRegion();}return result;}}static enum Level {language,script,region}}
+/*package com.ibm.icu.util; public class LocaleMatcher {
+	private static final boolean DEBUG=false;private static final double DEFAULT_THRESHOLD=0.5D;private final ULocale defaultLanguage;java.util.Map<ULocale, com.ibm.icu.impl.Row.R2<ULocale, Double>> maximizedLanguageToWeight=new java.util.LinkedHashMap();
+	LanguageMatcherData matcherData;
+	private static LanguageMatcherData defaultWritten=
+//			LanguageMatcherData.access$2(
+//			LanguageMatcherData.access$2(
+//			LanguageMatcherData.access$2(
+//			LanguageMatcherData.access$3(
+//			LanguageMatcherData.access$2(
+//			LanguageMatcherData.access$2(
+//			LanguageMatcherData.access$2(
+			LanguageMatcherData.access$2(
+			LanguageMatcherData.access$2(
+			LanguageMatcherData.access$2(
+			LanguageMatcherData.access$2(
+			LanguageMatcherData.access$2(new LanguageMatcherData().addDistance("ONE","n",100,"O"),"n","n",96),"n","n",96).addDistance("TWO","n",90,"T"),"d","n",90).addDistance("THREE","b",96,"T"),"s","b",96),"s","b",96),"s","h",96),"s","h",96),"s","s",96).addDistance("FOUR","s",90,"F"),"*","*",85,true,"R").addDistance("SIX","e",98,"S"),"e","e",97),"e","e",98),"e","e",99).freeze();
+//			LanguageMatcherData.access$2(new LanguageMatcherData().addDistance("ONE","n",100,"O"),"n","n",96),"n","n",96).addDistance("TWO","n",90,"T"),"d","n",90).addDistance("THREE","b",96,"T"),"s","b",96),"s","b",96),"s","h",96),"s","h",96),"s","s",96).addDistance("FOUR","s",90,"F"),"*","*",85,true,"R").addDistance("FIVE","*",75,true).addDistance("SIX","e",98,"S"),"e","e",97),"e","e",98),"e","e",99).addDistance("SEVEN","e",100,"L"),"e","e",93).addDistance("EIGHT","*",1,"g").addDistance("NINE","*",20,"s").addDistance("TEN","*",96,"e").freeze();
+	private static java.util.HashMap<String, String> canonicalMap=new java.util.HashMap();static {LocaleMatcher.canonicalMap.put("iw","he");LocaleMatcher.canonicalMap.put("mo","ro");LocaleMatcher.canonicalMap.put("tl","fil");}public LocaleMatcher(LocalePriorityList languagePriorityList){this(languagePriorityList,LocaleMatcher.defaultWritten);}public LocaleMatcher(String languagePriorityListString){this(LocalePriorityList.add(languagePriorityListString).build());}public LocaleMatcher(LocalePriorityList languagePriorityList,LanguageMatcherData matcherData){this.matcherData=matcherData;r4=languagePriorityList.iterator();while (r4.hasNext()){ULocale language=(ULocale)r4.next();super.add(language,languagePriorityList.getWeight(language));}java.util.Iterator<ULocale> it=languagePriorityList.iterator();this.defaultLanguage=it.hasNext()?(ULocale)it.next():null;}public double match(ULocale desired,ULocale desiredMax,ULocale supported,ULocale supportedMax){return this.matcherData.match(desired,desiredMax,supported,supportedMax);}public ULocale canonicalize(ULocale ulocale){String lang=ulocale.getLanguage();String lang2=(String)LocaleMatcher.canonicalMap.get(lang);String script=ulocale.getScript();String script2=(String)LocaleMatcher.canonicalMap.get(script);String region=ulocale.getCountry();String region2=(String)LocaleMatcher.canonicalMap.get(region);if (lang2 != null || script2 != null || region2 != null)return new ULocale(lang2 == null?lang:lang2,script2 == null?script:script2,region2 == null?region:region2);return ulocale;}public ULocale getBestMatch(LocalePriorityList languageList){double bestWeight=0.0D;ULocale bestTableMatch=null;r6=languageList.iterator();while (r6.hasNext()){ULocale language=(ULocale)r6.next();com.ibm.icu.impl.Row.R2<ULocale, Double> matchRow=super.getBestMatchInternal(language);double weight=((Double)matchRow.get1()).doubleValue() * languageList.getWeight(language).doubleValue();if (weight <= bestWeight){}bestWeight=weight;bestTableMatch=(ULocale)matchRow.get0();}if (bestWeight < 0.5D)bestTableMatch=this.defaultLanguage;return bestTableMatch;}public ULocale getBestMatch(String languageList){return this.getBestMatch(LocalePriorityList.add(languageList).build());}public ULocale getBestMatch(ULocale ulocale){return (ULocale)super.getBestMatchInternal(ulocale).get0();}public String toString(){return "{" + this.defaultLanguage + ", " + this.maximizedLanguageToWeight + "}";}private com.ibm.icu.impl.Row.R2<ULocale, Double> getBestMatchInternal(ULocale languageCode){languageCode=this.canonicalize(languageCode);ULocale maximized=super.addLikelySubtags(languageCode);double bestWeight=0.0D;ULocale bestTableMatch=null;r7=this.maximizedLanguageToWeight.keySet().iterator();while (r7.hasNext()){ULocale tableKey=(ULocale)r7.next();com.ibm.icu.impl.Row.R2<ULocale, Double> row=(com.ibm.icu.impl.Row.R2)this.maximizedLanguageToWeight.get(tableKey);double match=this.match(languageCode,maximized,tableKey,(ULocale)row.get0());double weight=match * ((Double)row.get1()).doubleValue();if (weight <= bestWeight){}bestWeight=weight;bestTableMatch=tableKey;}if (bestWeight < 0.5D)bestTableMatch=this.defaultLanguage;return com.ibm.icu.impl.Row.R2.of(bestTableMatch,Double.valueOf(bestWeight));}private void add(ULocale language,Double weight){language=this.canonicalize(language);com.ibm.icu.impl.Row.R2<ULocale, Double> row=com.ibm.icu.impl.Row.of(super.addLikelySubtags(language),weight);this.maximizedLanguageToWeight.put(language,row);}private ULocale addLikelySubtags(ULocale languageCode){ULocale result=ULocale.addLikelySubtags(languageCode);if (result == null || result.equals(languageCode)){String language=languageCode.getLanguage();String script=languageCode.getScript();String region=languageCode.getCountry();return new ULocale((language.length() == 0?"und":language) + "_" + (script.length() == 0?"Zzzz":script) + "_" + (region.length() == 0?"ZZ":region));}return result;}public static class LanguageMatcherData implements Freezable<LanguageMatcherData>{ScoreData languageScores=new ScoreData(Level.language);ScoreData scriptScores=new ScoreData(Level.script);ScoreData regionScores=new ScoreData(Level.region);private boolean frozen=false;private static int[] $SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level;
+	public double match(ULocale a,ULocale aMax,ULocale b,ULocale bMax){double diff=0.0D;diff=diff + this.languageScores.getScore(a,aMax,a.getLanguage(),aMax.getLanguage(),b,bMax,b.getLanguage(),bMax.getLanguage());diff=diff + this.scriptScores.getScore(a,aMax,a.getScript(),aMax.getScript(),b,bMax,b.getScript(),bMax.getScript());diff=diff + this.regionScores.getScore(a,aMax,a.getCountry(),aMax.getCountry(),b,bMax,b.getCountry(),bMax.getCountry());if (!a.getVariant().equals(b.getVariant()))diff=diff + 1.0D;if (diff < 0.0D)diff=0.0D; else if (diff > 1.0D)diff=1.0D;return 1.0D - diff;}
+			private LanguageMatcherData addDistance(String desired,String supported,int percent){return super.addDistance(desired,supported,percent,false,null);}public LanguageMatcherData addDistance(String desired,String supported,int percent,String comment){return super.addDistance(desired,supported,percent,false,comment);}public LanguageMatcherData addDistance(String desired,String supported,int percent,boolean oneway){return super.addDistance(desired,supported,percent,oneway,null);}private LanguageMatcherData addDistance(String desired,String supported,int percent,boolean oneway,String comment){double score=1.0D - (double)percent / 100.0D;LocalePatternMatcher desiredMatcher=new LocalePatternMatcher(desired);Level desiredLen=desiredMatcher.getLevel();LocalePatternMatcher supportedMatcher=new LocalePatternMatcher(supported);Level supportedLen=supportedMatcher.getLevel();if (desiredLen != supportedLen)throw new IllegalArgumentException();com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data=com.ibm.icu.impl.Row.of(desiredMatcher,supportedMatcher,Double.valueOf(score));com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data2=oneway?null:com.ibm.icu.impl.Row.of(supportedMatcher,desiredMatcher,Double.valueOf(score));switch (desiredLen){case language:String dlanguage=desiredMatcher.getLanguage();String slanguage=supportedMatcher.getLanguage();this.languageScores.addDataToScores(dlanguage,slanguage,data);if (!oneway)this.languageScores.addDataToScores(slanguage,dlanguage,data2);break;case script:String dscript=desiredMatcher.getScript();String sscript=supportedMatcher.getScript();this.scriptScores.addDataToScores(dscript,sscript,data);if (!oneway)this.scriptScores.addDataToScores(sscript,dscript,data2);break;case region:String dregion=desiredMatcher.getRegion();String sregion=supportedMatcher.getRegion();this.regionScores.addDataToScores(dregion,sregion,data);if (!oneway)this.regionScores.addDataToScores(sregion,dregion,data2);break;}return this;}public LanguageMatcherData cloneAsThawed(){LanguageMatcherData result=(LanguageMatcherData)this.clone();result.languageScores=this.languageScores.cloneAsThawed();result.scriptScores=this.scriptScores.cloneAsThawed();result.regionScores=this.regionScores.cloneAsThawed();result.frozen=false;return result;}public LanguageMatcherData freeze(){return this;}public boolean isFrozen(){return this.frozen;}public Object cloneAsThawed(){return this.cloneAsThawed();}public Object freeze(){return this.freeze();}static LanguageMatcherData access$2(LanguageMatcherData arg0,String arg1,String arg2,int arg3){return arg0.addDistance(arg1,arg2,arg3);}static LanguageMatcherData access$3(LanguageMatcherData arg0,String arg1,String arg2,int arg3,boolean arg4,String arg5){return arg0.addDistance(arg1,arg2,arg3,arg4,arg5);}static int[] $SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level(){if (LanguageMatcherData.$SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level == null){}r0=new int[Level.values().length];r0[Level.language.ordinal()]=1;r0[Level.region.ordinal()]=3;r0[Level.script.ordinal()]=2;return LanguageMatcherData.$SWITCH_TABLE$com$ibm$icu$util$LocaleMatcher$Level=r0;}}private static class ScoreData implements Freezable<ScoreData>{java.util.LinkedHashSet<com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double>> scores=new java.util.LinkedHashSet();final double worst;final Level level;private boolean frozen=false;public ScoreData(Level level){this.level=level;this.worst=(double)(1 - (level == Level.language?90:level == Level.script?20:4)) / 100.0D;}void addDataToScores(String desired,String supported,com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> data){this.scores.add(data);}double getScore(ULocale desiredLocale,ULocale dMax,String desiredRaw,String desiredMax,ULocale supportedLocale,ULocale sMax,String supportedRaw,String supportedMax){boolean desiredChange=desiredRaw.equals(desiredMax);boolean supportedChange=supportedRaw.equals(supportedMax);if (!desiredMax.equals(supportedMax)){double distance=super.getRawScore(dMax,sMax);if (desiredChange == supportedChange)distance=distance * 0.75D;if (desiredChange)distance=distance * 0.5D;} else if (desiredChange == supportedChange)double distance=0.0D; else double distance=0.25D * this.worst;return distance;}private double getRawScore(ULocale desiredLocale,ULocale supportedLocale){r4=this.scores.iterator();while (r4.hasNext()){com.ibm.icu.impl.Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double> datum=(com.ibm.icu.impl.Row.R3)r4.next();if (((LocalePatternMatcher)datum.get0()).matches(desiredLocale) && ((LocalePatternMatcher)datum.get1()).matches(supportedLocale))return ((Double)datum.get2()).doubleValue();}return this.worst;}public String toString(){return this.level + ", " + this.scores;}public ScoreData cloneAsThawed(){ScoreData result=(ScoreData)this.clone();result.scores=(java.util.LinkedHashSet)result.scores.clone();result.frozen=false;return result;}public ScoreData freeze(){return this;}public boolean isFrozen(){return this.frozen;}public Object cloneAsThawed(){return this.cloneAsThawed();}public Object freeze(){return this.freeze();}}private static class LocalePatternMatcher {private String lang;private String script;private String region;private Level level;static java.util.regex.Pattern pattern=java.util.regex.Pattern.compile("([a-zA-Z]{1,8}|\\\\*)(?:-([a-zA-Z]{4}|\\\\*))?(?:-([a-zA-Z]{2}|[0-9]{3}|\\\\*))?");public LocalePatternMatcher(String toMatch){java.util.regex.Matcher matcher=LocalePatternMatcher.pattern.matcher(toMatch);if (!matcher.matches())throw new IllegalArgumentException("Bad pattern: " + toMatch);this.lang=matcher.group(1);this.script=matcher.group(2);this.region=matcher.group(3);this.level=this.region != null?Level.region:this.script != null?Level.script:Level.language;if (this.lang.equals("*"))this.lang=null;if (this.script != null && this.script.equals("*"))this.script=null;if (this.region != null && this.region.equals("*"))this.region=null;}boolean matches(ULocale ulocale){if (this.lang != null && !this.lang.equals(ulocale.getLanguage()))return false;if (this.script != null && !this.script.equals(ulocale.getScript()))return false;if (this.region != null && !this.region.equals(ulocale.getCountry()))return false;return true;}public Level getLevel(){return this.level;}public String getLanguage(){return this.lang == null?"*":this.lang;}public String getScript(){return this.script == null?"*":this.script;}public String getRegion(){return this.region == null?"*":this.region;}public String toString(){String result=this.getLanguage();if (this.level != Level.language){result=result + "-" + this.getScript();if (this.level != Level.script)result=result + "-" + this.getRegion();}return result;}}static enum Level {language,script,region}
+			}
+
+*//*class Y {
+	public Y foo(String s1, String s2, int i) {
+		return foo(s1, s2, i, false, null);
+	}
+	public Y foo(String s1, String s2, int i , String s3) {
+		return foo(s1, s2, i, false, s3);
+	}
+	public Y foo(String s1, String s2, int i, boolean b) {
+		return foo(s1, s2, i, b, null);
+	}
+	public Y foo(String s1, String s2, int i, boolean b, String s3) {
+		return this;
+	}
+	public Y bar() {
+		return this;
+	}
+}
+class X {
+	public static Y defaultWritten = new Y().foo("1", "n", 100, "O").freeze();
+}
+*/
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
index ff198cb..0fdc331 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -21,13 +21,22 @@
 import java.util.Hashtable;
 import java.util.List;
 
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider;
 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.Util;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
 
@@ -43,8 +52,9 @@
 private String[] missingPackageHolder = new String[1];
 private int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
 private String encoding; // only useful if referenced in the source path
+private Hashtable<String, Hashtable<String, String>> packageSecondaryTypes = null;
 
-ClasspathDirectory(File directory, String encoding, int mode, 
+ClasspathDirectory(File directory, String encoding, int mode,
 		AccessRuleSet accessRuleSet, String destinationPath) {
 	super(accessRuleSet, destinationPath);
 	this.mode = mode;
@@ -155,6 +165,11 @@
 	}
 	return null;
 }
+public NameEnvironmentAnswer findSecondaryInClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	boolean sourceExists = isPackage(qualifiedPackageName) && ((this.mode & SOURCE) != 0) && doesFileExist( new String(typeName) + SUFFIX_STRING_java, qualifiedPackageName);
+	return sourceExists ? null : findSourceSecondaryType(typeName, qualifiedPackageName, qualifiedBinaryFileName); /* only secondary types */
+}
+
 @Override
 public boolean hasAnnotationFileFor(String qualifiedTypeName) {
 	int pos = qualifiedTypeName.lastIndexOf('/');
@@ -164,6 +179,64 @@
 	}
 	return false;
 }
+
+
+/**
+ *  Add all the secondary types in the package
+ */
+private Hashtable<String, String> getPackageTypes(char[] typeName, String qualifiedPackageName) {
+	Hashtable<String, String> packageEntry = new Hashtable<String, String>();
+
+	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
+	if (dirList == this.missingPackageHolder // package exists in another classpath directory or jar 
+			|| dirList == null) 
+		return packageEntry;
+
+	File dir = new File(this.path + qualifiedPackageName);
+	File[] listFiles = dir.isDirectory() ? dir.listFiles() : null;
+	if (listFiles == null) return packageEntry;
+
+	for (int i = 0, l = listFiles.length; i < l; ++i) {
+		File f = listFiles[i];
+		if (f.isDirectory()) continue;
+		String s = f.getAbsolutePath();
+		if (s == null) continue;
+		CompilationUnit cu = new CompilationUnit(null, s, this.encoding, this.destinationPath);
+		CompilationResult compilationResult = new CompilationResult(cu.getContents(), 1, 1, 10);
+		ProblemReporter problemReporter = 
+				new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					new CompilerOptions(JavaCore.getOptions()),
+					new DefaultProblemFactory());
+		Parser parser = new Parser(problemReporter, false);
+
+		CompilationUnitDeclaration unit = parser.parse(cu, compilationResult);
+		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit != null ? unit.types : null;
+		if (types == null) continue;
+		for (int j = 0, k = types.length; j < k; j++) {
+			TypeDeclaration type = types[j];
+			char[] name = type.isSecondary() ? type.name : null;  // add only secondary types
+			if (name != null) 
+				packageEntry.put(new String(name), s);
+		}
+	}
+	return packageEntry;
+}
+private NameEnvironmentAnswer findSourceSecondaryType(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	
+	if (this.packageSecondaryTypes == null) this.packageSecondaryTypes = new Hashtable<String, Hashtable<String,String>>();
+	Hashtable<String, String> packageEntry = this.packageSecondaryTypes.get(qualifiedPackageName);
+	if (packageEntry == null) {
+		packageEntry = 	getPackageTypes(typeName, qualifiedPackageName);
+		this.packageSecondaryTypes.put(qualifiedPackageName, packageEntry);
+	}
+	String fileName = packageEntry.get(new String(typeName));
+	return fileName != null ? new NameEnvironmentAnswer(new CompilationUnit(null,
+			fileName, this.encoding, this.destinationPath),
+			fetchAccessRestriction(qualifiedBinaryFileName)) : null;
+}
+
+
 public char[][][] findTypeNames(String qualifiedPackageName) {
 	if (!isPackage(qualifiedPackageName)) {
 		return null; // most common case
@@ -173,7 +246,7 @@
 		return null;
 	}
 	String[] listFiles = dir.list(new FilenameFilter() {
-		public boolean accept(File directory, String name) {
+		public boolean accept(File directory1, String name) {
 			String fileName = name.toLowerCase();
 			return fileName.endsWith(".class") || fileName.endsWith(".java"); //$NON-NLS-1$ //$NON-NLS-2$
 		}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index 706a699..b5a4d56 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -4836,11 +4836,11 @@
 		return new CompletionOnSingleNameReference(assistName, position, isInsideAttributeValue());
 	} else {
 		boolean canBeExplicitConstructorCall = false;
-		if(kind == K_BLOCK_DELIMITER
+		if((kind == K_BLOCK_DELIMITER || kind == K_LAMBDA_EXPRESSION_DELIMITER)
 			&& this.previousKind == K_BLOCK_DELIMITER
 			&& this.previousInfo == DO) {
 			return new CompletionOnKeyword3(assistName, position, Keywords.WHILE);
-		} else if(kind == K_BLOCK_DELIMITER
+		} else if((kind == K_BLOCK_DELIMITER || kind == K_LAMBDA_EXPRESSION_DELIMITER)
 			&& this.previousKind == K_BLOCK_DELIMITER
 			&& this.previousInfo == TRY) {
 			return new CompletionOnKeyword3(assistName, position, new char[][]{Keywords.CATCH, Keywords.FINALLY});
@@ -4862,7 +4862,7 @@
 			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=269493: Keywords are not proposed in a for
 			// loop without block. Completion while at K_CONTROL_STATEMENT_DELIMITER case needs to handled
 			// similar to the K_BLOCK_DELIMITER with minor differences.
-			if(kind == K_BLOCK_DELIMITER || kind == K_CONTROL_STATEMENT_DELIMITER) {
+			if(kind == K_BLOCK_DELIMITER || kind == K_CONTROL_STATEMENT_DELIMITER || kind == K_LAMBDA_EXPRESSION_DELIMITER) {
 				if(this.canBeExplicitConstructor == YES) {
 					canBeExplicitConstructorCall = true;
 				}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
index bef2780..bbfc6c9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -78,7 +78,7 @@
 	public int problemCount;
 	public int taskCount;
 	public ICompilationUnit compilationUnit;
-	private Map problemsMap;
+	private Map<CategorizedProblem, ReferenceContext> problemsMap;
 	private Set firstErrors;
 	private int maxProblemPerUnit;
 	public char[][][] qualifiedReferences;
@@ -205,7 +205,7 @@
 	if (problem.isError()){
 		priority += P_ERROR;
 	}
-	ReferenceContext context = this.problemsMap == null ? null : (ReferenceContext) this.problemsMap.get(problem);
+	ReferenceContext context = this.problemsMap == null ? null : this.problemsMap.get(problem);
 	if (context != null){
 		if (context instanceof AbstractMethodDeclaration){
 			AbstractMethodDeclaration method = (AbstractMethodDeclaration) context;
@@ -500,6 +500,13 @@
 	}
 }
 
+ReferenceContext getContext(CategorizedProblem problem) {
+	if (problem != null) {
+		return this.problemsMap.get(problem);
+	}
+	return null;
+}
+
 /**
  * For now, remember the compiled type using its compound name.
  */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
index 963b53a..beef5eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
@@ -17,6 +17,7 @@
 package org.eclipse.jdt.internal.compiler;
 
 import java.io.PrintWriter;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.eclipse.jdt.core.compiler.CategorizedProblem;
@@ -32,6 +33,7 @@
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.CompilerStats;
 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -88,6 +90,8 @@
 	//public CompilationUnitResult currentCompilationUnitResult;
 	public CompilationUnitDeclaration[] unitsToProcess;
 	public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
+	
+	private Map<String, APTProblem[]> aptProblems;
 
 	// name lookup
 	public LookupEnvironment lookupEnvironment;
@@ -496,6 +500,7 @@
 						return;
 					}
 				} catch (SourceTypeCollisionException e) {
+					backupAptProblems();
 					reset();
 					// a generated type was referenced before it was created
 					// the compiler either created a MissingType or found a BinaryType for it
@@ -511,6 +516,8 @@
 					return;
 				}
 			}
+			// Restore the problems before the results are processed and cleaned up.
+			restoreAptProblems();
 			processCompiledUnits(0);
 		} catch (AbortCompilation e) {
 			this.handleInternalException(e, null);
@@ -526,6 +533,58 @@
 		}
 	}
 
+	class APTProblem {
+		CategorizedProblem problem;
+		ReferenceContext context;
+		APTProblem(CategorizedProblem problem, ReferenceContext context) {
+			this.problem = problem;
+			this.context = context;
+		}
+	}
+	
+	protected void backupAptProblems() {
+		if (this.unitsToProcess == null) return;
+		for (CompilationUnitDeclaration unitDecl : this.unitsToProcess) {
+			if (unitDecl == null) continue;
+			CompilationResult result = unitDecl.compilationResult;
+			if (result != null && result.hasErrors()) {
+				CategorizedProblem[] errors = result.getErrors();
+				for (CategorizedProblem problem : errors) {
+					if (problem.getCategoryID() == CategorizedProblem.CAT_UNSPECIFIED) {
+						if (this.aptProblems == null) {
+							this.aptProblems = new HashMap<>();
+						}
+						APTProblem[] problems = this.aptProblems.get(new String(unitDecl.getFileName()));
+						if (problems == null) {
+							this.aptProblems.put(
+									new String(unitDecl.getFileName()),
+									new APTProblem[] { new APTProblem(problem, result.getContext(problem)) });
+						} else {
+							APTProblem[] temp = new APTProblem[problems.length + 1];
+							System.arraycopy(problems, 0, temp, 0, problems.length);
+							temp[problems.length] = new APTProblem(problem, result.getContext(problem));
+							this.aptProblems.put(new String(unitDecl.getFileName()), temp);
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	protected void restoreAptProblems() {
+		if (this.unitsToProcess != null && this.aptProblems!= null) {
+			for (CompilationUnitDeclaration unit : this.unitsToProcess) {
+				APTProblem[] problems = this.aptProblems.get(new String(unit.getFileName()));
+				if (problems != null) {
+					for (APTProblem problem : problems) {
+						unit.compilationResult.record(problem.problem, problem.context);
+					}
+				}
+			}
+		}
+		this.aptProblems = null; // No need for this.
+	}
+
 	protected void processCompiledUnits(int startingIndex) throws java.lang.Error {
 		CompilationUnitDeclaration unit = null;
 		ProcessTaskManager processingTask = null;
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 9692df5..f1ef793 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -40,6 +40,7 @@
  *							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
+ *							Bug 448709 - [1.8][null] ensure we don't infer types that violate null constraints on a type parameter's bound
  *     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
@@ -613,9 +614,18 @@
 	if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
  		checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, scope);
  	}
-	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
-		new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
-				.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+		if ((this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
+			new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
+					.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+		}
+		if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+			if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
+				TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
+				for (int i = 0; i < this.typeArguments.length; i++)
+					this.typeArguments[i].checkNullConstraints(scope, typeVariables, i);
+			}
+		}
 	}
 //{ObjectTeams: may need to wrap the resolved type
     this.resolvedType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(this.resolvedType, scope, this);
@@ -914,7 +924,7 @@
 }
 
 public boolean statementExpression() {
-	return true;
+	return ((this.bits & ASTNode.ParenthesizedMASK) == 0);
 }
 
 //-- interface Invocation: --
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index cc8bae7..2a26380 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -56,6 +56,7 @@
  *
  * Annotation
  */
+@SuppressWarnings({"rawtypes", "unchecked"})
 public abstract class Annotation extends Expression {
 	
 	Annotation persistibleAnnotation = this;  // Emit this into class file, unless this is a repeating annotation, in which case package this into the designated container.
@@ -987,7 +988,115 @@
 		return this.resolvedType;
 	}
 
+	private static boolean isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) {
+		switch (kind) {
+			case Binding.PACKAGE :
+				if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
+					return true;
+				else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) {
+					SourceTypeBinding sourceType = (SourceTypeBinding) recipient;
+					if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME))
+						return true;
+				}
+				break;
+			case Binding.TYPE_USE :
+				if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+					// jsr 308
+					return true;
+				}
+				if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) {
+					// already reported as syntax error; don't report secondary problems
+					return true;
+				}
+				break;
+			case Binding.TYPE :
+			case Binding.GENERIC_TYPE :
+				if (((ReferenceBinding)recipient).isAnnotationType()) {
+					if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0)
+					return true;
+				} else if ((metaTagBits & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) {
+					return true;
+				} else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) {
+					if (CharOperation.equals(((ReferenceBinding) recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME))
+						return true;
+				}
+//{ObjectTeams: allow @Override for roles:
+				if (   (((ReferenceBinding)recipient).isRole())
+					&& (annotationType.id == TypeIds.T_JavaLangOverride))
+					return true;
+//SH}
+				break;
+//{ObjectTeams: method mappings
+			// TODO(SH): should annotations for method mappings be controlled separately?
+			case Binding.BINDING :
+				if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
+					return true;
+				break;
+//SH}
+			case Binding.METHOD :
+				MethodBinding methodBinding = (MethodBinding) recipient;
+				if (methodBinding.isConstructor()) {
+					if ((metaTagBits & (TagBits.AnnotationForConstructor | TagBits.AnnotationForTypeUse)) != 0)
+						return true;
+				} else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) {
+					return true;
+				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+					SourceTypeBinding sourceType = (SourceTypeBinding) methodBinding.declaringClass;
+					MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(methodBinding);
+					if (isTypeUseCompatible(methodDecl.returnType, scope)) {
+						return true;
+					}
+				}
+				break;
+			case Binding.FIELD :
+				if ((metaTagBits & TagBits.AnnotationForField) != 0) {
+					return true;
+				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+					FieldBinding sourceField = (FieldBinding) recipient;
+					SourceTypeBinding sourceType = (SourceTypeBinding) sourceField.declaringClass;
+					FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
+					if (isTypeUseCompatible(fieldDeclaration.type, scope)) {
+						return true;
+					}
+				}
+				break;
+			case Binding.LOCAL :
+				LocalVariableBinding localVariableBinding = (LocalVariableBinding) recipient;
+				if ((localVariableBinding.tagBits & TagBits.IsArgument) != 0) {
+					if ((metaTagBits & TagBits.AnnotationForParameter) != 0) {
+						return true;
+					} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+						if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
+							return true;
+						}
+					}
+				} else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) {
+					return true;
+				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+					if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
+						return true;
+					}
+				}
+				break;
+			case Binding.TYPE_PARAMETER : // jsr308
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196
+				if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
+					return true;
+				}
+		}
+		return false;
+	}
+
+	public static boolean isAnnotationTargetAllowed(BlockScope scope, TypeBinding annotationType, Binding recipient) {
+		long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
+		if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
+			return true;
+		}
+		return isAnnotationTargetAllowed(recipient, scope, annotationType, recipient.kind(), metaTagBits);
+	}
+
 	static boolean isAnnotationTargetAllowed(Annotation annotation, BlockScope scope, TypeBinding annotationType, int kind) {
+
 		long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
 		if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
 			// does not specify any target restriction - all locations supported in Java 7 and before are possible
@@ -1012,102 +1121,7 @@
 				}
 			}
 		}
-		switch (kind) {
-			case Binding.PACKAGE :
-				if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
-					return true;
-				else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) {
-					SourceTypeBinding sourceType = (SourceTypeBinding) annotation.recipient;
-					if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME))
-						return true;
-				}
-				break;
-			case Binding.TYPE_USE :
-				if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
-					// jsr 308
-					return true;
-				}
-				if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) {
-					// already reported as syntax error; don't report secondary problems
-					return true;
-				}
-				break;
-			case Binding.TYPE :
-			case Binding.GENERIC_TYPE :
-				if (((ReferenceBinding)annotation.recipient).isAnnotationType()) {
-					if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0)
-					return true;
-				} else if ((metaTagBits & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) {
-					return true;
-				} else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) {
-					if (CharOperation.equals(((ReferenceBinding) annotation.recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME))
-						return true;
-				}
-//{ObjectTeams: allow @Override for roles:
-				if (   (((ReferenceBinding)annotation.recipient).isRole())
-					&& (annotation.resolvedType.id == TypeIds.T_JavaLangOverride))
-					return true;
-//SH}
-				break;
-//{ObjectTeams: method mappings
-			// TODO(SH): should annotations for method mappings be controlled separately?
-			case Binding.BINDING :
-				if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
-					return true;
-				break;
-//SH}
-			case Binding.METHOD :
-				MethodBinding methodBinding = (MethodBinding) annotation.recipient;
-				if (methodBinding.isConstructor()) {
-					if ((metaTagBits & (TagBits.AnnotationForConstructor | TagBits.AnnotationForTypeUse)) != 0)
-						return true;
-				} else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) {
-					return true;
-				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
-					SourceTypeBinding sourceType = (SourceTypeBinding) methodBinding.declaringClass;
-					MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(methodBinding);
-					if (isTypeUseCompatible(methodDecl.returnType, scope)) {
-						return true;
-					}
-				}
-				break;
-			case Binding.FIELD :
-				if ((metaTagBits & TagBits.AnnotationForField) != 0) {
-					return true;
-				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
-					FieldBinding sourceField = (FieldBinding) annotation.recipient;
-					SourceTypeBinding sourceType = (SourceTypeBinding) sourceField.declaringClass;
-					FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
-					if (isTypeUseCompatible(fieldDeclaration.type, scope)) {
-						return true;
-					}
-				}
-				break;
-			case Binding.LOCAL :
-				LocalVariableBinding localVariableBinding = (LocalVariableBinding) annotation.recipient;
-				if ((localVariableBinding.tagBits & TagBits.IsArgument) != 0) {
-					if ((metaTagBits & TagBits.AnnotationForParameter) != 0) {
-						return true;
-					} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
-						if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
-							return true;
-						}
-					}
-				} else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) {
-					return true;
-				} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
-					if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
-						return true;
-					}
-				}
-				break;
-			case Binding.TYPE_PARAMETER : // jsr308
-				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196
-				if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
-					return true;
-				}
-		}
-		return false;
+		return isAnnotationTargetAllowed(annotation.recipient, scope, annotationType, kind, metaTagBits);
 	}
 
 	static void checkAnnotationTarget(Annotation annotation, BlockScope scope, ReferenceBinding annotationType, int kind, Binding recipient, long tagBitsToRevert) {
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 c6e5fea..b842bd3 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -30,6 +30,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 453483 - [compiler][null][loop] Improve null analysis for loops
+ *							Bug 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -194,6 +195,8 @@
 }
 
 public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if ((this.implicitConversion & TypeIds.BOXING) != 0)
+		return FlowInfo.NON_NULL;
 	return this.expression.nullStatus(flowInfo, flowContext);
 }
 
@@ -336,6 +339,6 @@
 	return this.lhs.localVariableBinding();
 }
 public boolean statementExpression() {
-	return true;
+	return ((this.bits & ASTNode.ParenthesizedMASK) == 0);
 }
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
index c42e780..4e740a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -15,6 +15,7 @@
  *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
  *								bug 383368 - [compiler][null] syntactic null analysis for field references
  *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *								Bug 440282 - [resource] Resource leak detection false negative with empty finally block
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -60,9 +61,11 @@
 			flowContext.expireNullCheckedFieldInfo();
 		}
 	}
-	if (this.explicitDeclarations > 0) {
-		// if block has its own scope analyze tracking vars now:
+	if (this.scope != currentScope) {
+		// if block is tracking any resources other than the enclosing 'currentScope', analyse them now:
 		this.scope.checkUnclosedCloseables(flowInfo, flowContext, null, null);
+	}
+	if (this.explicitDeclarations > 0) {
 		// cleanup assignment info for locals that are scoped to this block:
 		LocalVariableBinding[] locals = this.scope.locals;
 		if (locals != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index bd9b012..97a4a1d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -24,6 +24,7 @@
  *								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 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 415541 - [1.8][compiler] Type annotations in the body of static initializer get dropped
  *******************************************************************************/
@@ -591,6 +592,8 @@
 }
 
 public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if ((this.implicitConversion & TypeIds.BOXING) != 0)
+		return FlowInfo.NON_NULL;
 	return this.expression.nullStatus(flowInfo, flowContext);
 }
 
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 079a108..d285c6d 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -24,6 +24,7 @@
  *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
  *							Bug 418537 - [1.8][null] Fix null type annotation analysis for poly conditional expressions
  *							Bug 428352 - [1.8][compiler] Resolution errors don't always surface
+ *							Bug 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -418,6 +419,8 @@
 	}
 
 	public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		if ((this.implicitConversion & TypeIds.BOXING) != 0)
+			return FlowInfo.NON_NULL;
 		return this.nullStatus;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 6cf57e7..6ef6d1d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -24,6 +24,8 @@
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -379,6 +381,14 @@
 					if (CharOperation.equals(memberValuePairs[j].name, TypeConstants.OPTIONAL))
 						return memberValuePairs[j].value instanceof FalseLiteral;
 				}
+			} else if (annotation.resolvedType.id == TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired) {
+				MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+				if (memberValuePairs == Annotation.NoValuePairs)
+					return true;
+				for (int j = 0; j < memberValuePairs.length; j++) {
+					if (CharOperation.equals(memberValuePairs[j].name, TypeConstants.REQUIRED))
+						return memberValuePairs[j].value instanceof TrueLiteral;
+				}
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index 45b882b..1a1f787 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 GK Software AG and others.
+ * Copyright (c) 2011, 2015 GK Software AG 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
@@ -13,7 +13,9 @@
 package org.eclipse.jdt.internal.compiler.ast;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -33,6 +35,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
@@ -182,6 +185,8 @@
 					return local.closeTracker;
 				if (!isAnyCloseable(expression.resolvedType))
 					return null;
+				if ((local.tagBits & TagBits.IsResource) != 0)
+					return null;
 				// tracking var doesn't yet exist. This happens in finally block
 				// which is analyzed before the corresponding try block
 				Statement location = local.declaration;
@@ -237,6 +242,8 @@
 			ConditionalExpression conditional = (ConditionalExpression) location;
 			return containsAllocation(conditional.valueIfTrue) || containsAllocation(conditional.valueIfFalse);
 		}
+		if (location instanceof CastExpression)
+			return containsAllocation(((CastExpression) location).expression);
 		return false;
 	}
 
@@ -246,6 +253,8 @@
 			preConnectTrackerAcrossAssignment(location, local, flowInfo, (AllocationExpression) expression, closeTracker);
 		} else if (expression instanceof ConditionalExpression) {
 			preConnectTrackerAcrossAssignment(location, local, flowInfo, (ConditionalExpression) expression, closeTracker);
+		} else if (expression instanceof CastExpression) {
+			preConnectTrackerAcrossAssignment(location, local, ((CastExpression) expression).expression, flowInfo);
 		}
 	}
 
@@ -273,7 +282,7 @@
 		if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable)) {
 			// remove unnecessary attempts (closeable is not relevant)
 			if (allocation.closeTracker != null) {
-				scope.removeTrackingVar(allocation.closeTracker);
+				allocation.closeTracker.withdraw();
 				allocation.closeTracker = null;
 			}
 		} else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) {
@@ -328,7 +337,7 @@
 			if (isWrapper) {
 				// remove unnecessary attempts (wrapper has no relevant inner)
 				if (allocation.closeTracker != null) {
-					scope.removeTrackingVar(allocation.closeTracker);
+					allocation.closeTracker.withdraw();
 					allocation.closeTracker = null;
 				}
 			} else {
@@ -353,7 +362,7 @@
 	}
 
 	private static FakedTrackingVariable pick(FakedTrackingVariable tracker1, FakedTrackingVariable tracker2, BlockScope scope) {
-		scope.removeTrackingVar(tracker2);
+		tracker2.withdraw();
 		return tracker1;
 	}
 
@@ -600,14 +609,14 @@
 		if (expression instanceof AllocationExpression) {
 			FakedTrackingVariable tracker = ((AllocationExpression) expression).closeTracker;
 			if (tracker != null && tracker.originalBinding == null) {
-				currentScope.removeTrackingVar(tracker);
+				tracker.withdraw();
 				((AllocationExpression) expression).closeTracker = null;
 			}
 		} else {
 			// assignment passing a local into a field?
 			LocalVariableBinding local = expression.localVariableBinding();
 			if (local != null && local.closeTracker != null && ((lhsBits & Binding.FIELD) != 0))
-				currentScope.removeTrackingVar(local.closeTracker); // TODO: may want to use local.closeTracker.markPassedToOutside(..,true)
+				local.closeTracker.withdraw(); // TODO: may want to use local.closeTracker.markPassedToOutside(..,true)
 		}
 	}
 
@@ -686,7 +695,7 @@
 				int finallyStatus = currentScope.finallyInfo.nullStatus(local);
 				if (finallyStatus == FlowInfo.NON_NULL)
 					return finallyStatus;
-				if (finallyStatus != FlowInfo.NULL) // neither is NON_NULL, but not both are NULL => call it POTENTIALLY_NULL
+				if (finallyStatus != FlowInfo.NULL && currentScope.finallyInfo.hasNullInfoFor(local)) // neither is NON_NULL, but not both are NULL => call it POTENTIALLY_NULL
 					status = FlowInfo.POTENTIALLY_NULL;
 			}
 			if (currentScope != outerScope && currentScope.parent instanceof BlockScope)
@@ -701,7 +710,7 @@
 		do {
 			flowInfo.markAsDefinitelyNonNull(current.binding);
 			current.globalClosingState |= CLOSE_SEEN;
-			flowContext.markFinallyNullStatus(this.binding, FlowInfo.NON_NULL);
+			flowContext.markFinallyNullStatus(current.binding, FlowInfo.NON_NULL);
 			current = current.innerTracker;
 		} while (current != null);
 	}
@@ -739,44 +748,100 @@
 		return flowInfo;
 	}
 
-	/** 
-	 * Pick tracking variables from 'varsOfScope' to establish a proper order of processing:
-	 * As much as possible pick wrapper resources before their inner resources.
-	 * Also consider cases of wrappers and their inners being declared at different scopes.
+	/**
+	 * Iterator for a set of FakedTrackingVariable, which dispenses the elements 
+	 * according to the priorities defined by enum {@link Stage}.
+	 * Resources whose outer is owned by an enclosing scope are never answered,
+	 * unless we are analysing on behalf of an exit (return/throw).
 	 */
-	public static FakedTrackingVariable pickVarForReporting(Set varsOfScope, BlockScope scope, boolean atExit) {
-		if (varsOfScope.isEmpty()) return null;
-		FakedTrackingVariable trackingVar = (FakedTrackingVariable) varsOfScope.iterator().next();
-		while (trackingVar.outerTracker != null) {
-			// resource is wrapped, is wrapper defined in this scope?
-			if (varsOfScope.contains(trackingVar.outerTracker)) {
-				// resource from same scope, travel up the wrapper chain
-				trackingVar = trackingVar.outerTracker;
-			} else if (atExit) {
-				// at an exit point we report against inner despite a wrapper that may/may not be closed later
-				break;
-			} else {
-				BlockScope outerTrackerScope = trackingVar.outerTracker.binding.declaringScope;
-				if (outerTrackerScope == scope) {
-					// outerTracker is from same scope and already processed -> pick trackingVar now
-					break;
-				} else {
-					// outer resource is from other (outer?) scope
-					Scope currentScope = scope;
-					while ((currentScope = currentScope.parent) instanceof BlockScope) {
-						if (outerTrackerScope == currentScope) {
-							// at end of block pass responsibility for inner resource to outer scope holding a wrapper
-							varsOfScope.remove(trackingVar); // drop this one
-							// pick a next candidate:
-							return pickVarForReporting(varsOfScope, scope, atExit);
+	public static class IteratorForReporting implements Iterator<FakedTrackingVariable> {
+
+		private final Set<FakedTrackingVariable> varSet;
+		private final Scope scope;
+		private final boolean atExit;
+
+		private Stage stage;
+		private Iterator<FakedTrackingVariable> iterator;
+		private FakedTrackingVariable next;
+		
+		enum Stage {
+			/** 1. prio: all top-level resources, ie., resources with no outer. */
+			OuterLess,
+			/** 2. prio: resources whose outer has already been processed (element of the same varSet). */
+			InnerOfProcessed,
+			/** 3. prio: resources whose outer is not owned by any enclosing scope. */
+			InnerOfNotEnclosing,
+			/** 4. prio: when analysing on behalf of an exit point: anything not picked before. */
+			AtExit
+		}
+
+		public IteratorForReporting(List<FakedTrackingVariable> variables, Scope scope, boolean atExit) {
+			this.varSet = new HashSet<>(variables);
+			this.scope = scope;
+			this.atExit = atExit;
+			setUpForStage(Stage.OuterLess);
+		}
+		@Override
+		public boolean hasNext() {
+			FakedTrackingVariable trackingVar;
+			switch (this.stage) {
+				case OuterLess:
+					while (this.iterator.hasNext()) {
+						trackingVar = this.iterator.next();
+						if (trackingVar.outerTracker == null)
+							return found(trackingVar);
+					}
+					setUpForStage(Stage.InnerOfProcessed);
+					//$FALL-THROUGH$
+				case InnerOfProcessed:
+					while (this.iterator.hasNext()) {
+						trackingVar = this.iterator.next();
+						FakedTrackingVariable outer = trackingVar.outerTracker;
+						if (outer.binding.declaringScope == this.scope && !this.varSet.contains(outer))
+							return found(trackingVar);
+					}
+					setUpForStage(Stage.InnerOfNotEnclosing);
+					//$FALL-THROUGH$
+				case InnerOfNotEnclosing:
+					searchAlien: while (this.iterator.hasNext()) {
+						trackingVar = this.iterator.next();
+						FakedTrackingVariable outer = trackingVar.outerTracker;
+						if (!this.varSet.contains(outer)) {
+							Scope outerTrackerScope = outer.binding.declaringScope;
+							Scope currentScope = this.scope;
+							while ((currentScope = currentScope.parent) instanceof BlockScope) {
+								if (outerTrackerScope == currentScope)
+									break searchAlien;
+							}
+							return found(trackingVar);
 						}
 					}
-					break; // not parent owned -> pick this var
-				}
+					setUpForStage(Stage.AtExit);
+					//$FALL-THROUGH$
+				case AtExit:
+					if (this.atExit && this.iterator.hasNext())
+						return found(this.iterator.next());
+					return false;
+				default: throw new IllegalStateException("Unexpected Stage "+this.stage); //$NON-NLS-1$
 			}
 		}
-		varsOfScope.remove(trackingVar);
-		return trackingVar;
+		private boolean found(FakedTrackingVariable trackingVar) {
+			this.iterator.remove();
+			this.next = trackingVar;
+			return true;
+		}
+		private void setUpForStage(Stage nextStage) {
+			this.iterator = this.varSet.iterator();
+			this.stage = nextStage;
+		}
+		@Override
+		public FakedTrackingVariable next() {
+			return this.next;
+		}
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
 	}
 
 	/**
@@ -824,6 +889,11 @@
 		return false;
 	}
 
+	public void withdraw() {
+		// must unregister at the declaringScope, note that twr resources are owned by the scope enclosing the twr
+		this.binding.declaringScope.removeTrackingVar(this);
+	}
+
 	public void recordErrorLocation(ASTNode location, int nullStatus) {
 		if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
 			return;
@@ -833,14 +903,20 @@
 		this.recordedLocations.put(location, new Integer(nullStatus));
 	}
 
-	public boolean reportRecordedErrors(Scope scope, int mergedStatus) {
+	public boolean reportRecordedErrors(Scope scope, int mergedStatus, boolean atDeadEnd) {
 		FakedTrackingVariable current = this;
 		while (current.globalClosingState == 0) {
 			current = current.innerTracker;
 			if (current == null) {
 				// no relevant state found -> report:
-				reportError(scope.problemReporter(), null, mergedStatus);
-				return true;
+				if (atDeadEnd && neverClosedAtLocations())
+					mergedStatus = FlowInfo.NULL;
+				if ((mergedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) {
+					reportError(scope.problemReporter(), null, mergedStatus);
+					return true;
+				} else {
+					break;
+				}
 			}
 		}
 		boolean hasReported = false;
@@ -863,6 +939,15 @@
 		return hasReported;
 	}
 	
+	private boolean neverClosedAtLocations() {
+		if (this.recordedLocations != null) {
+			for (Object value : this.recordedLocations.values())
+				if (!value.equals(FlowInfo.NULL))
+					return false;
+		}
+		return true;
+	}
+
 	public int reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
 		if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
 			return 0; // TODO: should we still propagate some flags??
@@ -903,14 +988,6 @@
 		}
 	}
 
-	public void resetReportingBits() {
-		FakedTrackingVariable current = this;
-		do {
-			current.globalClosingState &= ~(REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK);
-			current = current.innerTracker;
-		} while (current != null);
-	}
-
 	public String nameForReporting(ASTNode location, ReferenceContext referenceContext) {
 		if (this.name == UNASSIGNED_CLOSEABLE_NAME) {
 			if (location != null && referenceContext != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
index 3796302..3e72271 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
@@ -1,15 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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:
+ *Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
@@ -24,6 +26,8 @@
 	public int bodyStart;
 	public int bodyEnd;
 
+	private MethodBinding methodBinding;
+
 	public Initializer(Block block, int modifiers) {
 		this.block = block;
 		this.modifiers = modifiers;
@@ -126,6 +130,17 @@
 		}
 	}
 
+	/** Method used only by DOM to support bindings of initializers. */
+	public MethodBinding getMethodBinding() {
+		if (this.methodBinding == null) {
+			Scope scope = this.block.scope;
+			this.methodBinding = isStatic() 
+					? new MethodBinding(ClassFileConstants.AccStatic, CharOperation.NO_CHAR, TypeBinding.VOID, Binding.NO_PARAMETERS, Binding.NO_EXCEPTIONS, scope.enclosingSourceType())
+					: new MethodBinding(0, CharOperation.NO_CHAR, TypeBinding.VOID, Binding.NO_PARAMETERS, Binding.NO_EXCEPTIONS, scope.enclosingSourceType());
+		}
+		return this.methodBinding;
+	}
+
 	public void traverse(ASTVisitor visitor, MethodScope scope) {
 		if (visitor.visit(this, scope)) {
 			if (this.block != null) this.block.traverse(visitor, scope);
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 fd8c73f..1d7dbf4 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
@@ -52,6 +52,7 @@
  *								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
  *								Bug 456487 - [1.8][null] @Nullable type variant of @NonNull-constrained type parameter causes grief
+ *								Bug 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *     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
@@ -736,6 +737,8 @@
 // SH}
 }
 public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if ((this.implicitConversion & TypeIds.BOXING) != 0)
+		return FlowInfo.NON_NULL;
 	if (this.binding.isValidBinding()) {
 		// try to retrieve null status of this message send from an annotation of the called method:
 		long tagBits = this.binding.tagBits;
@@ -1632,7 +1635,7 @@
 	visitor.endVisit(this, blockScope);
 }
 public boolean statementExpression() {
-	return true;
+	return ((this.bits & ASTNode.ParenthesizedMASK) == 0);
 }
 public boolean receiverIsImplicitThis() {
 	return this.receiver.isImplicitThis();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index c090aaa..31ebefe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -53,6 +53,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ImplicitNullAnnotationVerifier;
 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
@@ -64,6 +65,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ConstructorDecapsulationException;
 import org.eclipse.objectteams.otdt.internal.core.compiler.ast.OTQualifiedAllocationExpression;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
@@ -361,9 +363,18 @@
 		TypeBinding result = resolveTypeForQualifiedAllocationExpression(scope);
 		if (result != null && !result.isPolyType() && this.binding != null) {
 			final CompilerOptions compilerOptions = scope.compilerOptions();
-			if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
-				new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
-						.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+			if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+				if ((this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
+					new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
+							.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+				}
+				if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+					if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
+						TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
+						for (int i = 0; i < this.typeArguments.length; i++)
+							this.typeArguments[i].checkNullConstraints(scope, typeVariables, i);
+					}
+				}
 			}
 		}
 		return result;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
index 96ebe04..281de66 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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 392384 - [1.8][compiler][null] Restore nullness info from type annotations in class files
  *								Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis 
  *								Bug 411964 - [1.8][null] leverage null type annotation in foreach statement
+ *								Bug 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -157,6 +158,8 @@
 }
 
 public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if ((this.implicitConversion & TypeIds.BOXING) != 0)
+		return FlowInfo.NON_NULL;
 	FieldBinding fieldBinding = lastFieldBinding();
 	if (fieldBinding != null) {
 		if (fieldBinding.isNonNull() || flowContext.isNullcheckedFieldAccess(this)) {
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 a7adb88..a4b0a2c 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
@@ -34,6 +34,7 @@
  *							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
  *							Bug 448709 - [1.8][null] ensure we don't infer types that violate null constraints on a type parameter's bound
+ *							Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
  *        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)
  *******************************************************************************/
@@ -57,6 +58,7 @@
 import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
+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;
@@ -576,6 +578,7 @@
         		scope.problemReporter().constructedArrayIncompatible(this, lhsType, this.descriptor.returnType);
         		return this.resolvedType = null;
         	}
+            checkNullAnnotations(scope);
         	return this.resolvedType;
         }
 
@@ -697,44 +700,7 @@
         	}
         	scope.problemReporter().unhandledException(methodExceptions[i], this);
         }
-        if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
-        	if (this.expectedType == null || !NullAnnotationMatching.hasContradictions(this.expectedType)) { // otherwise assume it has been reported and we can do nothing here
-	        	// TODO: simplify by using this.freeParameters?
-	        	int len;
-	        	int expectedlen = this.binding.parameters.length;
-	        	int providedLen = this.descriptor.parameters.length;
-	        	if (this.receiverPrecedesParameters)
-	        		providedLen--; // one parameter is 'consumed' as the receiver
-	        	boolean isVarArgs = false;
-	        	if (this.binding.isVarargs()) {
-	        		isVarArgs = (providedLen == expectedlen)
-						? !this.descriptor.parameters[expectedlen-1].isCompatibleWith(this.binding.parameters[expectedlen-1])
-						: true;
-	        		len = providedLen; // binding parameters will be padded from InferenceContext18.getParameter()
-	        	} else {
-	        		len = Math.min(expectedlen, providedLen);
-	        	}
-	    		for (int i = 0; i < len; i++) {
-	    			TypeBinding descriptorParameter = this.descriptor.parameters[i + (this.receiverPrecedesParameters ? 1 : 0)];
-	    			TypeBinding bindingParameter = InferenceContext18.getParameter(this.binding.parameters, i, isVarArgs);
-	    			NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(bindingParameter, descriptorParameter, FlowInfo.UNKNOWN);
-	    			if (annotationStatus.isAnyMismatch()) {
-	    				// immediate reporting:
-	    				scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, bindingParameter, descriptorParameter, this.descriptor, i, annotationStatus);
-	    			}
-	    		}
-	        	if (!this.binding.isConstructor() && (this.descriptor.returnType.tagBits & TagBits.AnnotationNonNull) != 0) {
-	        		// since constructors never return null we don't have to check those anyway.
-	        		if ((this.binding.returnType.tagBits & TagBits.AnnotationNonNull) == 0) {
-	        			char[][] providedAnnotationName = ((this.binding.returnType.tagBits & TagBits.AnnotationNullable) != 0) ?
-	        					scope.environment().getNullableAnnotationName() : null;
-	        			scope.problemReporter().illegalReturnRedefinition(this, this.descriptor,
-	        					scope.environment().getNonNullAnnotationName(),
-	        					providedAnnotationName, this.binding.returnType);
-	        		}
-	        	}
-        	}
-        }
+        checkNullAnnotations(scope);
         this.freeParameters = null; // not used after method lookup
         
     	if (checkInvocationArguments(scope, null, this.receiverType, this.binding, null, descriptorParameters, false, this))
@@ -771,6 +737,45 @@
     	return this.resolvedType; // Phew !
 	}
 
+	protected void checkNullAnnotations(BlockScope scope) {
+		if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+        	if (this.expectedType == null || !NullAnnotationMatching.hasContradictions(this.expectedType)) { // otherwise assume it has been reported and we can do nothing here
+	        	// TODO: simplify by using this.freeParameters?
+	        	int len;
+	        	int expectedlen = this.binding.parameters.length;
+	        	int providedLen = this.descriptor.parameters.length;
+	        	if (this.receiverPrecedesParameters)
+	        		providedLen--; // one parameter is 'consumed' as the receiver
+	        	boolean isVarArgs = false;
+	        	if (this.binding.isVarargs()) {
+	        		isVarArgs = (providedLen == expectedlen)
+						? !this.descriptor.parameters[expectedlen-1].isCompatibleWith(this.binding.parameters[expectedlen-1])
+						: true;
+	        		len = providedLen; // binding parameters will be padded from InferenceContext18.getParameter()
+	        	} else {
+	        		len = Math.min(expectedlen, providedLen);
+	        	}
+	    		for (int i = 0; i < len; i++) {
+	    			TypeBinding descriptorParameter = this.descriptor.parameters[i + (this.receiverPrecedesParameters ? 1 : 0)];
+	    			TypeBinding bindingParameter = InferenceContext18.getParameter(this.binding.parameters, i, isVarArgs);
+	    			NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(bindingParameter, descriptorParameter, FlowInfo.UNKNOWN);
+	    			if (annotationStatus.isAnyMismatch()) {
+	    				// immediate reporting:
+	    				scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, bindingParameter, descriptorParameter, this.descriptor, i, annotationStatus);
+	    			}
+	    		}
+	    		TypeBinding returnType = this.binding.returnType;
+	    		if (this.binding.isConstructor() || this.binding == scope.environment().arrayClone) {
+	    			returnType = scope.environment().createAnnotatedType(this.receiverType, new AnnotationBinding[]{ scope.environment().getNonNullAnnotation() });
+	    		}
+	    		NullAnnotationMatching annotationStatus = NullAnnotationMatching.analyse(this.descriptor.returnType, returnType, FlowInfo.UNKNOWN);
+	        	if (annotationStatus.isAnyMismatch()) {
+        			scope.problemReporter().illegalReturnRedefinition(this, this.descriptor, annotationStatus.isUnchecked(), returnType);
+	        	}
+        	}
+        }
+	}
+
 	private TypeBinding[] descriptorParametersAsArgumentExpressions() {
 		
 		if (this.descriptor == null || this.descriptor.parameters == null || this.descriptor.parameters.length == 0)
@@ -950,7 +955,15 @@
 
 	@Override
 	public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope) {
-		
+
+        final boolean isConstructorRef = isConstructorReference();
+		if (isConstructorRef && this.receiverType.isArrayType()) {
+			final TypeBinding leafComponentType = this.receiverType.leafComponentType();
+			if (!leafComponentType.isReifiable()) {
+				return false;
+			}
+		}
+
 		// We get here only when the reference expression is NOT pertinent to applicability.
 		if (!super.isPertinentToApplicability(targetType, null))
 			return true;
@@ -980,14 +993,12 @@
 		}
 		
 		// 15.13.1
-        final boolean isMethodReference = isMethodReference();
         this.freeParameters = descriptorParameters;
         this.checkingPotentialCompatibility = true;
         try {
-        	MethodBinding compileTimeDeclaration = 
-        			this.exactMethodBinding != null ? this.exactMethodBinding :
-        							isMethodReference ? scope.getMethod(this.receiverType, this.selector, descriptorParameters, this) :
-        												scope.getConstructor((ReferenceBinding) this.receiverType, descriptorParameters, this);
+			MethodBinding compileTimeDeclaration = this.exactMethodBinding != null ? this.exactMethodBinding : isConstructorRef
+							? scope.getConstructor((ReferenceBinding) this.receiverType, descriptorParameters, this)
+							: scope.getMethod(this.receiverType, this.selector, descriptorParameters, this);
 
         	if (compileTimeDeclaration != null && compileTimeDeclaration.isValidBinding()) // we have the mSMB.
         		this.potentialMethods = new MethodBinding [] { compileTimeDeclaration };
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 bd01f40..89e198f 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -324,6 +324,9 @@
 	if (this.expression != null) {
 		this.expression.setExpressionContext(ASSIGNMENT_CONTEXT);
 		this.expression.setExpectedType(methodType);
+		if (lambda != null && lambda.argumentsTypeElided() && this.expression instanceof CastExpression) {
+			this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
+		}
 	}
 	
 	if (methodType == TypeBinding.VOID) {
@@ -370,9 +373,14 @@
 		if (expressionType.needsUncheckedConversion(methodType)) {
 		    scope.problemReporter().unsafeTypeConversion(this.expression, expressionType, methodType);
 		}
-		if (this.expression instanceof CastExpression
-				&& (this.expression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
-			CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
+		if (this.expression instanceof CastExpression) {
+			if ((this.expression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
+				CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
+			} else if (lambda != null && lambda.argumentsTypeElided() && (this.expression.bits & ASTNode.UnnecessaryCast) != 0) {
+				if (TypeBinding.equalsEquals(((CastExpression)this.expression).expression.resolvedType, methodType)) {
+					scope.problemReporter().unnecessaryCast((CastExpression)this.expression);
+				}
+			}
 		}
 		return;
 	} else if (isBoxingCompatible(expressionType, methodType, this.expression, scope)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index db38143..1950dde 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -16,8 +16,9 @@
  *								bug 383368 - [compiler][null] syntactic null analysis for field references
  *								Bug 412203 - [compiler] Internal compiler error: java.lang.IllegalArgumentException: info cannot be null
  *								Bug 458396 - NPE in CodeStream.invoke()
+ *								Bug 407414 - [compiler][null] Incorrect warning on a primitive type being null
  *     Jesper S Moller - <jesper@selskabet.org>   - Contributions for 
- *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *     							bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
  *								bug 378674 - "The method can be declared as static" is wrong
  *								bug 404657 - [1.8][compiler] Analysis for effectively final variables fails to consider loops
  *******************************************************************************/
@@ -901,6 +902,8 @@
 }
 
 public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if ((this.implicitConversion & TypeIds.BOXING) != 0)
+		return FlowInfo.NON_NULL;
 	LocalVariableBinding local = localVariableBinding();
 	if (local != null) {
 		return flowInfo.nullStatus(local);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 65c07a7..6b1a1ec 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -22,6 +22,8 @@
  *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
  *								bug 384380 - False positive on a ?? Potential null pointer access ?? after a continue
  *								Bug 415790 - [compiler][resource]Incorrect potential resource leak warning in for loop with close in try/catch
+ *								Bug 371614 - [compiler][resource] Wrong "resource leak" problem on return/throw inside while loop
+ *								Bug 444964 - [1.7+][resource] False resource leak warning (try-with-resources for ByteArrayOutputStream - return inside for loop)
  *     Jesper Steen Moller - Contributions for
  *								bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
  *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
@@ -165,8 +167,8 @@
 			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
 			if (resourceBinding.closeTracker != null) {
 				// this was false alarm, we don't need to track the resource
-				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
-				// keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block
+				resourceBinding.closeTracker.withdraw();
+				resourceBinding.closeTracker = null;
 			}
 			MethodBinding closeMethod = findCloseMethod(resource, resourceBinding);
 			if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
@@ -279,7 +281,7 @@
 			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
 			if (resourceBinding.closeTracker != null) {
 				// this was false alarm, we don't need to track the resource
-				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
+				resourceBinding.closeTracker.withdraw();
 				// keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block
 			}
 			MethodBinding closeMethod = findCloseMethod(resource, resourceBinding);
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 27b11b3..87e1254 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, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -11,6 +11,7 @@
  *								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
+ *								Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -83,6 +84,7 @@
 	UnconditionalFlowInfo unconditionalCopy = flowInfo.unconditionalCopy();
 	unconditionalCopy.iNBit = -1L;
 	unconditionalCopy.iNNBit = -1L;
+	unconditionalCopy.tagBits |= FlowInfo.UNROOTED;
 	this.initsOnFinally = unconditionalCopy;
 }
 ExceptionHandlingFlowContext(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 7cecbc2..f1e5d43 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -14,6 +14,7 @@
  *     							bug 332637 - Dead Code detection removing code that isn't dead
  *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
  *								Bug 411964 - [1.8][null] leverage null type annotation in foreach statement
+ *								Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -61,6 +62,8 @@
 	public final static int POTENTIALLY_NULL = 16;
 	public final static int POTENTIALLY_NON_NULL = 32;
 
+	public final static int UNROOTED = 64; // marks a flowInfo that may be appended to another flowInfo (accepting incoming nulls/nonnulls, see UFI.iNBit/iNNBit).
+
 	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
 	static {
 		DEAD_END = new UnconditionalFlowInfo();
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 210650c..3b49f17 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, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -23,6 +23,7 @@
  *								Bug 455557 - [jdt] NPE LoopingFlowContext.recordNullReference
  *								Bug 455723 - Nonnull argument not correctly inferred in loop
  *								Bug 415790 - [compiler][resource]Incorrect potential resource leak warning in for loop with close in try/catch
+ *								Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
  *     Jesper S Moller - contributions for
  *								bug 404657 - [1.8][compiler] Analysis for effectively final variables fails to consider loops
  *******************************************************************************/
@@ -417,7 +418,7 @@
 							}
 							nullStatus = closeTracker.findMostSpecificStatus(flowInfo, scope, null);
 							closeTracker.recordErrorLocation(this.nullReferences[i], nullStatus);
-							closeTracker.reportRecordedErrors(scope, nullStatus);
+							closeTracker.reportRecordedErrors(scope, nullStatus, flowInfo.reachMode() != FlowInfo.REACHABLE);
 							this.nullReferences[i] = null;
 							continue;
 						}
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 8b68fd8..4e34ec5 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
@@ -21,6 +21,7 @@
  *							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
+ *							Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
@@ -440,10 +441,7 @@
 	else if (otherInits.extra != null) {
 		// no storage here, but other has extra storage.
 		int otherLength = otherInits.extra[0].length;
-		this.extra = new long[extraLength][];
-		for (int j = 0; j < extraLength; j++) {
-			this.extra[j] = new long[otherLength];
-		}
+		createExtraSpace(otherLength);
 		System.arraycopy(otherInits.extra[1], 0, this.extra[1], 0,
 			otherLength);
 	}
@@ -528,10 +526,7 @@
 	if (otherInits.extra != null) {
 		int mergeLimit = 0, copyLimit = otherInits.extra[0].length;
 		if (this.extra == null) {
-			this.extra = new long[extraLength][];
-			for (int j = 0; j < extraLength; j++) {
-				this.extra[j] = new long[copyLimit];
-			}
+			createExtraSpace(copyLimit);
 			if (COVERAGE_TEST_FLAG) {
 				if (CoverageTestId == 11) {
 					throw new AssertionFailedException("COVERAGE 11"); //$NON-NLS-1$
@@ -1188,10 +1183,7 @@
 			int vectorIndex = (position / BitCacheSize) - 1;
 			if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 				if (COVERAGE_TEST_FLAG) {
 					if (CoverageTestId == 16) {
 						throw new AssertionFailedException("COVERAGE 16"); //$NON-NLS-1$
@@ -1287,10 +1279,7 @@
 			mask = 1L << (position % BitCacheSize);
 			if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length ];
-				}
+				createExtraSpace(length);
 				if (COVERAGE_TEST_FLAG) {
 					if(CoverageTestId == 20) {
 						throw new AssertionFailedException("COVERAGE 20"); //$NON-NLS-1$
@@ -1355,10 +1344,7 @@
 			int vectorIndex = (position / BitCacheSize) - 1;
 			if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 			}
 			else {
 				int oldLength; // might need to grow the arrays
@@ -1416,10 +1402,7 @@
     		int vectorIndex = (position / BitCacheSize) - 1;
     		if (this.extra == null) {
     			int length = vectorIndex + 1;
-    			this.extra = new long[extraLength][];
-    			for (int j = 0; j < extraLength; j++) {
-    				this.extra[j] = new long[length];
-    			}
+    			createExtraSpace(length);
     		}
     		else {
     			int oldLength; // might need to grow the arrays
@@ -1476,10 +1459,7 @@
     		int vectorIndex = (position / BitCacheSize) - 1;
     		if (this.extra == null) {
     			int length = vectorIndex + 1;
-    			this.extra = new long[extraLength][];
-    			for (int j = 0; j < extraLength; j++) {
-    				this.extra[j] = new long[length];
-    			}
+    			createExtraSpace(length);
     		}
     		else {
     			int oldLength; // might need to grow the arrays
@@ -1543,10 +1523,7 @@
 			int vectorIndex = (position / BitCacheSize) - 1;
 			if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 			}
 			else {
 				int oldLength; // might need to grow the arrays
@@ -1632,10 +1609,7 @@
     		int vectorIndex = (position / BitCacheSize) - 1;
     		if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 			}
 			else {
 				int oldLength; // might need to grow the arrays
@@ -1682,10 +1656,7 @@
     		int vectorIndex = (position / BitCacheSize) - 1;
     		if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 			}
 			else {
 				int oldLength; // might need to grow the arrays
@@ -1732,10 +1703,7 @@
     		int vectorIndex  = (position / BitCacheSize) - 1;
     		if (this.extra == null) {
 				int length = vectorIndex + 1;
-				this.extra = new long[extraLength][];
-				for (int j = 0; j < extraLength; j++) {
-					this.extra[j] = new long[length];
-				}
+				createExtraSpace(length);
 			}
 			else {
 				int oldLength; // might need to grow the arrays
@@ -2055,6 +2023,7 @@
 	copy.iNBit = -1L;
 	copy.iNNBit = -1L;
 	copy.tagBits = this.tagBits & ~NULL_FLAG_MASK;
+	copy.tagBits |= UNROOTED;
 	copy.maxFieldCount = this.maxFieldCount;
 	if (this.extra != null) {
 		int length;
@@ -2215,9 +2184,7 @@
 		}
 	}
 	else if (vectorIndex >= 0) {
-		for (int j = 0; j < extraLength; j++) {
-			copy.extra[j] = new long[length];
-		}
+		copy.createExtraSpace(length);
 	}
 	if (vectorIndex >= 0) {
 		mask = ~((1L << (limit % BitCacheSize))-1);
@@ -2261,5 +2228,16 @@
 		}
 	}
 }
+
+private void createExtraSpace(int length) {
+	this.extra = new long[extraLength][];
+	for (int j = 0; j < extraLength; j++) {
+		this.extra[j] = new long[length];
+	}
+	if ((this.tagBits & UNROOTED) != 0) {
+		Arrays.fill(this.extra[IN], -1L);
+		Arrays.fill(this.extra[INN], -1L);
+	}
+}
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
index a3bf693..29f4311 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -131,14 +131,14 @@
 	public abstract int kind();
 	/*
 	 * Computes a key that uniquely identifies this binding.
-	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
+	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding, a LocalVariableBinding or a PackageBinding (i.e. an ImportBinding).
 	 */
 	public char[] computeUniqueKey() {
 		return computeUniqueKey(true/*leaf*/);
 	}
 	/*
 	 * Computes a key that uniquely identifies this binding. Optionally include access flags.
-	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
+	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding, a LocalVariableBinding or a PackageBinding (i.e. an ImportBinding)
 	 */
 	public char[] computeUniqueKey(boolean isLeaf) {
 		return null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 68b1712..297d3f4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -20,6 +20,10 @@
  *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
  *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
  *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
+ *								Bug 371614 - [compiler][resource] Wrong "resource leak" problem on return/throw inside while loop
+ *								Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
+ *								Bug 444964 - [1.7+][resource] False resource leak warning (try-with-resources for ByteArrayOutputStream - return inside for loop)
+ *								Bug 396575 - [compiler][resources] Incorrect Errors/Warnings check for potential resource leak when surrounding with try-catch
  *     Jesper S Moller <jesper@selskabet.org> - Contributions for
  *								bug 378674 - "The method can be declared as static" is wrong
  *     Keigo Imai - Contribution for  bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class
@@ -27,10 +31,9 @@
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.*;
@@ -1212,7 +1215,7 @@
 /** When are no longer interested in this tracking variable - remove it. */
 public void removeTrackingVar(FakedTrackingVariable trackingVariable) {
 	if (trackingVariable.innerTracker != null) {
-		removeTrackingVar(trackingVariable.innerTracker);
+		trackingVariable.innerTracker.withdraw();
 		trackingVariable.innerTracker = null;
 	}
 	if (this.trackingVariables != null)
@@ -1242,10 +1245,10 @@
 	FakedTrackingVariable returnVar = (location instanceof ReturnStatement) ?
 			FakedTrackingVariable.getCloseTrackingVariable(((ReturnStatement)location).expression, flowInfo, flowContext) : null;
 
-	Set varSet = new HashSet(this.trackingVariables);
-	FakedTrackingVariable trackingVar;
-	// pick one outer-most variable from the set at a time
-	while ((trackingVar = FakedTrackingVariable.pickVarForReporting(varSet, this, location != null)) != null) {
+	// iterate variables according to the priorities defined in FakedTrackingVariable.IteratorForReporting.Stage
+	Iterator<FakedTrackingVariable> iterator = new FakedTrackingVariable.IteratorForReporting(this.trackingVariables, this, location != null);
+	while (iterator.hasNext()) {
+		FakedTrackingVariable trackingVar = iterator.next();
 
 		if (returnVar != null && trackingVar.isResourceBeingReturned(returnVar)) {
 			continue;
@@ -1270,7 +1273,7 @@
 		if (location == null) // at end of block and not definitely unclosed
 		{
 			// problems at specific locations: medium priority
-			if (trackingVar.reportRecordedErrors(this, status)) // ... report previously recorded errors
+			if (trackingVar.reportRecordedErrors(this, status, flowInfo.reachMode() != FlowInfo.REACHABLE)) // ... report previously recorded errors
 				continue;
 		} 
 		if (status == FlowInfo.POTENTIALLY_NULL) {
@@ -1287,12 +1290,6 @@
 		for (int i=0; i<this.localIndex; i++)
 			this.locals[i].closeTracker = null;		
 		this.trackingVariables = null;
-	} else {
-		int size = this.trackingVariables.size();
-		for (int i=0; i<size; i++) {
-			FakedTrackingVariable tracker = (FakedTrackingVariable) this.trackingVariables.get(i);
-			tracker.resetReportingBits();
-		}
 	}
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
index 5e987f8..4ccb266 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -14,6 +14,7 @@
  *								Bug 441797 - [1.8] synchronize type annotations on capture and its wildcard
  *								Bug 456497 - [1.8][null] during inference nullness from target type is lost against weaker hint from applicability analysis
  *								Bug 456924 - StackOverflowError during compilation
+ *								Bug 462790 - [null] NPE in Expression.computeConversion()
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -49,6 +50,7 @@
 		this.end = end;
 		this.captureID = captureID;
 		this.tagBits |= TagBits.HasCapturedWildcard;
+		this.cud = cud;
 		if (wildcard.hasTypeAnnotations()) {
 			// register an unannoted version before adding the annotated wildcard:
 			CaptureBinding unannotated = (CaptureBinding) clone(null);
@@ -64,7 +66,6 @@
 		} else {			
 			computeId(this.environment);
 		}
-		this.cud = cud;
 	}
 	
 	// for subclass CaptureBinding18
@@ -440,6 +441,26 @@
 		return this.wildcard;
 	}
 
+	/*
+	 * CaptureBinding needs even more propagation, because we are creating a naked type
+	 * (during CaptureBinding(WildcardBinding,ReferenceBinding,int,int,ASTNode,int)
+	 * that has no firstBound / superclass / superInterfaces set.
+	 */
+	@Override
+	protected TypeBinding[] getDerivedTypesForDeferredInitialization() {
+		TypeBinding[] derived = this.environment.typeSystem.getDerivedTypes(this);
+		if (derived.length > 0) {
+			int count = 0;
+			for (int i = 0; i < derived.length; i++) {
+				if (derived[i] != null && derived[i].id == this.id)
+					derived[count++] = derived[i];
+			}
+			if (count < derived.length)
+				System.arraycopy(derived, 0, derived = new TypeBinding[count], 0, count);
+		}
+		return derived;
+	}
+
 	public String toString() {
 		if (this.wildcard != null) {
 			StringBuffer buffer = new StringBuffer(10);
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 508c72d..f76562d 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -22,6 +22,7 @@
  *							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"
+ *							Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
  *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          Bug 415821 - [1.8][compiler] CLASS_EXTENDS target type annotation missing for anonymous classes
  *     het@google.com - Bug 456986 - Bogus error when annotation processor generates annotation type
@@ -617,6 +618,12 @@
 				fields[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;	
 			}
 		}
+		if (isEnum && compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+			// mark return types of values & valueOf as nonnull (needed to wait till after setMethods() to avoid reentrance):
+			LookupEnvironment environment = this.environment();
+			((SyntheticMethodBinding)methodBindings[0]).markNonNull(environment);
+			((SyntheticMethodBinding)methodBindings[1]).markNonNull(environment);
+		}
 	}
 
 //{ObjectTeams: accessible to sub-class:
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 ee19b24..1056a1c 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
@@ -40,6 +40,7 @@
  *								Bug 446434 - [1.8][null] Enable interned captures also when analysing null type annotations
  *								Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
  *								Bug 456508 - Unexpected RHS PolyTypeBinding for: <code-snippet>
+ *								Bug 390064 - [compiler][resource] Resource leak warning missing when extending parameterized class
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -102,6 +103,7 @@
 		if (enclosingType != null && enclosingType.hasNullTypeAnnotations())
 			this.tagBits |= TagBits.HasNullTypeAnnotation;
 		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
+		this.typeBits = type.typeBits;
 	}
 
 	/**
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 61007e1..e436088 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -36,9 +36,12 @@
  *								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
+ *								Bug 456532 - [1.8][null] ReferenceBinding.appendNullAnnotation() includes phantom annotations in error messages
  *      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
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -1026,10 +1029,20 @@
 			}
 			break;
 		case 6:
-			if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.ITYPEBINDING, this.compoundName[5]))
-				return;
-			if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_CORE_DOM_ITYPEBINDING, this.compoundName))
-				this.typeBits |= TypeIds.BitUninternedType;
+			if (CharOperation.equals(TypeConstants.ORG, this.compoundName[0])) {
+				if (CharOperation.equals(TypeConstants.SPRING, this.compoundName[1])) {
+					if (CharOperation.equals(TypeConstants.AUTOWIRED, this.compoundName[5])) {
+						if (CharOperation.equals(TypeConstants.ORG_SPRING_AUTOWIRED, this.compoundName)) {
+							this.id = TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired;
+						}
+					}
+					return;
+				}
+				if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.ITYPEBINDING, this.compoundName[5]))
+					return;
+				if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_CORE_DOM_ITYPEBINDING, this.compoundName))
+					this.typeBits |= TypeIds.BitUninternedType;
+			}
 			break;
 		case 7 :
 			if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.TYPEBINDING, this.compoundName[6]))
@@ -2051,15 +2064,24 @@
 
 protected void appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options) {
 	if (options.isAnnotationBasedNullAnalysisEnabled) {
-		// restore applied null annotation from tagBits:
-	    if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
-	    	char[][] nonNullAnnotationName = options.nonNullAnnotationName;
-			nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
-	    }
-	    if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
-	    	char[][] nullableAnnotationName = options.nullableAnnotationName;
-			nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
-	    }
+		if (options.usesNullTypeAnnotations()) {
+			for (AnnotationBinding annotation : this.typeAnnotations) {
+				TypeBinding annotationType = annotation.getAnnotationType();
+				if (annotationType.id == TypeIds.T_ConfiguredAnnotationNonNull || annotation.type.id == TypeIds.T_ConfiguredAnnotationNullable) {
+					nameBuffer.append('@').append(annotationType.shortReadableName()).append(' ');
+				}
+			}
+		} else {
+			// restore applied null annotation from tagBits:
+		    if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
+		    	char[][] nonNullAnnotationName = options.nonNullAnnotationName;
+				nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
+		    }
+		    if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
+		    	char[][] nullableAnnotationName = options.nullableAnnotationName;
+				nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
+		    }
+		}
 	}
 }
 
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 032efd5..51b02a7 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
@@ -1713,13 +1713,13 @@
 		ObjectVector found = new ObjectVector(3);
 		CompilationUnitScope unitScope = compilationUnitScope();
 		unitScope.recordTypeReferences(argumentTypes);
-
+		List<TypeBinding> visitedTypes = new ArrayList<TypeBinding>();
 		if (receiverTypeIsInterface) {
 			unitScope.recordTypeReference(receiverType);
 			MethodBinding[] receiverMethods = receiverType.getMethods(selector, argumentTypes.length);
 			if (receiverMethods.length > 0)
 				found.addAll(receiverMethods);
-			findMethodInSuperInterfaces(receiverType, selector, found, null, invocationSite);
+			findMethodInSuperInterfaces(receiverType, selector, found, visitedTypes, invocationSite);
 //{ObjectTeams: confined types don't proceed to java.lang.Object:
 		  if (!(TypeAnalyzer.isConfined(receiverType)))
 // SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index c108d8b..c1c2ede 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -26,6 +26,7 @@
  *								bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
  *								Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
  *								Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
+ *								Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations

  *								Bug 415850 - [1.8] Ensure RunJDTCoreTests can cope with null annotations enabled
  *								Bug 416172 - [1.8][compiler][null] null type annotation not evaluated on method return type
  *								Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
@@ -1158,16 +1159,27 @@
 	return uniqueKey;
 }
 
-//{ObjectTeams: allow access from Dependencies:
-public
-// SH}
-void faultInTypesForFieldsAndMethods() {
-	if (!isPrototype()) throw new IllegalStateException();
+private void checkAnnotationsInType() {
 	// check @Deprecated annotation
 	getAnnotationTagBits(); // marks as deprecated by side effect
 	ReferenceBinding enclosingType = enclosingType();
 	if (enclosingType != null && enclosingType.isViewedAsDeprecated() && !isDeprecated())
 		this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+
+	for (int i = 0, length = this.memberTypes.length; i < length; i++)
+		((SourceTypeBinding) this.memberTypes[i]).checkAnnotationsInType();
+}
+
+//{ObjectTeams: allow access from Dependencies:
+public
+// SH}
+void faultInTypesForFieldsAndMethods() {
+	if (!isPrototype()) throw new IllegalStateException();
+	checkAnnotationsInType();
+	internalFaultInTypeForFieldsAndMethods();
+}
+
+private void internalFaultInTypeForFieldsAndMethods() {
 	fields();
 	methods();
 
@@ -1180,7 +1192,7 @@
 	for (int i = 0; i < this.memberTypes.length; i++)
 		if (!this.memberTypes[i].isBinaryBinding()) // roles could be binary contained in source
 //carp}
-		((SourceTypeBinding) this.memberTypes[i]).faultInTypesForFieldsAndMethods();
+		((SourceTypeBinding) this.memberTypes[i]).internalFaultInTypeForFieldsAndMethods();
 }
 // NOTE: the type of each field of a source type is resolved when needed
 public FieldBinding[] fields() {
@@ -2519,7 +2531,7 @@
 				 				arg.type.resolvedType :
 					 			arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
 // orig:
-//				parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/); 
+//				parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
 			} finally {
 				if (deferRawTypeCheck) { 
 					arg.type.bits &= ~ASTNode.IgnoreRawTypeCheck;
@@ -2755,8 +2767,7 @@
 			methodDecl.createArgumentBindings();
 		// add implicit annotations (inherited(?) & default):
 		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
-			new ImplicitNullAnnotationVerifier(this.scope.environment(), compilerOptions.inheritNullAnnotations)
-					.checkImplicitNullAnnotations(method, methodDecl, true, this.scope);
+			new ImplicitNullAnnotationVerifier(this.scope.environment()).checkImplicitNullAnnotations(method, methodDecl, true, this.scope);

 		}
 	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index 73a188d..133ff43 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -11,6 +11,7 @@
  *     Technical University Berlin - extended API and implementation
  *		Stephan Herrmann - Contribution for
  *								bug 400710 - [1.8][compiler] synthetic access to default method generates wrong code
+ *								Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
  *      Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                          	Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
  *******************************************************************************/
@@ -458,6 +459,14 @@
 	    this.modifiers = ClassFileConstants.AccSynthetic | ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
 		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
 	    this.returnType = arrayType;
+	    LookupEnvironment environment = declaringClass.environment;
+		if (environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+			// mark X[]::new and X[]::clone as returning 'X @NonNull' (don't wait (cf. markNonNull()), because we're called as late as codeGen):
+	    	if (environment.usesNullTypeAnnotations())
+	    		this.returnType = environment.createAnnotatedType(this.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
+	    	else
+	    		this.tagBits |= TagBits.AnnotationNonNull;
+	    }
 	    this.parameters = new TypeBinding[] { purpose == SyntheticMethodBinding.ArrayConstructor ? TypeBinding.INT : (TypeBinding) arrayType};
 	    this.thrownExceptions = Binding.NO_EXCEPTIONS;
 	    this.purpose = purpose;
@@ -673,4 +682,27 @@
 	public LambdaExpression sourceLambda() {
 		return this.lambda;
 	}
+
+	public void markNonNull(LookupEnvironment environment) {
+		// deferred update of the return type
+	    switch (this.purpose) {
+			case EnumValues:
+				if (environment.usesNullTypeAnnotations()) {
+					TypeBinding elementType = ((ArrayBinding)this.returnType).leafComponentType();
+					AnnotationBinding nonNullAnnotation = environment.getNonNullAnnotation();
+					elementType = environment.createAnnotatedType(elementType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
+					this.returnType = environment.createArrayType(elementType, 1, new AnnotationBinding[]{ nonNullAnnotation, null });
+				} else {
+					this.tagBits |= TagBits.AnnotationNonNull;
+				}
+				return;
+			case EnumValueOf:
+				if (environment.usesNullTypeAnnotations()) {
+					this.returnType = environment.createAnnotatedType(this.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
+				} else {
+					this.tagBits |= TagBits.AnnotationNonNull;
+				}
+				return;
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index c9611a2..0284bd1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -22,6 +22,8 @@
  *								Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
  *    Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
  *                              Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ *    Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -119,6 +121,7 @@
     char[] TYPEBINDING = "TypeBinding".toCharArray(); //$NON-NLS-1$
     char[] DOM = "dom".toCharArray(); //$NON-NLS-1$
     char[] ITYPEBINDING = "ITypeBinding".toCharArray(); //$NON-NLS-1$
+    char[] SPRING = "springframework".toCharArray(); //$NON-NLS-1$
     
 	// Constant compound names
 	char[][] JAVA_LANG = {JAVA, LANG};
@@ -330,6 +333,13 @@
 	//    detail for the above:
 	char[] OPTIONAL = "optional".toCharArray(); //$NON-NLS-1$
 
+	// Spring @Autowired annotation
+	char [] AUTOWIRED = "Autowired".toCharArray();  //$NON-NLS-1$
+	char [] BEANS = "beans".toCharArray();  //$NON-NLS-1$
+	char [] FACTORY = "factory".toCharArray(); //$NON-NLS-1$
+	char[][] ORG_SPRING_AUTOWIRED = new char[][] {ORG, SPRING, BEANS, FACTORY, ANNOTATION, AUTOWIRED};
+	char[] REQUIRED = "required".toCharArray(); //$NON-NLS-1$
+
 	// Constraints for generic type argument inference
 	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
 	int CONSTRAINT_EXTENDS = 1;	// Actual << Formal
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index cc71148..1693a65 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -16,6 +16,8 @@
  *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
  *      Jesper S Moller <jesper@selskabet.org> -  Contributions for
  *								Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -127,11 +129,16 @@
 	// new in 3.9 to identify known @Inject annotations
 	final int T_JavaxInjectInject = 80;
 	final int T_ComGoogleInjectInject = 81;
+
+	// @Autowired
+	final int T_OrgSpringframeworkBeansFactoryAnnotationAutowired = 82;
+
 	// Java 8 - JEP 120
 	final int T_JavaLangAnnotationRepeatable = 90;
 	// If you add new type id, make sure to bump up T_LastWellKnownTypeId if there is a cross over.
 	final int T_LastWellKnownTypeId = 128;
 	
+
 	final int NoId = Integer.MAX_VALUE;
 
 	public static final int IMPLICIT_CONVERSION_MASK = 0xFF;
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 c1abf52..df79020 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
@@ -33,6 +33,8 @@
  *								Bug 456497 - [1.8][null] during inference nullness from target type is lost against weaker hint from applicability analysis
  *								Bug 456459 - Discrepancy between Eclipse compiler and javac - Enums, interfaces, and generics
  *								Bug 456487 - [1.8][null] @Nullable type variant of @NonNull-constrained type parameter causes grief
+ *								Bug 462790 - [null] NPE in Expression.computeConversion()
+ *								Bug 456532 - [1.8][null] ReferenceBinding.appendNullAnnotation() includes phantom annotations in error messages
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -944,6 +946,27 @@
 	    return readableName;
 	}
 
+	protected void appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options) {
+		int oldSize = nameBuffer.length();
+		super.appendNullAnnotation(nameBuffer, options);
+		if (oldSize == nameBuffer.length()) { // nothing appended in super.appendNullAnnotation()?
+			if (hasNullTypeAnnotations()) {
+				// see if the prototype has null type annotations:
+				TypeVariableBinding[] typeVariables = null;
+				if (this.declaringElement instanceof ReferenceBinding) {
+					typeVariables = ((ReferenceBinding) this.declaringElement).typeVariables();
+				} else if (this.declaringElement instanceof MethodBinding) {
+					typeVariables = ((MethodBinding) this.declaringElement).typeVariables();
+				}
+				if (typeVariables != null && typeVariables.length > this.rank) {
+					TypeVariableBinding prototype = typeVariables[this.rank];
+					if (prototype != this)//$IDENTITY-COMPARISON$
+						prototype.appendNullAnnotation(nameBuffer, options);
+				}
+			}
+		}
+	}
+
 	public TypeBinding unannotated() {
 		return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
 	}
@@ -1032,10 +1055,11 @@
 	public TypeBinding setFirstBound(TypeBinding firstBound) {
 		this.firstBound = firstBound;
 		if ((this.tagBits & TagBits.HasAnnotatedVariants) != 0) {
-			TypeBinding [] annotatedTypes = this.environment.getAnnotatedTypes(this);
+			TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
 			for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
 				TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
-				annotatedType.firstBound = firstBound;
+				if (annotatedType.firstBound == null)
+					annotatedType.firstBound = firstBound;
 			}
 		}
 		if (firstBound != null && firstBound.hasNullTypeAnnotations())
@@ -1048,10 +1072,11 @@
 	public ReferenceBinding setSuperClass(ReferenceBinding superclass) {
 		this.superclass = superclass;
 		if ((this.tagBits & TagBits.HasAnnotatedVariants) != 0) {
-			TypeBinding [] annotatedTypes = this.environment.getAnnotatedTypes(this);
+			TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
 			for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
 				TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
-				annotatedType.superclass = superclass;
+				if (annotatedType.superclass == null)
+					annotatedType.superclass = superclass;
 			}
 		}
 		return superclass;
@@ -1062,15 +1087,20 @@
 	public ReferenceBinding [] setSuperInterfaces(ReferenceBinding[] superInterfaces) {
 		this.superInterfaces = superInterfaces;
 		if ((this.tagBits & TagBits.HasAnnotatedVariants) != 0) {
-			TypeBinding [] annotatedTypes = this.environment.getAnnotatedTypes(this);
+			TypeBinding [] annotatedTypes = getDerivedTypesForDeferredInitialization();
 			for (int i = 0, length = annotatedTypes == null ? 0 : annotatedTypes.length; i < length; i++) {
 				TypeVariableBinding annotatedType = (TypeVariableBinding) annotatedTypes[i];
-				annotatedType.superInterfaces = superInterfaces;
+				if (annotatedType.superInterfaces == null)
+					annotatedType.superInterfaces = superInterfaces;
 			}
 		}
 		return superInterfaces;
 	}
 
+	protected TypeBinding[] getDerivedTypesForDeferredInitialization() {
+		return this.environment.getAnnotatedTypes(this);
+	}
+
 	public TypeBinding combineTypeAnnotations(TypeBinding substitute) {
 		if (hasTypeAnnotations()) {
 			// may need to merge annotations from the original variable and from substitution:
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 fd36d24..689813b 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
@@ -59,6 +59,8 @@
  *								Bug 446442 - [1.8] merge null annotations from super methods
  *								Bug 455723 - Nonnull argument not correctly inferred in loop
  *								Bug 458361 - [1.8][null] reconciler throws NPE in ProblemReporter.illegalReturnRedefinition()
+ *								Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
+ *								Bug 461878 - [1.7][1.8][compiler][null] ECJ compiler does not allow to use null annotations on annotations
  *      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
@@ -68,6 +70,8 @@
  *								bug 419209 - [1.8] Repeating container annotations should be rejected in the presence of annotation it contains
  *								Bug 429384 - [1.8][null] implement conformance rules for null-annotated lower / upper type bounds
  *								Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected
+ *     Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
+ *                              bug 386692 - Missing "unused" warning on "autowired" fields
  ********************************************************************************/
 package org.eclipse.jdt.internal.compiler.problem;
 
@@ -6366,8 +6370,15 @@
 	String[] shortArguments = new String[] {
 		String.valueOf(annotation.resolvedType.shortReadableName())
 	};
+	int severity = ProblemSeverities.Error | ProblemSeverities.Fatal;
+	if (annotation.recipient instanceof ReferenceBinding) {
+		if (((ReferenceBinding) annotation.recipient).isAnnotationType())
+			severity = ProblemSeverities.Warning; // special case for https://bugs.eclipse.org/461878
+	}
 	handle(IProblem.NullAnnotationUnsupportedLocation,
-		arguments, shortArguments, annotation.sourceStart, annotation.sourceEnd);
+			arguments, shortArguments,
+			severity,
+			annotation.sourceStart, annotation.sourceEnd);
 }
 public void nullAnnotationUnsupportedLocation(TypeReference type) {
 	int sourceEnd = type.sourceEnd;
@@ -9527,6 +9538,7 @@
 					break;
 				case TypeIds.T_JavaxInjectInject:
 				case TypeIds.T_ComGoogleInjectInject:
+				case TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired:
 					if (problemId != IProblem.UnusedPrivateField)
 						return true; // @Inject on method/ctor does constitute a relevant use, just on fields it doesn't
 					break;
@@ -13802,8 +13814,7 @@
 			location.sourceEnd);
 }
 public void illegalReturnRedefinition(ASTNode location, MethodBinding descriptorMethod,
-			char[][] nonNullAnnotationName, 
-			char/*@Nullable*/[][] providedAnnotationName, TypeBinding providedType) {
+			boolean isUnchecked, TypeBinding providedType) {
 	StringBuffer methodSignature = new StringBuffer()
 		.append(descriptorMethod.declaringClass.readableName())
 		.append('.')
@@ -13812,22 +13823,16 @@
 		.append(descriptorMethod.declaringClass.shortReadableName())
 		.append('.')
 		.append(descriptorMethod.shortReadableName());
-	StringBuffer providedPrefix = new StringBuffer(); 
-	StringBuffer providedShortPrefix = new StringBuffer(); 
-	if (providedAnnotationName != null) {
-		providedPrefix.append('@').append(CharOperation.toString(providedAnnotationName)).append(' ');
-		providedShortPrefix.append('@').append(providedAnnotationName[providedAnnotationName.length-1]).append(' ');
-	}
 	this.handle(
-		providedAnnotationName == null
+		isUnchecked
 			? IProblem.ReferenceExpressionReturnNullRedefUnchecked
 			: IProblem.ReferenceExpressionReturnNullRedef,
 		new String[] { methodSignature.toString(),
-						CharOperation.toString(nonNullAnnotationName), String.valueOf(descriptorMethod.returnType.readableName()),
-						providedPrefix.toString(), String.valueOf(providedType.readableName())},
+						String.valueOf(descriptorMethod.returnType.nullAnnotatedReadableName(this.options, false)),
+						String.valueOf(providedType.nullAnnotatedReadableName(this.options, false))},
 		new String[] { shortSignature.toString(),
-						String.valueOf(nonNullAnnotationName[nonNullAnnotationName.length-1]), String.valueOf(descriptorMethod.returnType.shortReadableName()),
-						providedShortPrefix.toString(), String.valueOf(providedType.shortReadableName())},
+						String.valueOf(descriptorMethod.returnType.nullAnnotatedReadableName(this.options, true)),
+						String.valueOf(providedType.nullAnnotatedReadableName(this.options, true))},
 		location.sourceStart,
 		location.sourceEnd);
 }
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 c8fe886..c1fdaa4 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
@@ -817,8 +817,8 @@
 956 = Null type safety (type annotations): The expression of type ''{1}'' needs unchecked conversion to conform to ''{0}'', corresponding supertype is ''{2}''
 957 = Null type mismatch at parameter {0}: required ''{1}'' but provided ''{2}'' via method descriptor {3}
 958 = Null type safety: parameter {0} provided via method descriptor {3} needs unchecked conversion to conform to ''{1}''
-959 = Null type mismatch at method return type: Method descriptor {0} promises ''@{1} {2}'' but referenced method provides ''{3}{4}''
-960 = Null type safety at method return type: Method descriptor {0} promises ''@{1} {2}'' but referenced method provides ''{3}{4}''
+959 = Null type mismatch at method return type: Method descriptor {0} promises ''{1}'' but referenced method provides ''{2}''
+960 = Null type safety at method return type: Method descriptor {0} promises ''{1}'' but referenced method provides ''{2}''
 961 = Redundant null check: comparing ''{0}'' against null
 962 = The nullness annotation ''{0}'' is not applicable at this location
 963 = Nullness annotations are not applicable at this location 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
index 151d5da..74844eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -1115,7 +1115,14 @@
 				}
 			}
 		} else if (typeBinding.isNestedType()) {
-			classFile.recordInnerClasses(typeBinding);
+			TypeBinding enclosingType = typeBinding;
+			do {
+				if (!enclosingType.canBeSeenBy(classFile.referenceBinding.scope))
+					break;
+				enclosingType = enclosingType.enclosingType();
+			} while (enclosingType != null);
+			if (enclosingType == null)
+				classFile.recordInnerClasses(typeBinding);
 		}
 	}
 	/*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
index 72390f4..5ba061e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
@@ -61,6 +61,7 @@
 import org.eclipse.jdt.internal.core.CancelableProblemFactory;
 import org.eclipse.jdt.internal.core.INameEnvironmentWithProgress;
 import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.LocalVariable;
 import org.eclipse.jdt.internal.core.NameLookup;
 import org.eclipse.jdt.internal.core.SourceRefElement;
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
@@ -764,9 +765,15 @@
 				}
 				intList.add(i);
 			} else {
-				// binary member
+				// binary member or method argument
 				try {
-					String key = ((BinaryMember) element).getKey(true/*open to get resolved info*/);
+					String key;
+					if (element instanceof BinaryMember)
+						key = ((BinaryMember) element).getKey(true/*open to get resolved info*/);
+					else if (element instanceof LocalVariable)
+						key = ((LocalVariable) element).getKey(true/*open to get resolved info*/);
+					else
+						throw new IllegalArgumentException(element + " has an unexpected type"); //$NON-NLS-1$
 					binaryElementPositions.put(key, i);
 				} catch (JavaModelException e) {
 					throw new IllegalArgumentException(element + " does not exist"); //$NON-NLS-1$
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 ae99a7a..675fa1e 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
@@ -7,9 +7,11 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 package org.eclipse.jdt.core.dom;
 
@@ -25,6 +27,7 @@
 import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.FieldReference;
 import org.eclipse.jdt.internal.compiler.ast.ImportReference;
 import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
@@ -56,6 +59,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
@@ -283,6 +287,13 @@
 	 * Method declared on BindingResolver.
 	 */
 	synchronized IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) {
+		return getMethodOrLambdaBinding(methodBinding, null, null);
+	}
+
+	private synchronized IMethodBinding getMethodOrLambdaBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding,
+													org.eclipse.jdt.internal.compiler.lookup.MethodBinding descriptor,
+													IBinding enclosingBinding)
+	{
  		if (methodBinding != null && !methodBinding.isValidBinding()) {
 			org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding problemMethodBinding =
 				(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) methodBinding;
@@ -297,7 +308,11 @@
 			if (binding != null) {
 				return binding;
 			}
-			binding = new MethodBinding(this, methodBinding);
+			if (descriptor != null && enclosingBinding != null) {
+				binding = new MethodBinding.LambdaMethod(this, descriptor, methodBinding, enclosingBinding);
+			} else {
+				binding = new MethodBinding(this, methodBinding);
+			}
 			this.bindingTables.compilerBindingsToASTBindings.put(methodBinding, binding);
 			return binding;
 		}
@@ -390,6 +405,11 @@
 	 * Method declared on BindingResolver.
 	 */
 	synchronized ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) {
+		return internalGetTypeBinding(referenceBinding, null);
+	}
+
+	private synchronized ITypeBinding internalGetTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding, IBinding declaringMember) {
+		// may also create an TypeBinding.AnonymousTypeBinding
 		if (referenceBinding == null) {
 			return null;
 		} else if (!referenceBinding.isValidBinding()) {
@@ -403,7 +423,7 @@
 						if (binding != null) {
 							return binding;
 						}
-						binding = new TypeBinding(this, binding2);
+						binding = TypeBinding.createTypeBinding(this, binding2, declaringMember);
 						this.bindingTables.compilerBindingsToASTBindings.put(binding2, binding);
 						return binding;
 					}
@@ -417,7 +437,7 @@
 						return binding;
 					}
 					if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0) {
-						binding = new TypeBinding(this, referenceBinding);
+						binding = TypeBinding.createTypeBinding(this, referenceBinding, declaringMember);
 					} else {
 						binding = new RecoveredTypeBinding(this, referenceBinding);
 					}
@@ -433,7 +453,7 @@
 			if (binding != null) {
 				return binding;
 			}
-			binding = new TypeBinding(this, referenceBinding);
+			binding = TypeBinding.createTypeBinding(this, referenceBinding, declaringMember);
 			this.bindingTables.compilerBindingsToASTBindings.put(referenceBinding, binding);
 			return binding;
 		}
@@ -948,7 +968,12 @@
 		Object oldNode = this.newAstToOldAst.get(lambda);
 		if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
 			org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode;
-			IMethodBinding methodBinding = getMethodBinding(lambdaExpression.getMethodBinding());
+			IMethodBinding methodBinding = null;
+			if (lambdaExpression.descriptor != null) {
+				IBinding declaringMember = getDeclaringMember(lambdaExpression, lambdaExpression.enclosingScope);
+				if (declaringMember != null)
+					methodBinding = getMethodOrLambdaBinding(lambdaExpression.getMethodBinding(), lambdaExpression.descriptor, declaringMember);
+			}
 			if (methodBinding == null) {
 				return null;
 			}
@@ -961,6 +986,48 @@
 		}
 		return null;
 	}
+
+	private IBinding getDeclaringMember(org.eclipse.jdt.internal.compiler.ast.ASTNode node, Scope currentScope) {
+		MethodScope methodScope = currentScope != null ? currentScope.methodScope() : null;
+		if (methodScope != null) {
+			if (methodScope.isInsideInitializer()) {
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingType = methodScope.referenceType();
+				if (enclosingType.fields != null) {
+					for (int i = 0; i < enclosingType.fields.length; i++) {
+						FieldDeclaration field = enclosingType.fields[i];
+						if (field.declarationSourceStart <= node.sourceStart && node.sourceEnd <= field.declarationSourceEnd) {
+							if (field instanceof org.eclipse.jdt.internal.compiler.ast.Initializer)
+								return getMethodBinding(((org.eclipse.jdt.internal.compiler.ast.Initializer) field).getMethodBinding());
+							else
+								return getVariableBinding(field.binding);
+						}
+					}
+				}
+			} else {
+				if (methodScope.isLambdaScope()) {
+					org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) methodScope.referenceContext;
+					IMethodBinding methodBinding = null;
+					if (lambdaExpression.descriptor != null) {
+						IBinding declaringMember = getDeclaringMember(lambdaExpression, lambdaExpression.enclosingScope);
+						if (declaringMember != null)
+							methodBinding = getMethodOrLambdaBinding(lambdaExpression.getMethodBinding(), lambdaExpression.descriptor, declaringMember);
+					}
+					if (methodBinding == null) {
+						return null;
+					}
+					String key = methodBinding.getKey();
+					if (key != null) {
+						this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+					}
+					return methodBinding;
+				} else {
+					return getMethodBinding(methodScope.referenceMethodBinding());
+				}
+			}
+		}
+		return null;
+	}
+
 	/*
 	 * Method declared on BindingResolver.
 	 */
@@ -1765,7 +1832,8 @@
 		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type);
 		if (node != null && (node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) {
 			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousLocalTypeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
-			ITypeBinding typeBinding = this.getTypeBinding(anonymousLocalTypeDeclaration.binding);
+			IBinding declaringMember = getDeclaringMember(anonymousLocalTypeDeclaration, anonymousLocalTypeDeclaration.scope);
+			ITypeBinding typeBinding = internalGetTypeBinding(anonymousLocalTypeDeclaration.binding, declaringMember);
 			if (typeBinding == null) {
 				return null;
 			}
@@ -1926,7 +1994,8 @@
 		final Object node = this.newAstToOldAst.get(type);
 		if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
 			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
-			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			IBinding declaringMember = getDeclaringMember(typeDeclaration, typeDeclaration.scope);
+			ITypeBinding typeBinding = internalGetTypeBinding(typeDeclaration.binding, declaringMember);
 			if (typeBinding == null) {
 				return null;
 			}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
index 36bbf3d..d9b6034 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -8,6 +8,8 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
@@ -87,6 +89,31 @@
 	public ITypeBinding getDeclaringClass();
 
 	/**
+	 * If this method binding represents a lambda expression then:
+	 * <ul>
+	 * <li>If the lambda expression is declared in the body of a method,
+	 *   answers the binding of that declaring method.
+	 * </li>
+	 * <li>Otherwise, if the lambda expression is declared in the 
+	 *   initializer of a field, answers the binding of that declaring field.
+	 * </li>
+	 * <li>Otherwise, if the lambda expression is declared in a static initializer or an
+	 *   instance initializer, a method binding is returned to represent that initializer
+	 *   (selector is an empty string in this case).
+	 * </li>
+	 * </ul>
+	 * <p>
+	 * If this method binding does not represent a lambda expression,
+	 * <code>null</code> is returned.
+	 * </p>
+	 * @return a method binding or field binding representing the member that
+	 * contains the lambda expression represented by this method binding,
+	 * or null for regular method bindings.
+	 * @since 3.11
+	 */
+	public IBinding getDeclaringMember();
+
+	/**
 	 * Returns the resolved default value of an annotation type member,
 	 * or <code>null</code> if the member has no default value, or if this
 	 * is not the binding for an annotation type member.
@@ -293,6 +320,8 @@
 	 * <li>For references to a signature polymorphic method from class MethodHandle,
 	 * returns the declaration of the method. In the reference binding, the parameter types and
 	 * the return type are determined by the concrete invocation context.</li>
+	 * <li>For lambda methods, returns the (possibly parameterized) single abstract method
+	 * of the functional type.</li>
 	 * <li>For other method bindings, this returns the same binding.</li>
 	 * </ul>
 	 *
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
index 5da4239..0d17f9e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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,8 @@
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
@@ -261,6 +263,30 @@
 	public IMethodBinding getDeclaringMethod();
 
 	/**
+	 * If this type binding represents a local type, possibly an anonymous class, then:
+	 * <ul>
+	 * <li>If the local type is declared in the body of a method,
+	 *   answers the binding of that declaring method.
+	 * </li>
+	 * <li>Otherwise, if the local type (an anonymous class in this case) is declared
+	 *   in the initializer of a field, answers the binding of that declaring field.
+	 * </li>
+	 * <li>Otherwise, if the local type is declared in a static initializer or
+	 *   an instance initializer, a method binding is returned to represent that initializer
+	 *   (selector is an empty string in this case).
+	 * </li>
+	 * </ul>
+	 * <p>
+	 * If this type binding does not represent a local type, <code>null</code> is returned.
+	 * </p>
+	 * @return a method binding or field binding representing the member that
+	 * contains the local type represented by this type binding,
+	 * or null for non-local type bindings.
+	 * @since 3.11
+	 */
+	public IBinding getDeclaringMember();
+
+	/**
 	 * Returns the dimensionality of this array type, or <code>0</code> if this
 	 * is not an array type binding.
 	 *
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 52c98a0..90eab94 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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,12 +9,15 @@
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
 
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
@@ -40,8 +43,8 @@
 		Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | Modifier.NATIVE |
 		Modifier.STRICTFP | Modifier.DEFAULT;
 	private static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
-	private org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding;
-	private BindingResolver resolver;
+	protected org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding;
+	protected BindingResolver resolver;
 	private ITypeBinding[] parameterTypes;
 	private ITypeBinding[] exceptionTypes;
 	private String name;
@@ -133,6 +136,11 @@
 		return this.declaringClass;
 	}
 
+	@Override
+	public IBinding getDeclaringMember() {
+		return null;
+	}
+
 	public IAnnotationBinding[] getParameterAnnotations(int index) {
 		if (getParameterTypes() == NO_TYPE_BINDINGS) {
 			return AnnotationBinding.NoAnnotations;
@@ -497,4 +505,69 @@
 		return this.binding.copyInheritanceSrc != null;
 	}
 // SH}
+
+	/*
+	 * Method binding representing a lambda expression.
+	 * Most properties are read from the SAM descriptor,
+	 * but key, parameter types, and annotations are taken from the lambda implementation.
+	 * Additionally we store the declaring member (see #getDeclaringMember()).
+	 */
+	static class LambdaMethod extends MethodBinding {
+
+		private MethodBinding implementation;
+		private IBinding declaringMember;
+
+		public LambdaMethod(DefaultBindingResolver resolver,
+							org.eclipse.jdt.internal.compiler.lookup.MethodBinding lambdaDescriptor,
+							org.eclipse.jdt.internal.compiler.lookup.MethodBinding implementation,
+							IBinding declaringMember)
+		{
+			super(resolver, lambdaDescriptor);
+			this.implementation = new MethodBinding(resolver, implementation);
+			this.declaringMember = declaringMember;
+		}
+
+		/**
+		 * @see IBinding#getModifiers()
+		 */
+		public int getModifiers() {
+			return super.getModifiers() & ~ClassFileConstants.AccAbstract;
+		}
+
+		/**
+		 * @see IBinding#getKey()
+		 */
+		public String getKey() {
+			return this.implementation.getKey();
+		}
+
+		@Override
+		public ITypeBinding[] getParameterTypes() {
+			return this.implementation.getParameterTypes();
+		}
+
+		@Override
+		public IAnnotationBinding[] getParameterAnnotations(int paramIndex) {
+			return this.implementation.getParameterAnnotations(paramIndex);
+		}
+
+		public IAnnotationBinding[] getAnnotations() {
+			return this.implementation.getAnnotations();
+		}
+
+		@Override
+		public IBinding getDeclaringMember() {
+			return this.declaringMember;
+		}
+
+		@Override
+		public IMethodBinding getMethodDeclaration() {
+			return this.resolver.getMethodBinding(this.binding);
+		}
+
+		@Override
+		public String toString() {
+			return super.toString().replace("public abstract ", "public ");  //$NON-NLS-1$//$NON-NLS-2$
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
index e907680..6335af3 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
@@ -14,6 +14,8 @@
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.batch.ClasspathDirectory;
 import org.eclipse.jdt.internal.compiler.batch.FileSystem;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
@@ -41,8 +43,29 @@
 	}
 	public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
 		checkCanceled();
-		return super.findType(typeName, packageName);
+		NameEnvironmentAnswer answer = super.findType(typeName, packageName);
+		if (answer == null) {
+			NameEnvironmentAnswer suggestedAnswer = null;
+			String qualifiedPackageName = new String(CharOperation.concatWith(packageName, '/'));
+			String qualifiedTypeName = new String(CharOperation.concatWith(packageName, typeName, '/'));
+			String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+			for (int i = 0, length = this.classpaths.length; i < length; i++) {
+				if (!(this.classpaths[i] instanceof ClasspathDirectory)) continue;
+				ClasspathDirectory classpathDirectory = (ClasspathDirectory) this.classpaths[i];
+				answer = classpathDirectory.findSecondaryInClass(typeName, qualifiedPackageName, qualifiedBinaryFileName);
+				if (answer != null) {
+					if (!answer.ignoreIfBetter()) {
+						if (answer.isBetter(suggestedAnswer))
+							return answer;
+					} else if (answer.isBetter(suggestedAnswer))
+						// remember suggestion and keep looking
+						suggestedAnswer = answer;
+				}
+			}
+		}
+		return answer;
 	}
+
 	public NameEnvironmentAnswer findType(char[][] compoundName) {
 		checkCanceled();
 		return super.findType(compoundName);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
index 39b4144..98ed738 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2014 IBM Corporation and others.
+ * Copyright (c) 2007, 2015 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
@@ -8,6 +8,8 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
@@ -166,6 +168,14 @@
 	}
 
 	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringMember()
+	 */
+	@Override
+	public IBinding getDeclaringMember() {
+		return null;
+	}
+
+	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDimensions()
 	 */
 	public int getDimensions() {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 30f628c..eeb5f7f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -11,6 +11,7 @@
  *     Technical University Berlin - extended API and implementation
  *     Stephan Herrmann - Contribution for
  *								Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
@@ -30,7 +31,6 @@
 import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18;
-import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
@@ -79,7 +79,7 @@
 	org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding;
 	private TypeBinding prototype = null;
 	private String key;
-	private BindingResolver resolver;
+	protected BindingResolver resolver;
 	private IVariableBinding[] fields;
 	private IAnnotationBinding[] annotations;
 	private IAnnotationBinding[] typeAnnotations;
@@ -90,6 +90,18 @@
 	private ITypeBinding[] bounds;
 	private ITypeBinding[] typeParameters;
 
+	/**
+	 * Create either a regular TypeBinding or an AnonymousTypeBinding (if declaringMember is given).
+	 */
+	public static TypeBinding createTypeBinding(BindingResolver resolver,
+												org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding,
+												IBinding declaringMember)
+	{
+		return declaringMember != null
+					? new LocalTypeBinding(resolver, referenceBinding, declaringMember)
+					: new TypeBinding(resolver, referenceBinding);
+	}
+
 	public TypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding) {
 		this.binding = binding;
 		this.resolver = resolver;
@@ -435,8 +447,8 @@
 	 * @see ITypeBinding#getDeclaringMethod()
 	 */
 	public synchronized IMethodBinding getDeclaringMethod() {
-		if (this.binding instanceof LocalTypeBinding) {
-			LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.binding;
+		if (this.binding instanceof org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) {
+			org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding localTypeBinding = (org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) this.binding;
 			MethodBinding methodBinding = localTypeBinding.enclosingMethod;
 			if (methodBinding != null) {
 				try {
@@ -506,6 +518,11 @@
 		return null;
 	}
 
+	@Override
+	public IBinding getDeclaringMember() {
+		return null;
+	}
+
 	/*
 	 * @see ITypeBinding#getDimensions()
 	 */
@@ -1643,4 +1660,22 @@
 		this.typeAnnotations = resolveAnnotationBindings(this.binding.getTypeAnnotations(), true);
 		return this.typeAnnotations;
 	}
+
+	static class LocalTypeBinding extends TypeBinding {
+
+		private IBinding declaringMember;
+
+		public LocalTypeBinding(BindingResolver resolver,
+									org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding,
+									IBinding declaringMember)
+		{
+			super(resolver, binding);
+			this.declaringMember = declaringMember;
+		}
+
+		@Override
+		public IBinding getDeclaringMember() {
+			return this.declaringMember;
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
index 7b833e3..3a1e2ad 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -8,6 +8,8 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 
 package org.eclipse.jdt.core.dom;
@@ -156,6 +158,9 @@
 					case ASTNode.METHOD_DECLARATION :
 						MethodDeclaration methodDeclaration = (MethodDeclaration) node;
 						return methodDeclaration.resolveBinding();
+					case ASTNode.LAMBDA_EXPRESSION :
+						LambdaExpression lambdaExpression = (LambdaExpression) node;
+						return lambdaExpression.resolveMethodBinding();
 					default:
 						node = node.getParent();
 				}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
index 9daae6c..e31367b 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
+ *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] IndexOutOfBoundsException in TokenManager - https://bugs.eclipse.org/462945
  *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
@@ -19,6 +20,7 @@
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRPAREN;
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameWHITESPACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamepackage;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -119,6 +121,12 @@
 	}
 
 	@Override
+	public boolean preVisit2(ASTNode node) {
+		boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
+		return !isMalformed;
+	}
+
+	@Override
 	public boolean visit(LineComment node) {
 		int commentIndex = this.tm.firstIndexIn(node, TokenNameCOMMENT_LINE);
 		handleLineComment(commentIndex);
@@ -425,7 +433,7 @@
 				commentToken.putLineBreaksAfter(previous.getLineBreaksAfter());
 				previous.clearLineBreaksAfter();
 			} else if (existingBreaksAfter <= existingBreaksBefore && next != null
-					&& commentIndex > 0 /* doesn't apply to a comment before the package declaration */) {
+					&& next.tokenType != TokenNamepackage /* doesn't apply to a comment before the package declaration */) {
 				commentToken.putLineBreaksBefore(next.getLineBreaksBefore());
 				next.clearLineBreaksBefore();
 			}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index 7b035b0..d6f5d69 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
+ *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] IndexOutOfBoundsException in TokenManager - https://bugs.eclipse.org/462945
  *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
@@ -84,6 +85,12 @@
 	}
 
 	@Override
+	public boolean preVisit2(ASTNode node) {
+		boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
+		return !isMalformed;
+	}
+
+	@Override
 	public boolean visit(CompilationUnit node) {
 		List<ImportDeclaration> imports = node.imports();
 		if (!imports.isEmpty()) {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index 119643e..95c3cff 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
+ *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] IndexOutOfBoundsException in TokenManager - https://bugs.eclipse.org/462945

  *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
@@ -103,6 +104,12 @@
 	}
 
 	@Override
+	public boolean preVisit2(ASTNode node) {

+		boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;

+		return !isMalformed;

+	}

+

+	@Override

 	public boolean visit(TypeDeclaration node) {
 		if (node.getName().getStartPosition() == -1)
 			return true; // this is a fake type created by parsing in class body mode
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
index 25a0af5..0640b73 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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,8 @@
  *     IBM Corporation - added J2SE 1.5 support
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								Bug 463533 - Signature.getSignatureSimpleName() returns different results for resolved and unresolved extends
  *******************************************************************************/
 package org.eclipse.jdt.core;
 
@@ -1921,12 +1923,21 @@
 	}
 
 	if(dotCount > 0) {
+		int typeStart = 0;
 		for(int i = 0; i < qualifiedType.length; i++) {
-			if(qualifiedType[i] == '.') {
-				dotCount--;
+			switch (qualifiedType[i]) {
+				case '.':
+					dotCount--;
+					break;
+				case ' ':
+					typeStart = i+1;
+					break;
 			}
 			if(dotCount <= 0) {
-				return CharOperation.subarray(qualifiedType, i + 1, qualifiedType.length);
+				char[] simpleName = CharOperation.subarray(qualifiedType, i + 1, qualifiedType.length);
+				if (typeStart > 0 && typeStart < qualifiedType.length)
+					return CharOperation.concat(CharOperation.subarray(qualifiedType, 0, typeStart), simpleName);
+				return simpleName;
 			}
 		}
 	}
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 d8dc589..8984deb 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, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -102,7 +102,7 @@
 			Plugin jdtCorePlugin = JavaCore.getPlugin();
 			if (jdtCorePlugin == null) return null;
 
-			IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.FORMATTER_EXTPOINT_ID);
+			IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.FORMATTER_EXTPOINT_ID);
 			if (extension != null) {
 				IExtension[] extensions =  extension.getExtensions();
 				for(int i = 0; i < extensions.length; i++){
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java
index a24a91a..fdc1e21 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java
@@ -175,11 +175,15 @@
 	
 		if (annotationPath == null) 
 			return null;
+
 		IWorkspaceRoot workspaceRoot = project.getProject().getWorkspace().getRoot();
-		IFile annotationZip = workspaceRoot.getFile(annotationPath);
-		if (annotationZip.exists())
-			return null;
-	
+
+		if (annotationPath.segmentCount() > 1) {
+			IFile annotationZip = workspaceRoot.getFile(annotationPath);
+			if (annotationZip.exists())
+				return null;
+		}
+		
 		annotationPath = annotationPath.append(binaryTypeName).addFileExtension(ExternalAnnotationProvider.ANNOTION_FILE_EXTENSION);
 		return workspaceRoot.getFile(annotationPath);
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
index e71ffb1..e86c4a5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -13,6 +13,7 @@
  *     Stephan Herrmann - Contribution for
  *								Bug 458577 - IClassFile.getWorkingCopy() may lead to NPE in BecomeWorkingCopyOperation
  *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ *								Bug 462768 - [null] NPE when using linked folder for external annotations
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -33,6 +34,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
@@ -394,12 +396,22 @@
 {
 	// try resolve path within the workspace:
 	IWorkspaceRoot root = project.getWorkspace().getRoot();
-	IResource resource = root.getFolder(externalAnnotationPath);
+	IResource resource = externalAnnotationPath.segmentCount() == 1
+			? root.getProject(externalAnnotationPath.lastSegment())
+			: root.getFolder(externalAnnotationPath);
 	if (!resource.exists())
 		resource = root.getFile(externalAnnotationPath);
-	String resolvedPath = resource.exists()
-							? resource.getLocation().toString() // workspace lookup succeeded -> resolve it
-							: externalAnnotationPath.toString(); // not in workspace, use as is
+	String resolvedPath;
+	if (resource.exists()) {
+		if (resource.isVirtual()) {
+			Util.log(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, 
+					"Virtual resource "+externalAnnotationPath+" cannot be used as annotationpath for project "+project.getName())); //$NON-NLS-1$ //$NON-NLS-2$
+			return;
+		}
+		resolvedPath = resource.getLocation().toString(); // workspace lookup succeeded -> resolve it
+	} else {
+		resolvedPath = externalAnnotationPath.toString(); // not in workspace, use as is
+	}
 	try {
 		annotationZip = reader.setExternalAnnotationProvider(resolvedPath, typeName, annotationZip, new ClassFileReader.ZipFileProducer() {
 			@Override public ZipFile produce() throws IOException {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
index b5acca9..a003b2b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -11,6 +11,8 @@
  *     Thirumala Reddy Mutchukota <thirumala@google.com> - Avoid optional library classpath entries validation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=412882
  *     Stephan Herrmann - Contribution for
  *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
+ *								Bug 462768 - [null] NPE when using linked folder for external annotations
+ *                              Bug 465296 - precedence of extra attributes on a classpath container
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -343,9 +345,9 @@
 			IClasspathAttribute[] combinedAttributes = this.extraAttributes;
 			int lenRefer = referringExtraAttributes.length;
 			if (lenRefer > 0) {
-				int lenCombined = combinedAttributes.length;
-				System.arraycopy(combinedAttributes, 0, combinedAttributes=new IClasspathAttribute[lenCombined+lenRefer], 0, lenCombined);
-				System.arraycopy(referringExtraAttributes, 0, combinedAttributes, lenCombined, lenRefer);
+				int lenEntry = combinedAttributes.length;
+				System.arraycopy(combinedAttributes, 0, combinedAttributes=new IClasspathAttribute[lenEntry+lenRefer], lenRefer, lenEntry);
+				System.arraycopy(referringExtraAttributes, 0, combinedAttributes, 0, lenRefer);
 			}
 			return new ClasspathEntry(
 								getContentKind(),
@@ -1282,11 +1284,13 @@
 				if (!resolve)
 					return annotationPath;
 
-				if (annotationPath.segmentCount() > 1) {
-					// try Workspace-absolute:
-					IProject targetProject = project.getWorkspace().getRoot().getProject(annotationPath.segment(0));
-					if (targetProject.exists())
+				// try Workspace-absolute:
+				IProject targetProject = project.getWorkspace().getRoot().getProject(annotationPath.segment(0));
+				if (targetProject.exists()) {
+					if (annotationPath.segmentCount() > 1)
 						return targetProject.getLocation().append(annotationPath.removeFirstSegments(1));
+					else
+						return targetProject.getLocation();
 				}
 				// absolute, not in workspace, must be Filesystem-absolute:
 				return annotationPath;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index c77be25..9d912ad 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -30,7 +30,6 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.IWorkspaceRunnable;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.resources.WorkspaceJob;
 import org.eclipse.core.runtime.*;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -41,7 +40,6 @@
 import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
 import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
-import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -815,26 +813,7 @@
 				}
 				if (projectsToTouch.length > 0) {
 					if (asynchronous){
-						WorkspaceJob touchJob = new WorkspaceJob(Messages.updating_external_archives_jobName) {
-							
-							public IStatus runInWorkspace(IProgressMonitor progressMonitor) throws CoreException {
-								try {
-									if (progressMonitor != null)
-										progressMonitor.beginTask("", projectsToTouch.length); //$NON-NLS-1$
-									touchProjects(projectsToTouch, progressMonitor);
-								}
-								finally {
-									if (progressMonitor != null)
-										progressMonitor.done();
-								}
-								return Status.OK_STATUS;
-							}
-							
-							public boolean belongsTo(Object family) {
-								return ResourcesPlugin.FAMILY_MANUAL_REFRESH == family;
-							}
-						};
-						touchJob.schedule();
+						this.manager.touchProjects(projectsToTouch, monitor);
 					}
 					else {
 						// touch the projects to force them to be recompiled while taking the workspace lock
@@ -873,18 +852,6 @@
 		}
 	}
 
-	protected void touchProjects(final IProject[] projectsToTouch, IProgressMonitor progressMonitor)
-			throws CoreException {
-		for (int i = 0; i < projectsToTouch.length; i++) {
-			IProgressMonitor monitor = progressMonitor == null ? null: new SubProgressMonitor(progressMonitor, 1);
-			IProject project = projectsToTouch[i];
-			// touch to force a build of this project
-			if (JavaBuilder.DEBUG)
-				System.out.println("Touching project " + project.getName() + " due to external jar file change"); //$NON-NLS-1$ //$NON-NLS-2$
-			project.touch(monitor);
-		}
-	}
-
 	/*
 	 * Check if external archives have changed for the given elements and create the corresponding deltas.
 	 * Returns whether at least one delta was created.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalAnnotationTracker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalAnnotationTracker.java
index 972bfcf..fd6da1c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalAnnotationTracker.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalAnnotationTracker.java
@@ -44,6 +44,7 @@
 	static class DirectoryNode {
 
 		DirectoryNode parent;		
+		IPath path;
 		
 		/** Key is a full workspace path. */
 		Map<IPath,DirectoryNode> children;
@@ -54,8 +55,9 @@
 		Map<IPath, ClassFile> classFiles;
 		IPackageFragmentRoot modelRoot; // TODO: for handling zipped annotations
 		
-		public DirectoryNode(DirectoryNode parent) {
+		public DirectoryNode(DirectoryNode parent, IPath path) {
 			this.parent = parent;
+			this.path = path;
 		}
 
 		Map<IPath, DirectoryNode> getChildren() {
@@ -80,9 +82,9 @@
 			}
 		}
 		void unregisterDirectory(DirectoryNode child) {
-			if (this.children == null) return;
-			this.children.remove(child);
-			if (this.children.isEmpty() && this.parent != null)
+			if (this.children != null)
+				this.children.remove(child.path);
+			if ((this.children == null || this.children.isEmpty()) && this.parent != null)
 				this.parent.unregisterDirectory(this);
 		}
 
@@ -106,10 +108,13 @@
 					count += child.numClassFiles();
 			return count;
 		}
+		boolean isEmpty() {
+			return (this.children == null || this.children.isEmpty()) && (this.classFiles == null || this.classFiles.isEmpty());
+		}
 	}
 
 	/** The tree of tracked annotation bases and class files. */
-	DirectoryNode tree = new DirectoryNode(null);
+	DirectoryNode tree = new DirectoryNode(null, null);
 
 	private static ExternalAnnotationTracker singleton;
 	private ExternalAnnotationTracker() { }
@@ -170,7 +175,7 @@
 		Map<IPath, DirectoryNode> children = current.getChildren(); // create if necessary
 		DirectoryNode nextHeadNode = children.get(nextHead);
 		if (nextHeadNode == null)
-			children.put(nextHead, nextHeadNode = new DirectoryNode(current));
+			children.put(nextHead, nextHeadNode = new DirectoryNode(current, nextHead));
 		if (baseDepth == nextDepth)
 			return nextHeadNode;
 		return getAnnotationBase(nextHeadNode, annotationBase, baseDepth, nextDepth+1);
@@ -207,14 +212,16 @@
 						traverseForDirectories(childDir, child);
 				}
 			}
-		}			
+		}
+		if (directoryNode.isEmpty())
+			directoryNode.parent.children.remove(matchedDelta.getFullPath());
 	}
 
 	// traversal of delta nodes to be matched against map of class files:
 	private void traverseForClassFiles(Map<IPath, ClassFile> classFiles, IResourceDelta matchedDelta, int baseDepth) {
 		for (IResourceDelta delta : matchedDelta.getAffectedChildren()) {
 			IPath deltaRelativePath = delta.getFullPath().removeFirstSegments(baseDepth);
-			ClassFile classFile = classFiles.get(deltaRelativePath);
+			ClassFile classFile = classFiles.remove(deltaRelativePath);
 			if (classFile != null) {
 				try {
 					// the payload: unload the class file corresponding to a changed external annotation file:
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 009e003..6b8b4d6 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
@@ -17,6 +17,7 @@
  *     Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425
  *     Thirumala Reddy Mutchukota <thirumala@google.com> - Contribution to bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=411423
  *     Terry Parker <tparker@google.com> - [performance] Low hit rates in JavaModel caches - https://bugs.eclipse.org/421165
+ *     Terry Parker <tparker@google.com> - Enable the Java model caches to recover from IO errors - https://bugs.eclipse.org/455042
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -102,7 +103,6 @@
 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$
 	private static final String ASSUMED_EXTERNAL_FILES_CACHE = "assumedExternalFilesCache";  //$NON-NLS-1$
 
@@ -1457,11 +1457,14 @@
 	 * A set of IPaths for jars that are known to not contain a chaining (through MANIFEST.MF) to another library
 	 */
 	private Set nonChainingJars;
-	
+
+	// The amount of time from when an invalid archive is first sensed until that state is considered stale.
+	private static long INVALID_ARCHIVE_TTL_MILLISECONDS = 2 * 60 * 1000;
+
 	/*
-	 * A set of IPaths for jars that are known to be invalid - such as not being a valid/known format
+	 * A map of IPaths for jars that are known to be invalid (such as not being in a valid/known format), to an eviction timestamp.
 	 */
-	private Set invalidArchives;
+	private Map<IPath, Long> invalidArchives;
 
 	/*
 	 * A set of IPaths for files that are known to be external to the workspace.
@@ -1528,19 +1531,16 @@
 					propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) {
 					JavaModelManager manager = JavaModelManager.getJavaModelManager();
 					IJavaModel model = manager.getJavaModel();
-					IJavaProject[] projects;
+					IJavaProject[] jProjects;
 					try {
-						projects = model.getJavaProjects();
-						for (int i = 0, pl = projects.length; i < pl; i++) {
-							JavaProject javaProject = (JavaProject) projects[i];
+						jProjects = model.getJavaProjects();
+						IProject[] projects = new IProject[jProjects.length];
+						for (int i = 0, pl = jProjects.length; i < pl; i++) {
+							JavaProject javaProject = (JavaProject) jProjects[i];
+							projects[i] = javaProject.getProject();
 							manager.deltaState.addClasspathValidation(javaProject);
-							try {
-								// need to touch the project to force validation by DeltaProcessor
-					            javaProject.getProject().touch(null);
-					        } catch (CoreException e) {
-					            // skip
-					        }
 						}
+						manager.touchProjects(projects, null);
 					} catch (JavaModelException e) {
 						// skip
 					}
@@ -1608,7 +1608,6 @@
 		if (Platform.isRunning()) {
 			this.indexManager = new IndexManager();
 			this.nonChainingJars = loadClasspathListCache(NON_CHAINING_JARS_CACHE);
-			this.invalidArchives = loadClasspathListCache(INVALID_ARCHIVES_CACHE);
 			this.externalFiles = loadClasspathListCache(EXTERNAL_FILES_CACHE);
 			this.assumedExternalFiles = loadClasspathListCache(ASSUMED_EXTERNAL_FILES_CACHE);
 			String includeContainerReferencedLib = System.getProperty(RESOLVE_REFERENCED_LIBRARIES_FOR_CONTAINERS);
@@ -1632,11 +1631,9 @@
 	public void addInvalidArchive(IPath path) {
 		// unlikely to be null
 		if (this.invalidArchives == null) {
-			this.invalidArchives = Collections.synchronizedSet(new HashSet());
+			this.invalidArchives = Collections.synchronizedMap(new HashMap());
 		}
-		if(this.invalidArchives != null) {
-			this.invalidArchives.add(path);
-		}
+		this.invalidArchives.put(path, System.currentTimeMillis() + INVALID_ARCHIVE_TTL_MILLISECONDS);
 	}
 
 	/**
@@ -2650,8 +2647,11 @@
 	 * @exception CoreException If unable to create/open the ZipFile
 	 */
 	public ZipFile getZipFile(IPath path) throws CoreException {
+		return getZipFile(path, true);
+	}
 
-		if (isInvalidArchive(path))
+	private ZipFile getZipFile(IPath path, boolean checkInvalidArchiveCache) throws CoreException {
+		if (checkInvalidArchiveCache && isInvalidArchive(path))
 			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, new ZipException()));
 		
 		ZipCache zipCache;
@@ -3067,6 +3067,36 @@
 		*/
 	}
 
+	void touchProjects(final IProject[] projectsToTouch, IProgressMonitor progressMonitor) throws JavaModelException {
+		WorkspaceJob touchJob = new WorkspaceJob(Messages.synchronizing_projects_job) {
+			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+				try {
+					if (monitor != null) {
+						monitor.beginTask("", projectsToTouch.length); //$NON-NLS-1$
+					}
+					for (IProject iProject : projectsToTouch) {
+						IProgressMonitor subMonitor = monitor == null ? null: new SubProgressMonitor(monitor, 1);
+						if (JavaBuilder.DEBUG) {
+							System.out.println("Touching project " + iProject.getName()); //$NON-NLS-1$
+						}
+						iProject.touch(subMonitor);
+					}
+				}
+				finally {
+					if (monitor != null) {
+						monitor.done();
+					}
+				}
+				return Status.OK_STATUS;
+			}
+
+			public boolean belongsTo(Object family) {
+				return ResourcesPlugin.FAMILY_MANUAL_REFRESH == family;
+			}
+		};
+		touchJob.schedule();
+	}
+
 	private HashSet getClasspathBeingResolved() {
 	    HashSet result = (HashSet) this.classpathsBeingResolved.get();
 	    if (result == null) {
@@ -3093,12 +3123,41 @@
 	}
 	
 	public boolean isInvalidArchive(IPath path) {
-		return this.invalidArchives != null && this.invalidArchives.contains(path);
+		if (this.invalidArchives == null)
+			return false;
+		Long evictionTime = this.invalidArchives.get(path);
+		if (evictionTime == null)
+			return false;
+		long now = System.currentTimeMillis();
+
+		// If the TTL for this cache entry has expired, directly check whether the archive is still invalid.
+		// If it transitioned to being valid, remove it from the cache and force an update to project caches.
+		if (now > evictionTime) {
+			try {
+				getZipFile(path, false);
+				removeFromInvalidArchiveCache(path);
+				return false;
+			} catch (CoreException e) {
+				// Archive is still invalid, fall through to reporting it is invalid.
+			}
+		}
+		return true;
 	}
 
 	public void removeFromInvalidArchiveCache(IPath path) {
 		if (this.invalidArchives != null) {
-			this.invalidArchives.remove(path);
+			if (this.invalidArchives.remove(path) != null) {
+				try {
+					// Bug 455042: Force an update of the JavaProjectElementInfo project caches.
+					for (IJavaProject project : getJavaModel().getJavaProjects()) {
+						if (project.findPackageFragmentRoot(path) != null) {
+							((JavaProject) project).resetCaches();
+						}
+					}
+				} catch (JavaModelException e) {
+					Util.log(e, "Unable to retrieve the Java model."); //$NON-NLS-1$
+				}
+			}
 		}
 	}
 
@@ -3214,8 +3273,6 @@
 	private Set getClasspathListCache(String cacheName) throws CoreException {
 		if (cacheName == NON_CHAINING_JARS_CACHE) 
 			return getNonChainingJarsCache();
-		else if (cacheName == INVALID_ARCHIVES_CACHE)
-			return this.invalidArchives;
 		else if (cacheName == EXTERNAL_FILES_CACHE)
 			return this.externalFiles;
 		else if (cacheName == ASSUMED_EXTERNAL_FILES_CACHE)
@@ -4322,7 +4379,6 @@
 			case ISaveContext.FULL_SAVE : {
 				// save non-chaining jar, invalid jar and external file caches on full save
 				saveClasspathListCache(NON_CHAINING_JARS_CACHE);
-				saveClasspathListCache(INVALID_ARCHIVES_CACHE);
 				saveClasspathListCache(EXTERNAL_FILES_CACHE);
 				saveClasspathListCache(ASSUMED_EXTERNAL_FILES_CACHE);
 	
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
index 1e5dedf..f05213b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
@@ -459,6 +459,19 @@
 		return true;
 	}
 
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()
+	 */
+	public String getKey(boolean forceOpen) throws JavaModelException {
+		if (this.parent.getElementType() == IJavaElement.METHOD) {
+			StringBuilder buf = new StringBuilder(((IMethod)this.parent).getKey());
+			buf.append('#');
+			buf.append(this.name);
+			return buf.toString();
+		}
+		return null;
+	}
+
 	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
 		buffer.append(tabString(tab));
 		if (info != NO_INFO) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
index 78f79aa..560ddfe 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2015 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
+ *     Stephan Herrmann - Contribution for Bug 464615 - [dom] ASTParser.createBindings() ignores parameterization of a method invocation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -33,6 +34,10 @@
 		return this.uniqueKey;
 	}
 
+	public String getKey(boolean forceOpen) {
+		return this.uniqueKey;
+	}
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.IField#isResolved()
 	 */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
index d36c8d4..7715122 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2015 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,9 +7,12 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for Bug 464615 - [dom] ASTParser.createBindings() ignores parameterization of a method invocation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import org.eclipse.jdt.core.JavaModelException;
+
 /**
  * Handle representing a binary method that is resolved.
  * The uniqueKey contains the genericSignature of the resolved method. Use BindingKey to decode it.
@@ -31,6 +34,12 @@
 	public String getKey() {
 		return this.uniqueKey;
 	}
+
+	@Override
+	public String getKey(boolean forceOpen) throws JavaModelException {
+		return this.uniqueKey;
+	}
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.IMethod#isResolved()
 	 */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
index 1c5d2e7..88b72ef 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2015 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
+ *     Stephan Herrmann - Contribution for Bug 464615 - [dom] ASTParser.createBindings() ignores parameterization of a method invocation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -38,6 +39,11 @@
 	public String getKey() {
 		return this.uniqueKey;
 	}
+	
+	@Override
+	public String getKey(boolean forceOpen) throws JavaModelException {
+		return this.uniqueKey;
+	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.core.BinaryType#isResolved()
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
index a46552b..cd63189 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
@@ -18,6 +18,7 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
 import org.eclipse.jdt.internal.compiler.ast.Assignment;
 import org.eclipse.jdt.internal.compiler.ast.CastExpression;
@@ -55,6 +56,44 @@
 
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class BindingKeyResolver extends BindingKeyParser {
+
+	/** Synthetic bindings for local variables (method arguments) restored from a binding key. */
+	private final class SyntheticLocalVariableBinding extends LocalVariableBinding {
+
+		private final MethodBinding enclosingMethod;
+		private char[] key;
+
+		SyntheticLocalVariableBinding(char[] name, TypeBinding type, MethodBinding enclosingMethod) {
+			super(name, type, 0, true);
+			this.enclosingMethod = enclosingMethod;
+		}
+
+		@Override
+		public char[] computeUniqueKey() {
+			if (this.key == null) {
+				// have no scope to find the enclosing method, so use the captured method:
+				StringBuilder buf = new StringBuilder().append(this.enclosingMethod.computeUniqueKey());
+				buf.append('#');
+				buf.append(this.name);
+				int length = buf.length();
+				this.key = new char[length];
+				buf.getChars(0, length, this.key, 0);
+			}
+			return this.key;
+		}
+		
+		@Override
+		public int hashCode() {
+			return CharOperation.hashCode(computeUniqueKey());
+		}
+
+		public boolean equals(Object obj) {
+			if (!(obj instanceof SyntheticLocalVariableBinding))
+				return false;
+			return CharOperation.equals(computeUniqueKey(), ((SyntheticLocalVariableBinding) obj).computeUniqueKey());
+		}
+	}
+
 	Compiler compiler;
 	Binding compilerBinding;
 
@@ -290,15 +329,30 @@
 		if (this.scope == null) {
 			if (this.methodBinding == null)
 				return;
-			this.scope = this.methodBinding.sourceMethod().scope;
+			AbstractMethodDeclaration sourceMethod = this.methodBinding.sourceMethod();
+			if (sourceMethod != null) {
+				this.scope = sourceMethod.scope;
+			} else {
+				char[][] parameterNames = this.methodBinding.parameterNames;
+				for (int i = 0; i < parameterNames.length; i++) {
+					if (CharOperation.equals(parameterNames[i], varName)) {
+						// we don't have a compiler binding for this argument, but we can craft one:
+						this.compilerBinding = new SyntheticLocalVariableBinding(varName, this.methodBinding.parameters[i], this.methodBinding);
+						this.methodBinding = null;
+						return;
+					}
+				}
+			}
 		}
-	 	for (int i = 0; i < this.scope.localIndex; i++) {
-			LocalVariableBinding local = this.scope.locals[i];
-			if (CharOperation.equals(local.name, varName)
-					&& occurrenceCount-- == 0) {
-				this.methodBinding = null;
-				this.compilerBinding = local;
-				return;
+		if (this.scope != null) {
+		 	for (int i = 0; i < this.scope.localIndex; i++) {
+				LocalVariableBinding local = this.scope.locals[i];
+				if (CharOperation.equals(local.name, varName)
+						&& occurrenceCount-- == 0) {
+					this.methodBinding = null;
+					this.compilerBinding = local;
+					return;
+				}
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
index 64b668e..fbcc410 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others.
+ * Copyright (c) 2005, 2015 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
@@ -8,12 +8,18 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Technical University Berlin - extended API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								Bug 463330 - [dom] DOMFinder doesn't find the VariableBinding corresponding to a method argument
+ *								Bug 464463 - [dom] DOMFinder doesn't find an ITypeParameter
+ *								Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.util;
 
 import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.ILocalVariable;
 import org.eclipse.jdt.core.IMember;
 import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.ITypeParameter;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
@@ -29,6 +35,7 @@
 import org.eclipse.jdt.core.dom.IBinding;
 import org.eclipse.jdt.core.dom.ImportDeclaration;
 import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.LambdaExpression;
 import org.eclipse.jdt.core.dom.MarkerAnnotation;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.NormalAnnotation;
@@ -36,10 +43,12 @@
 import org.eclipse.jdt.core.dom.ParameterizedType;
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jdt.core.dom.RoleTypeDeclaration;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
 import org.eclipse.jdt.core.dom.TypeParameter;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.internal.core.LambdaMethod;
 import org.eclipse.jdt.internal.core.SourceRefElement;
 
 public class DOMFinder extends ASTVisitor {
@@ -68,8 +77,11 @@
 
 	public ASTNode search() throws JavaModelException {
 		ISourceRange range = null;
-		if (this.element instanceof IMember && !(this.element instanceof IInitializer))
+		if (this.element instanceof IMember && !(this.element instanceof IInitializer)
+				&& !(this.element instanceof LambdaMethod) && !(this.element instanceof org.eclipse.jdt.internal.core.LambdaExpression))
 			range = ((IMember) this.element).getNameRange();
+		else if (this.element instanceof ITypeParameter || this.element instanceof ILocalVariable)
+			range = this.element.getNameRange();
 		else
 			range = this.element.getSourceRange();
 		this.rangeStart = range.getOffset();
@@ -207,4 +219,16 @@
 			this.foundBinding = node.resolveBinding();
 		return true;
 	}
+
+	public boolean visit(SingleVariableDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;		
+	}
+
+	public boolean visit(LambdaExpression node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveMethodBinding();
+		return true;
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
index 4e52a9e..ceb402f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -192,7 +192,7 @@
 	public static String cache_invalidLoadFactor;
 	public static String savedState_jobName;
 	public static String refreshing_external_folders;
-	public static String updating_external_archives_jobName;
+	public static String synchronizing_projects_job;
 	public static String convention_unit_nullName;
 	public static String convention_unit_notJavaName;
 	public static String convention_classFile_nullName;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index d5908f8..bf3c646 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -191,7 +191,7 @@
 cache_invalidLoadFactor = Incorrect load factor
 savedState_jobName = Processing Java changes since last activation
 refreshing_external_folders = Refreshing external folders
-updating_external_archives_jobName = Refreshing external archives
+synchronizing_projects_job = Synchronizing projects
 
 ## java model initialization
 javamodel_initialization = Initializing Java tooling
diff --git a/org.eclipse.jdt.core/plugin.properties b/org.eclipse.jdt.core/plugin.properties
index 8f99944..1f11bc3 100644
--- a/org.eclipse.jdt.core/plugin.properties
+++ b/org.eclipse.jdt.core/plugin.properties
@@ -30,3 +30,4 @@
 jarManifestName=JAR Manifest File
 traceComponentLabel=JDT Core
 javaFormatterName=Java Formatter
+defaultJavaFormatterName=Eclipse [built-in]
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
index 2f48730..76e3e99 100644
--- a/org.eclipse.jdt.core/plugin.xml
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -291,7 +291,7 @@
    <javaFormatter
          class="org.eclipse.jdt.internal.formatter.DefaultCodeFormatter"
          id="org.eclipse.jdt.core.defaultJavaFormatter"
-         name="Eclipse [built-in]">
+         name="%defaultJavaFormatterName">
    </javaFormatter>
 </extension>
 
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index b4dbbf6..71c98d4 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -29,7 +29,6 @@
     <plugins>
     <plugin>
 		<artifactId>maven-antrun-plugin</artifactId>
-		<version>1.7</version>
 		<executions>
 			<execution>
 				<phase>prepare-package</phase>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
index 7eeac86..53684c9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -301,7 +301,11 @@
  * Returns null if the path doesn't correspond to a project.
  */
 private static IJavaProject getJavaProject(IPath path, IJavaModel model) {
-	IJavaProject project = model.getJavaProject(path.lastSegment());
+	String lastSeg = path.lastSegment();
+	if (lastSeg == null) {
+		lastSeg = path.toOSString();
+	}
+	IJavaProject project = model.getJavaProject(lastSeg);
 	if (project.exists()) {
 		return project;
 	}