Update jdt.core from BETA_JAVA8 with
a27c88e6ab2cdd140d2a25deaa52833a8b2cd1b2 upto
4d5ca8a02167bbefc92469b1dbb1f1e04260a45e
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 b7f17d9..71de456 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
@@ -18,6 +18,7 @@
  *								bug 402237 - [1.8][compiler] investigate differences between compilers re MethodVerifyTest
  *								bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
  *								Bug 412203 - [compiler] Internal compiler error: java.lang.IllegalArgumentException: info cannot be null
+ *								Bug 422051 - [1.8][compiler][tests] cleanup excuses (JavacHasABug) in InterfaceMethodTests
  *     Jesper S Moller - Contributions for bug 378674 - "The method can be declared as static" is wrong
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.compiler.regression;
@@ -774,15 +775,7 @@
 								return compiler.compliance != ClassFileConstants.JDK1_5 ||
 										compiler.minor != 1600 ? null : this;
 							}
-					}: null,
-			Javac8AcceptsDefaultMethodInAnnotationType = RUN_JAVAC ?
-				new JavacHasABug(
-					MismatchType.EclipseErrorsJavacNone,
-					ClassFileConstants.JDK1_8, 23 /* TODO: insert minor when fixed */) : null,
-			Javac8ProducesIllegalAccessError = RUN_JAVAC ? 
-				new JavacHasABug(
-					MismatchType.StandardOutputMismatch,
-					ClassFileConstants.JDK1_8, 23 /* TODO: insert minor when fixed */) : null;
+					}: null;
 	}
 }
 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
index c79521e..50fd25b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java
@@ -12,6 +12,7 @@
 
 import java.util.Map;
 
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 
 import junit.framework.Test;
@@ -134,48 +135,84 @@
 		"----------\n");
 }
 public void test001d() {
-	this.runNegativeTest(
-		new String[] {
-			"X.java",
-			"import java.util.ArrayList;\n" +
-			"public class X<T> {" +
-			"	public void ab(ArrayList<String> al){\n" + 
-			"		System.out.println(\"SUCCESS\");\n" +
-			"	}\n" + 
-			"	public static void main(String[] args) {\n" + 
-			"		X<String> x = new X<>();\n" + 
-			"		x.ab(new ArrayList<>());\n" + 
-			"	}\n" +
-			"}",
-		},
-		"----------\n" + 
-		"1. ERROR in X.java (at line 7)\n" + 
-		"	x.ab(new ArrayList<>());\n" + 
-		"	  ^^\n" + 
-		"The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" + 
-		"----------\n");
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"import java.util.ArrayList;\n" +
+				"public class X<T> {" +
+				"	public void ab(ArrayList<String> al){\n" + 
+				"		System.out.println(\"SUCCESS\");\n" +
+				"	}\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"		X<String> x = new X<>();\n" + 
+				"		x.ab(new ArrayList<>());\n" + 
+				"	}\n" +
+				"}",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	x.ab(new ArrayList<>());\n" + 
+			"	  ^^\n" + 
+			"The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" + 
+			"----------\n");
+	} else {
+		this.runConformTest(
+				new String[] {
+					"X.java",
+					"import java.util.ArrayList;\n" +
+					"public class X<T> {" +
+					"	public void ab(ArrayList<String> al){\n" + 
+					"		System.out.println(\"SUCCESS\");\n" +
+					"	}\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		X<String> x = new X<>();\n" + 
+					"		x.ab(new ArrayList<>());\n" + 
+					"	}\n" +
+					"}",
+				},
+				"SUCCESS");
+	}
 }
 public void test001e() {
-	this.runNegativeTest(
-		new String[] {
-			"X.java",
-			"import java.util.ArrayList;\n" +
-			"public class X<T> {" +
-			"	public void ab(ArrayList<T> al){\n" + 
-			"		System.out.println(\"SUCCESS\");\n" +
-			"	}\n" + 
-			"	public static void main(String[] args) {\n" + 
-			"		X<String> x = new X<>();\n" + 
-			"		x.ab(new ArrayList<>());\n" + 
-			"	}\n" +
-			"}",
-		},
-		"----------\n" + 
-		"1. ERROR in X.java (at line 7)\n" + 
-		"	x.ab(new ArrayList<>());\n" + 
-		"	  ^^\n" + 
-		"The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" + 
-		"----------\n");
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"import java.util.ArrayList;\n" +
+				"public class X<T> {" +
+				"	public void ab(ArrayList<T> al){\n" + 
+				"		System.out.println(\"SUCCESS\");\n" +
+				"	}\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"		X<String> x = new X<>();\n" + 
+				"		x.ab(new ArrayList<>());\n" + 
+				"	}\n" +
+				"}",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	x.ab(new ArrayList<>());\n" + 
+			"	  ^^\n" + 
+			"The method ab(ArrayList<String>) in the type X<String> is not applicable for the arguments (ArrayList<Object>)\n" + 
+			"----------\n");
+	} else {
+		this.runConformTest(
+				new String[] {
+					"X.java",
+					"import java.util.ArrayList;\n" +
+					"public class X<T> {" +
+					"	public void ab(ArrayList<T> al){\n" + 
+					"		System.out.println(\"SUCCESS\");\n" +
+					"	}\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		X<String> x = new X<>();\n" + 
+					"		x.ab(new ArrayList<>());\n" + 
+					"	}\n" +
+					"}",
+				},
+				"SUCCESS");
+	}
 }
 public void test001f() {
 	this.runNegativeTest(
@@ -533,45 +570,69 @@
 		"2");
 }
 public void test007a() {
-	this.runNegativeTest(
-		new String[] {
-			"X.java",
-			"public class X<T> {\n" +
-			"	public X(){\n" +
-			"	}\n" +
-			"	public X(T param){\n" +
-			"		System.out.println(param);\n" +
-			"	}\n" +
-			"	public static void testFunction(X<String> param){\n" +
-			"		System.out.println(\"SUCCESS\");\n" +
-			"	}\n" +
-			"	public static void main(String[] args) {\n" + 
-			"		X.testFunction(new X<>());\n" + 
-			"		X.testFunction(new X(\"hello\"));\n" +
-			"	}\n" +
-			"}",
-		},
-		"----------\n" + 
-		"1. ERROR in X.java (at line 11)\n" + 
-		"	X.testFunction(new X<>());\n" + 
-		"	  ^^^^^^^^^^^^\n" + 
-		"The method testFunction(X<String>) in the type X is not applicable for the arguments (X<Object>)\n" + 
-		"----------\n" + 
-		"2. WARNING in X.java (at line 12)\n" + 
-		"	X.testFunction(new X(\"hello\"));\n" + 
-		"	               ^^^^^^^^^^^^^^\n" + 
-		"Type safety: The constructor X(Object) belongs to the raw type X. References to generic type X<T> should be parameterized\n" + 
-		"----------\n" + 
-		"3. WARNING in X.java (at line 12)\n" + 
-		"	X.testFunction(new X(\"hello\"));\n" + 
-		"	               ^^^^^^^^^^^^^^\n" + 
-		"Type safety: The expression of type X needs unchecked conversion to conform to X<String>\n" + 
-		"----------\n" + 
-		"4. WARNING in X.java (at line 12)\n" + 
-		"	X.testFunction(new X(\"hello\"));\n" + 
-		"	                   ^\n" + 
-		"X is a raw type. References to generic type X<T> should be parameterized\n" + 
-		"----------\n");
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X<T> {\n" +
+				"	public X(){\n" +
+				"	}\n" +
+				"	public X(T param){\n" +
+				"		System.out.println(param);\n" +
+				"	}\n" +
+				"	public static void testFunction(X<String> param){\n" +
+				"		System.out.println(\"SUCCESS\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" + 
+				"		X.testFunction(new X<>());\n" + 
+				"		X.testFunction(new X(\"hello\"));\n" +
+				"	}\n" +
+				"}",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 11)\n" + 
+			"	X.testFunction(new X<>());\n" + 
+			"	  ^^^^^^^^^^^^\n" + 
+			"The method testFunction(X<String>) in the type X is not applicable for the arguments (X<Object>)\n" + 
+			"----------\n" + 
+			"2. WARNING in X.java (at line 12)\n" + 
+			"	X.testFunction(new X(\"hello\"));\n" + 
+			"	               ^^^^^^^^^^^^^^\n" + 
+			"Type safety: The constructor X(Object) belongs to the raw type X. References to generic type X<T> should be parameterized\n" + 
+			"----------\n" + 
+			"3. WARNING in X.java (at line 12)\n" + 
+			"	X.testFunction(new X(\"hello\"));\n" + 
+			"	               ^^^^^^^^^^^^^^\n" + 
+			"Type safety: The expression of type X needs unchecked conversion to conform to X<String>\n" + 
+			"----------\n" + 
+			"4. WARNING in X.java (at line 12)\n" + 
+			"	X.testFunction(new X(\"hello\"));\n" + 
+			"	                   ^\n" + 
+			"X is a raw type. References to generic type X<T> should be parameterized\n" + 
+			"----------\n");
+	} else {
+		this.runConformTest(
+				new String[] {
+					"X.java",
+					"public class X<T> {\n" +
+					"	public X(){\n" +
+					"	}\n" +
+					"	public X(T param){\n" +
+					"		System.out.println(param);\n" +
+					"	}\n" +
+					"	public static void testFunction(X<String> param){\n" +
+					"		System.out.println(\"SUCCESS\");\n" +
+					"	}\n" +
+					"	public static void main(String[] args) {\n" + 
+					"		X.testFunction(new X<>());\n" + 
+					"		X.testFunction(new X(\"hello\"));\n" +
+					"	}\n" +
+					"}",
+				},
+				"SUCCESS\n" + 
+				"hello\n" + 
+				"SUCCESS");
+	}
 }
 //shows the difference between using <> and the raw type - different semantics
 public void test008() {
@@ -921,23 +982,38 @@
 }
 //check inference at method argument position.
 public void test0021() {
-	this.runNegativeTest(
-		new String[] {
-			"X.java",
-			"import java.util.List;\n" +
-			"import java.util.ArrayList;\n" +
-			"class X<T> {\n" +
-			"  public X(T t) {}\n" +
-			"  int f(List<String> p) {return 0;}\n" +
-			"  int x = f(new ArrayList<>());\n" +
-			"}\n",
-		},
-		"----------\n" + 
-		"1. ERROR in X.java (at line 6)\n" + 
-		"	int x = f(new ArrayList<>());\n" + 
-		"	        ^\n" + 
-		"The method f(List<String>) in the type X<T> is not applicable for the arguments (ArrayList<Object>)\n" + 
-		"----------\n");
+	if (this.complianceLevel < ClassFileConstants.JDK1_8) {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"import java.util.List;\n" +
+				"import java.util.ArrayList;\n" +
+				"class X<T> {\n" +
+				"  public X(T t) {}\n" +
+				"  int f(List<String> p) {return 0;}\n" +
+				"  int x = f(new ArrayList<>());\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	int x = f(new ArrayList<>());\n" + 
+			"	        ^\n" + 
+			"The method f(List<String>) in the type X<T> is not applicable for the arguments (ArrayList<Object>)\n" + 
+			"----------\n");
+	} else {
+		this.runNegativeTest(
+				new String[] {
+					"X.java",
+					"import java.util.List;\n" +
+					"import java.util.ArrayList;\n" +
+					"class X<T> {\n" +
+					"  public X(T t) {}\n" +
+					"  int f(List<String> p) {return 0;}\n" +
+					"  int x = f(new ArrayList<>());\n" +
+					"}\n",
+				},
+				"");
+	}
 }
 public void test0022() {
 	this.runConformTest(
@@ -1033,6 +1109,7 @@
 		"----------\n");
 }
 // Test various scenarios.
+// NOTE: THIS TEST MOST LIKELY CAPTURES THE WRONG OUTPUT FOR JAVA 8. AS WE FIX TYPE INFERENCE ISSUES, THIS MAY FAIL.
 public void test0026() {
 	this.runNegativeTest(
 		new String[] {
@@ -1055,6 +1132,7 @@
 			"   X<?> x6 = new X<>(list);\n" +
 			"}\n"
 		},
+		this.complianceLevel < ClassFileConstants.JDK1_8 ? 
 		"----------\n" + 
 		"1. ERROR in X.java (at line 8)\n" + 
 		"	X<Number> x = new X<>(1);\n" + 
@@ -1075,7 +1153,28 @@
 		"	int i = m(new X<>(\"\"));\n" + 
 		"	        ^\n" + 
 		"The method m(X<String>) in the type X<T> is not applicable for the arguments (X<Object>)\n" + 
-		"----------\n");
+		"----------\n" :
+			"----------\n" + 
+			"1. ERROR in X.java (at line 8)\n" + 
+			"	X<Number> x = new X<>(1);\n" + 
+			"	              ^^^^^^^^^^\n" + 
+			"Type mismatch: cannot convert from X<Integer> to X<Number>\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 12)\n" + 
+			"	X<Object> x4 = new X<>(1).idem();\n" + 
+			"	               ^^^^^^^^^^^^^^^^^\n" + 
+			"Type mismatch: cannot convert from X<Integer> to X<Object>\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 13)\n" + 
+			"	X<Object> x5 = new X<>(1);\n" + 
+			"	               ^^^^^^^^^^\n" + 
+			"Type mismatch: cannot convert from X<Integer> to X<Object>\n" + 
+			"----------\n" + 
+			"4. ERROR in X.java (at line 15)\n" + 
+			"	int i = m(new X<>(\"\"));\n" + 
+			"	          ^^^^^^^^^^^\n" + 
+			"The constructor X<String>(String) is ambiguous\n" + 
+			"----------\n");
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=344655
 public void test0027() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
index 89cc6c4..4e21d0e 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InterfaceMethodsTest.java
@@ -1100,22 +1100,18 @@
 	// an annotation type cannot have default methods
 	public void testAnnotation1() {
 		runNegativeTest(
-			false,
 			new String[] {
 				"I.java",
 				"public @interface I {\n" +
 				"    default String id() { return \"1\"; }\n" +
 				"}\n"
 			},
-			null,
-			null,
 			"----------\n" + 
 			"1. ERROR in I.java (at line 2)\n" + 
 			"	default String id() { return \"1\"; }\n" + 
 			"	^^^^^^^\n" + 
 			"Syntax error on token \"default\", @ expected\n" + 
-			"----------\n",
-			JavacTestOptions.JavacHasABug.Javac8AcceptsDefaultMethodInAnnotationType);
+			"----------\n");
 	}
 	
 	// basic situation similar to AmbiguousMethodTest.test009()
@@ -1804,8 +1800,7 @@
 	}
 
 	// class implements interface with default method. 
-	// - synth. access needed for visibility reasons
-	// - witness for NoSuchMethodError in synthetic method (SuperMethodAccess)
+	// - witness for NoSuchMethodError in synthetic method (SuperMethodAccess) - turned out to be a JVM bug
 	public void testSuperAccess01() {
 		runConformTest(
 			new String[] {
@@ -1827,11 +1822,9 @@
 	}
 
 	// class implements interface with default method. 
-	// - synth. access needed for visibility reasons
 	// - intermediate public interface
 	public void testSuperAccess02() {
 		runConformTest(
-			false,
 			new String[] {
 				"p1/C.java",
 				"package p1;\n" +
@@ -1850,10 +1843,34 @@
 				"}\n" +
 				"public interface J extends I {}\n"
 			},
-			"",
-			"default",
-			"",
-			JavacTestOptions.JavacHasABug.Javac8ProducesIllegalAccessError);
+			"default");
+	}
+	
+	// https://bugs.eclipse.org/421796 - Bug 421796 - [1.8][compiler] java.lang.AbstractMethodError executing default method code.
+	public void testSuperAccess03() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"interface I  {\n" + 
+				"    void foo(); \n" + 
+				"}\n" + 
+				"\n" + 
+				"interface J extends I {\n" + 
+				"    default void foo() {\n" + 
+				"    }\n" + 
+				"}\n" + 
+				"\n" + 
+				"interface K extends J {\n" + 
+				"}\n" + 
+				"\n" + 
+				"public class X implements K {\n" + 
+				"	public static void main(String argv[]) {\n" + 
+				"		X test = new X();\n" + 
+				"		((J)test).foo();\n" + 
+				"		test.foo();\n" + 
+				"	}\n" + 
+				"}\n"
+			});
 	}
 
 	// Variant of test MethodVerifyTest.test144() from https://bugs.eclipse.org/bugs/show_bug.cgi?id=194034
@@ -2183,24 +2200,46 @@
 	}
     // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421543, [1.8][compiler] Compiler fails to recognize default method being turned into abstract by subtytpe
 	public void testBug421543b() {
-		runNegativeTest(
+		runConformTest(
 			new String[] {
 				"X.java",
 				"interface I<T>  {\n" +
 				"	void foo(T t);\n" +
 				"}\n" +
+				"@SuppressWarnings(\"override\")\n" +
 				"interface J extends I<J> {\n" +
 				"	default void foo(J t) {}\n" +
 				"}\n" +
 				"public class X implements J {\n" +
 				"}\n"
 			}, 
-			"----------\n" + 
-			"1. WARNING in X.java (at line 5)\n" + 
-			"	default void foo(J t) {}\n" + 
-			"	             ^^^^^^^^\n" + 
-			"The method foo(J) of type J should be tagged with @Override since it actually overrides a superinterface method\n" + 
-			"----------\n");
+			"");
+	}
+    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421797, [1.8][compiler] ClassFormatError with default methods & I.super.foo() syntax
+	public void testBug421797() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	int m(String s, int val);\n" +
+				"	public default int foo(String s, int val) {\n" +
+				"		System.out.print(s + \" from I.foo:\");\n" +
+				"		return val * val; \n" +
+				"	}\n" +
+				"}\n" +
+				"interface T extends I {\n" +
+				"	public default int m(String s, int value) { \n" +
+				"		I i = I.super::foo; \n" +
+				"		return i.foo(s, value);\n" +
+				"	}\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String argv[]) {  \n" +
+				"		System.out.println(new T(){}.m(\"Hello\", 1234));\n" +
+				"	}\n" +
+				"}\n"
+			}, 
+			"Hello from I.foo:1522756");
 	}	
 
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
index ca27e03..ac9610f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NegativeLambdaExpressionsTest.java
@@ -31,7 +31,7 @@
 public class NegativeLambdaExpressionsTest extends AbstractRegressionTest {
 
 static {
-//	TESTS_NAMES = new String[] { "testSuperReference03"};
+//	TESTS_NAMES = new String[] { "test401610i"};
 //	TESTS_NUMBERS = new int[] { 50 };
 //	TESTS_RANGE = new int[] { 11, -1 };
 }
@@ -5147,6 +5147,12 @@
 				"----------\n" + 
 				"3. ERROR in X.java (at line 7)\n" + 
 				"	new X().foo(()->{});\n" + 
+				"	        ^^^\n" + 
+				"The method foo(I<T>) in the type X is not applicable for the arguments (() -> {\n" + 
+				"})\n" + 
+				"----------\n" + 
+				"4. ERROR in X.java (at line 7)\n" + 
+				"	new X().foo(()->{});\n" + 
 				"	            ^^^^^^\n" + 
 				"The target type of this expression is not a well formed parameterized type due to bound(s) mismatch\n" + 
 				"----------\n");
@@ -5612,15 +5618,10 @@
 			"----------\n" + 
 			"3. ERROR in X.java (at line 9)\n" + 
 			"	foo(true ? x-> 1 : x->0);\n" + 
-			"	^^^\n" + 
-			"The method foo(I...) in the type X is not applicable for the arguments ((true ? (<no type> x) -> 1 : (<no type> x) -> 0))\n" + 
-			"----------\n" + 
-			"4. ERROR in X.java (at line 9)\n" + 
-			"	foo(true ? x-> 1 : x->0);\n" + 
 			"	               ^\n" + 
 			"Type mismatch: cannot convert from int to String\n" + 
 			"----------\n" + 
-			"5. ERROR in X.java (at line 9)\n" + 
+			"4. ERROR in X.java (at line 9)\n" + 
 			"	foo(true ? x-> 1 : x->0);\n" + 
 			"	                      ^\n" + 
 			"Type mismatch: cannot convert from int to String\n" + 
@@ -5785,8 +5786,11 @@
 				"----------\n" + 
 				"1. ERROR in X.java (at line 8)\n" + 
 				"	goo((x) -> { if (x) return null; });\n" + 
-				"	    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-				"This method must return a result of type String\n" + 
+				"	^^^\n" + 
+				"The method goo(I) in the type X is not applicable for the arguments ((<no type> x) -> {\n" + 
+				"  if (x)\n" + 
+				"      return null;\n" + 
+				"})\n" + 
 				"----------\n");
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=401939, [1.8][compiler] Incorrect shape analysis leads to method resolution failure .
@@ -5847,12 +5851,17 @@
 				"    }\n" +
 				"    Zork z;\n" +
 				"}\n",			},
-			"----------\n" + 
-			"1. ERROR in X.java (at line 13)\n" + 
-			"	Zork z;\n" + 
-			"	^^^^\n" + 
-			"Zork cannot be resolved to a type\n" + 
-			"----------\n");
+				"----------\n" + 
+				"1. ERROR in X.java (at line 11)\n" + 
+				"	new X().goo((p1, p2) -> p1 = p1 + p2);\n" + 
+				"	        ^^^\n" + 
+				"The method goo(I) is ambiguous for the type X\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 13)\n" + 
+				"	Zork z;\n" + 
+				"	^^^^\n" + 
+				"Zork cannot be resolved to a type\n" + 
+				"----------\n");
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=402219, [1.8][compiler] Compile time errors in lambda during hypothetical type check should render candidate method inapplicable.
 public void test402219a() {
@@ -5903,12 +5912,17 @@
 				"    }\n" +
 				"    Zork z;\n" +
 				"}\n",			},
-			"----------\n" + 
-			"1. ERROR in X.java (at line 13)\n" + 
-			"	Zork z;\n" + 
-			"	^^^^\n" + 
-			"Zork cannot be resolved to a type\n" + 
-			"----------\n");
+				"----------\n" + 
+				"1. ERROR in X.java (at line 11)\n" + 
+				"	new X().goo((p1, p2) -> p1 + p2);\n" + 
+				"	        ^^^\n" + 
+				"The method goo(I) is ambiguous for the type X\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 13)\n" + 
+				"	Zork z;\n" + 
+				"	^^^^\n" + 
+				"Zork cannot be resolved to a type\n" + 
+				"----------\n");
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=402259, [1.8][compiler] NPE during overload resolution when there are syntax errors. 
 public void test402259() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
new file mode 100644
index 0000000..7b241f3
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java
@@ -0,0 +1,991 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import junit.framework.Test;
+public class OverloadResolutionTest8 extends AbstractRegressionTest {
+
+static {
+//	TESTS_NAMES = new String[] { "test007"};
+//	TESTS_NUMBERS = new int[] { 50 };
+//	TESTS_RANGE = new int[] { 11, -1 };
+}
+public OverloadResolutionTest8(String name) {
+	super(name);
+}
+public static Test suite() {
+	return buildMinimalComplianceTestSuite(testClass(), F_1_8);
+}
+public static Class testClass() {
+	return OverloadResolutionTest8.class;
+}
+
+public void test001() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	int foo(int [] a);\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	int foo(int a);\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo((a)->a.length));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 9)\n" + 
+			"	System.out.println(foo((a)->a.length));\n" + 
+			"	                   ^^^\n" + 
+			"The method foo(I) is ambiguous for the type X\n" + 
+			"----------\n"
+			);
+}
+public void test002() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	void foo();\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void goo(I i) {\n" +
+				"		System.out.println(\"goo(I)\");\n" +
+				"	}\n" +
+				"	static void goo(J j) {\n" +
+				"		System.out.println(\"goo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		final boolean x = true;\n" +
+				"		goo(()-> goo((I)null));\n" +
+				"	}\n" +
+				"	int f() {\n" +
+				"		final boolean x = true;\n" +
+				"		while (x);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"goo(I)");
+}
+public void test003() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"   static final boolean f = true;\n" +
+				"	static void goo(J j) {\n" +
+				"		System.out.println(\"goo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		final boolean x = true;\n" +
+				"		goo(()-> { \n" +
+				"			final boolean y = true;\n" +
+				"			while (y); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (x); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (f); \n" +
+				"			});\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"goo(J)\n" +
+			"goo(J)\n" +
+			"goo(J)");
+}
+public void test004() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"   static boolean f = true;\n" +
+				"	static void goo(J j) {\n" +
+				"		System.out.println(\"goo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		boolean x = true;\n" +
+				"		goo(()-> { \n" +
+				"			boolean y = true;\n" +
+				"			while (y); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (x); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (f); \n" +
+				"			});\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 11)\n" + 
+			"	goo(()-> { \n" + 
+			"	^^^\n" + 
+			"The method goo(J) in the type X is not applicable for the arguments (() -> {\n" + 
+			"  boolean y = true;\n" + 
+			"  while (y)    ;\n" + 
+			"})\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 15)\n" + 
+			"	goo(()-> { \n" + 
+			"	^^^\n" + 
+			"The method goo(J) in the type X is not applicable for the arguments (() -> {\n" + 
+			"  while (x)    ;\n" + 
+			"})\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 18)\n" + 
+			"	goo(()-> { \n" + 
+			"	^^^\n" + 
+			"The method goo(J) in the type X is not applicable for the arguments (() -> {\n" + 
+			"  while (f)    ;\n" + 
+			"})\n" + 
+			"----------\n");
+}
+public void test005() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"   final boolean f = true;\n" +
+				"	static void goo(J j) {\n" +
+				"		System.out.println(\"goo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		final boolean x = true;\n" +
+				"		goo(()-> { \n" +
+				"			final boolean y = true;\n" +
+				"			while (y); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (x); \n" +
+				"			});\n" +
+				"		goo(()-> { \n" +
+				"			while (f); \n" +
+				"			});\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 19)\n" + 
+			"	while (f); \n" + 
+			"	       ^\n" + 
+			"Cannot make a static reference to the non-static field f\n" + 
+			"----------\n");
+}
+public void test006() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				" public static interface StringToInt {\n" +
+				"  	int stoi(String s);\n" +
+				" }\n" +
+				" public static interface ReduceInt {\n" +
+				"     int reduce(int a, int b);\n" +
+				" }\n" +
+				" void foo(StringToInt s) { }\n" +
+				" void bar(ReduceInt r) { }\n" +
+				" void bar() {\n" +
+				"     bar((int x, int y) -> x+y); //SingleVariableDeclarations are OK\n" +
+				"     foo(s -> s.length());\n" +
+				"     foo((s) -> s.length());\n" +
+				"     foo((String s) -> s.length()); //SingleVariableDeclaration is OK\n" +
+				"     bar((x, y) -> x+y);\n" +
+				" }\n" +
+				"}\n",
+			},
+			"");
+}
+public void test007() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	void foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void goo(J j) {\n" +
+				"		System.out.println(\"goo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		goo(()-> 10); \n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 9)\n" + 
+			"	goo(()-> 10); \n" + 
+			"	         ^^\n" + 
+			"Void methods cannot return a value\n" + 
+			"----------\n");
+}
+public void test008() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Object foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	String foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()->null));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+public void test009() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Object foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	void foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()-> {}));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+public void test010() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Object foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	void foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()-> foo(()->null)));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test011() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	String foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()-> \"Hello\" ));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+public void test012() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	String foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()-> 1234 ));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test013() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"interface J  {\n" +
+				"	Integer foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(()-> 1234 ));\n" +
+				"	}\n" +
+				"	static String foo(I i) {\n" +
+				"		return(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static String foo(J j) {\n" +
+				"		return(\"foo(J)\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test014() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Integer foo();\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				" \n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(()-> new Integer(10));\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test015() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"interface I {\n" +
+				"	Integer foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				" \n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(()-> new Integer(10));\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test016() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface O {\n" +
+				"	Object foo();\n" +
+				"}\n" +
+				"interface S {\n" +
+				"	String foo();\n" +
+				"}\n" +
+				"interface I {\n" +
+				"	O foo();\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	S foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(()-> ()-> \"String\");\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+public void test017() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface J {\n" +
+				"	int foo();\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(()-> new Integer(10));\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+public void test018() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	X [] foo(int x);\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I x) {\n" +
+				"            System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	I i = X[]::new;\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(X[]::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test019() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	void foo(int x);\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I x) {\n" +
+				"            System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	I i = X[]::new;\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(X[]::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+
+public void test020() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	Y foo();\n" +
+				"}\n" +
+				"class Y {\n" +
+				"	Y() {\n" +
+				"	}\n" +
+				"	\n" +
+				"	Y(int x) {\n" +
+				"	}\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 20)\n" + 
+			"	foo(Y::new);\n" + 
+			"	^^^\n" + 
+			"The method foo(I) is ambiguous for the type X\n" + 
+			"----------\n");
+}
+public void test021() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	Y foo();\n" +
+				"}\n" +
+				"class Y {\n" +
+				"	private Y() {\n" +
+				"	}\n" +
+				"	\n" +
+				"	Y(int x) {\n" +
+				"	}\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"       System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"       System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test022() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	Y foo();\n" +
+				"}\n" +
+				"class Y {\n" +
+				"	Y(float f) {\n" +
+				"       System.out.println(\"Y(float)\");\n" +
+				"	}\n" +
+				"	\n" +
+				"	Y(int x) {\n" +
+				"       System.out.println(\"Y(int)\");\n" +
+				"	}\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"       i.foo(10);\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"       j.foo();\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"Y(int)");
+}
+public void test023() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	Y foo();\n" +
+				"}\n" +
+				"class Y {\n" +
+				"	Y(int ... x) {\n" +
+				"	}\n" +
+				"	\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 18)\n" + 
+			"	foo(Y::new);\n" + 
+			"	^^^\n" + 
+			"The method foo(I) is ambiguous for the type X\n" + 
+			"----------\n");
+}
+public void test024() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"class Y {\n" +
+				"	Y(int x) {\n" +
+				"	}\n" +
+				"	\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 18)\n" + 
+			"	foo(Y::new);\n" + 
+			"	^^^\n" + 
+			"The method foo(I) is ambiguous for the type X\n" + 
+			"----------\n");
+}
+public void test025() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X foo(int x);\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"    Y(int x) {\n" +
+				"    }\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"            System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"            System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test026() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X foo(int x);\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"    <T> Y(int x) {\n" +
+				"    }\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"            System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"            System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 19)\n" + 
+			"	foo(Y::new);\n" + 
+			"	^^^\n" + 
+			"The method foo(I) is ambiguous for the type X\n" + 
+			"----------\n");
+}
+public void test027() { // javac 8b115 complains of ambiguity here.
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X foo(int x);\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"    <T> Y(int x) {\n" +
+				"    }\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"            System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"            System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y::<String>new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test028() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y [] foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X [] foo();\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(Y []::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(I)");
+}
+public void test029() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y [] foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X [] foo();\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(X []::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 17)\n" + 
+			"	foo(X []::new);\n" + 
+			"	    ^^^^^^^^^\n" + 
+			"Constructed array X[] cannot be assigned to Y[] as required in the interface descriptor  \n" + 
+			"----------\n");
+}
+public void test030() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I {\n" +
+				"	Y [] foo(int x);\n" +
+				"}\n" +
+				"interface J {\n" +
+				"	X [] foo(int x);\n" +
+				"}\n" +
+				"class Y extends X {\n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static void foo(I i) {\n" +
+				"		System.out.println(\"foo(I)\");\n" +
+				"	}\n" +
+				"	static void foo(J j) {\n" +
+				"		System.out.println(\"foo(J)\");\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(X []::new);\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(J)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test031() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"public class X<T> {\n" +
+				"	void foo(X<String> s) {\n" +
+				"       System.out.println(\"foo(X<String>)\");\n" +
+				"   }\n" +
+				"	public static void main(String[] args) {\n" +
+				"		new X<String>().foo(new X<>());\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"foo(X<String>)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test032() {
+	this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X<T> {\n" +
+				"    void foo(X<String> s, Object o) {\n" +
+				"        System.out.println(\"foo(X<String>)\");\n" +
+				"    }\n" +
+				"    void foo(X xs, String s) {\n" +
+				"        System.out.println(\"foo(X<String>)\");\n" +
+				"    }\n" +
+				"    public static void main(String[] args) {\n" +
+				"        new X<String>().foo(new X<>(), \"Hello\");\n" +
+				"    }\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. WARNING in X.java (at line 5)\n" + 
+			"	void foo(X xs, String s) {\n" + 
+			"	         ^\n" + 
+			"X is a raw type. References to generic type X<T> should be parameterized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 9)\n" + 
+			"	new X<String>().foo(new X<>(), \"Hello\");\n" + 
+			"	                ^^^\n" + 
+			"The method foo(X<String>, Object) is ambiguous for the type X<String>\n" + 
+			"----------\n");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401850, [1.8][compiler] Compiler fails to type poly allocation expressions in method invocation contexts
+public void test033() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"class Y<T> {}\n" +
+				"public class X<T> extends Y<T> {\n" +
+				"    void foo(X<String> s) {\n" +
+				"        System.out.println(\"foo(X<String>)\");\n" +
+				"    }\n" +
+				"    void foo(Y<String> y) {\n" +
+				"        System.out.println(\"foo(Y<String>)\");\n" +
+				"    }\n" +
+				"    public static void main(String[] args) {\n" +
+				"        new X<String>().foo(new X<>());\n" +
+				"    }\n" +
+				"}\n",
+			},
+			"foo(X<String>)");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422050, [1.8][compiler] Overloaded method call with poly-conditional expression rejected by the compiler
+public void test422050() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I { \n" +
+				"	int foo(); \n" +
+				"}\n" +
+				"interface J { \n" +
+				"	double foo(); \n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static int foo(I i) {\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	static int foo(J j) {\n" +
+				"		return 1;\n" +
+				"	}\n" +
+				"	public static void main(String argv[]) {\n" +
+				"		System.out.println(foo (() -> true ? 0 : 1));\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"0");
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=422050, [1.8][compiler] Overloaded method call with poly-conditional expression rejected by the compiler
+public void test422050a() {
+	this.runConformTest(
+			new String[] {
+				"X.java",
+				"interface I { \n" +
+				"	Integer foo(); \n" +
+				"}\n" +
+				"interface J { \n" +
+				"	void foo(); \n" +
+				"}\n" +
+				"public class X {\n" +
+				"	static int foo(I i) {\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	static int foo(J j) {\n" +
+				"		return 1;\n" +
+				"	}\n" +
+				"	public static void main(String argv[]) {\n" +
+				"		System.out.println(foo (() -> foo((I) null)));\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"0");
+}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index c5c27b4..d1fff24 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -139,6 +139,7 @@
 	since_1_8.add(NullTypeAnnotationTest.class);
 	since_1_8.add(NegativeLambdaExpressionsTest.class);
 	since_1_8.add(LambdaExpressionsTest.class);
+	since_1_8.add(OverloadResolutionTest8.class);
 	since_1_8.add(Jsr335ClassFileTest.class);
 	since_1_8.add(ExpressionContextTests.class);
 	since_1_8.add(InterfaceMethodsTest.class);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
index 17d56dd..b2c008c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava8Tests.java
@@ -27,16 +27,23 @@
 import org.eclipse.jdt.core.tests.compiler.parser.LambdaExpressionSyntaxTest;
 import org.eclipse.jdt.core.tests.compiler.parser.ReferenceExpressionSyntaxTest;
 import org.eclipse.jdt.core.tests.compiler.parser.TypeAnnotationSyntaxTest;
+import org.eclipse.jdt.core.tests.compiler.regression.ClassFileReaderTest_1_8;
+import org.eclipse.jdt.core.tests.compiler.regression.Deprecated18Test;
 import org.eclipse.jdt.core.tests.compiler.regression.ExpressionContextTests;
 import org.eclipse.jdt.core.tests.compiler.regression.CompilerInvocationTests;
 import org.eclipse.jdt.core.tests.compiler.regression.FlowAnalysisTest8;
 import org.eclipse.jdt.core.tests.compiler.regression.GrammarCoverageTests308;
 import org.eclipse.jdt.core.tests.compiler.regression.InterfaceMethodsTest;
+import org.eclipse.jdt.core.tests.compiler.regression.JSR308SpecSnippetTests;
 import org.eclipse.jdt.core.tests.compiler.regression.Jsr335ClassFileTest;
 import org.eclipse.jdt.core.tests.compiler.regression.LambdaExpressionsTest;
+import org.eclipse.jdt.core.tests.compiler.regression.MethodParametersAttributeTest;
 import org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest;
 import org.eclipse.jdt.core.tests.compiler.regression.NegativeTypeAnnotationTest;
 import org.eclipse.jdt.core.tests.compiler.regression.NullTypeAnnotationTest;
+import org.eclipse.jdt.core.tests.compiler.regression.OverloadResolutionTest8;
+import org.eclipse.jdt.core.tests.compiler.regression.RepeatableAnnotationTest;
+import org.eclipse.jdt.core.tests.compiler.regression.TypeAnnotationTest;
 import org.eclipse.jdt.core.tests.dom.ASTConverter15JLS8Test;
 import org.eclipse.jdt.core.tests.dom.ASTConverter18Test;
 import org.eclipse.jdt.core.tests.dom.ASTConverterAST8Test;
@@ -44,6 +51,7 @@
 import org.eclipse.jdt.core.tests.dom.ASTConverterTestAST8_2;
 import org.eclipse.jdt.core.tests.dom.ConverterTestSetup;
 import org.eclipse.jdt.core.tests.dom.TypeAnnotationsConverterTest;
+import org.eclipse.jdt.core.tests.dom.TypeBindingTests308;
 import org.eclipse.jdt.core.tests.formatter.FormatterJSR308Tests;
 import org.eclipse.jdt.core.tests.formatter.FormatterJSR335Tests;
 import org.eclipse.jdt.core.tests.model.JavaSearchBugs8Tests;
@@ -59,6 +67,7 @@
 			LambdaExpressionSyntaxTest.class,
 			NegativeLambdaExpressionsTest.class,
 			LambdaExpressionsTest.class,
+			OverloadResolutionTest8.class,
 			Jsr335ClassFileTest.class,
 			NegativeTypeAnnotationTest.class,
 			TypeAnnotationSyntaxTest.class,
@@ -73,6 +82,12 @@
 			FormatterJSR335Tests.class,
 			FormatterJSR308Tests.class,
 			JavaSearchBugs8Tests.class,
+			TypeAnnotationTest.class,
+			JSR308SpecSnippetTests.class,
+			Deprecated18Test.class,
+			MethodParametersAttributeTest.class,
+			ClassFileReaderTest_1_8.class,
+			RepeatableAnnotationTest.class,
 		};
 	}
 	
@@ -85,6 +100,7 @@
 				ASTConverter15JLS8Test.class,
 				ASTConverter18Test.class,
 				ASTRewritingTest.class,
+				TypeBindingTests308.class,
 		};
 	}
 	public static Test suite() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index c0907ae..c48f3c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -949,10 +949,6 @@
 	public void tagAsHavingErrors() {
 		this.ignoreFurtherInvestigation = true;
 	}
-	
-	public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
-		// Nothing to do for this context;
-	}
 
 //{ObjectTeams: and remove it again:
 	public void resetErrorFlag() {
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 346e26a..0c104c0 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
@@ -365,34 +365,24 @@
 
 public TypeBinding resolveType(BlockScope scope) {
 	// Propagate the type checking to the arguments, and check if the constructor is defined.
-	this.constant = Constant.NotAConstant;
-	if (this.type == null) {
-		// initialization of an enum constant
-		this.resolvedType = scope.enclosingReceiverType();
-	} else {
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+	final CompilerOptions compilerOptions = scope.compilerOptions();
+	if (this.constant != Constant.NotAConstant) {
+		this.constant = Constant.NotAConstant;
+		if (this.type == null) {
+			// initialization of an enum constant
+			this.resolvedType = scope.enclosingReceiverType();
+		} else {
 //{ObjectTeams: support detection of new path.R():
-		this.type.bits |= IsAllocationType;
+			this.type.bits |= IsAllocationType;
 // SH}
-		this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
-		checkIllegalNullAnnotation(scope, this.resolvedType);
-		checkParameterizedAllocation: {
-			if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
-				ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
-				if (currentType == null) return currentType;
-				do {
-					// isStatic() is answering true for toplevel types
-					if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
-					if (currentType.isRawType()) break checkParameterizedAllocation;
-				} while ((currentType = currentType.enclosingType())!= null);
-				ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
-				for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
-					if (qRef.typeArguments[i] != null) {
-						scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
-						break;
-					}
-				}
+			this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+			if (isDiamond && this.typeExpected == null && this.expressionContext == INVOCATION_CONTEXT && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+				return this.resolvedType = new PolyTypeBinding(this);
 			}
 		}
+	} else {
+		this.resolvedType = this.type.resolvedType;
 	}
 	// will check for null after args are resolved
 
@@ -408,11 +398,10 @@
 	}
 // SH}
 
-	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
 	// resolve type arguments (for generic constructor call)
 	if (this.typeArguments != null) {
 		int length = this.typeArguments.length;
-		boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+		boolean argHasError = compilerOptions.sourceLevel < ClassFileConstants.JDK1_5;
 		this.genericTypeArguments = new TypeBinding[length];
 		for (int i = 0; i < length; i++) {
 			TypeReference typeReference = this.typeArguments[i];
@@ -473,7 +462,7 @@
 				for (int i = length; --i >= 0;) {
 					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
 				}
-				this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this);
+				this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
 				if (this.binding != null && !this.binding.isValidBinding()) {
 					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
 					// record the closest match, for clients who may still need hint about possible method match
@@ -563,7 +552,6 @@
 	if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
  		checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, null, argumentTypes, scope);
  	}
-	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);
@@ -776,14 +764,14 @@
 	this.expressionContext = context;
 }
 
+public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+	return this.type.resolvedType != null && this.type.resolvedType.actualType().isCompatibleWith(left.actualType());
+}
+
 public boolean isPolyExpression() {
 	return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
 			this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
 }
-
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
-	return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
-}
 /**
  * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType()
  */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 5c9539b..cfbb24a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -810,10 +810,6 @@
 	this.ignoreFurtherInvestigation = true;
 }
 
-public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
-	// Nothing to do for this context;
-}
-
 //{ObjectTeams: and let us remove it again:
 public void resetErrorFlag() {
 	this.ignoreFurtherInvestigation = false;
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 06f318c..53fc31e 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
@@ -461,7 +461,7 @@
 			
 			if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE || this.originalValueIfFalseType.kind() == Binding.POLY_TYPE) {
 				this.isPolyExpression = true;
-				return new PolyTypeBinding(this);
+				return this.resolvedType = new PolyTypeBinding(this);
 			}
 		} else {
 			if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE)
@@ -649,6 +649,10 @@
 		this.expressionContext = context;
 	}
 	
+	public boolean isPertinentToApplicability() {
+		return this.valueIfTrue.isPertinentToApplicability() && this.valueIfFalse.isPertinentToApplicability();
+	}
+	
 	public boolean isPolyExpression() throws UnsupportedOperationException {
 		if (this.expressionContext != ASSIGNMENT_CONTEXT && this.expressionContext != INVOCATION_CONTEXT)
 			return false;
@@ -660,10 +664,10 @@
 		return this.valueIfTrue.isCompatibleWith(left, scope) && this.valueIfFalse.isCompatibleWith(left, scope);
 	}
 	
-	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
 		return isPolyExpression() ?
-				this.valueIfTrue.tIsMoreSpecific(t, s) && this.valueIfFalse.tIsMoreSpecific(t, s):
-				super.tIsMoreSpecific(t, s);
+				this.valueIfTrue.sIsMoreSpecific(s, t) && this.valueIfFalse.sIsMoreSpecific(s, t):
+				super.sIsMoreSpecific(s, t);
 	}
 	
 	public void tagAsEllipsisArgument() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 0c336b4..2c064a9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -496,7 +496,7 @@
 					for (int i = length; --i >= 0;) {
 						pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
 					}
-					this.binding = scope.findMethod(receiverType, TypeConstants.INIT, pseudoArgs, this);
+					this.binding = scope.findMethod(receiverType, TypeConstants.INIT, pseudoArgs, this, false);
 					if (this.binding != null && !this.binding.isValidBinding()) {
 						MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
 						// record the closest match, for clients who may still need hint about possible method match
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 0a79e7f..66e0473 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1133,6 +1133,10 @@
 	return this.constant;
 }
 
+public boolean isPertinentToApplicability() {
+	return true;
+}
+
 /**
  * Returns the type of the expression after required implicit conversions. When expression type gets promoted
  * or inserted a generic cast, the converted type will differ from the resolved type (surface side-effects from
@@ -1323,18 +1327,11 @@
 	throw new UnsupportedOperationException("Unexpected control flow, should not have reached Expression.isCompatibleWith"); //$NON-NLS-1$
 }
 
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
 	TypeBinding expressionType = this.resolvedType;
 	if (expressionType == null || !expressionType.isValidBinding()) // Shouldn't get here, just to play it safe
 		return false; // trigger ambiguity.
-	
-	if (TypeBinding.equalsEquals(t.findSuperTypeOriginatingFrom(s), s))
-		return true;
-	
-	final boolean tIsBaseType = t.isBaseType();
-	final boolean sIsBaseType = s.isBaseType();
-	
-	return expressionType.isBaseType() ? tIsBaseType && !sIsBaseType : !tIsBaseType && sIsBaseType;
+	return s.findSuperTypeOriginatingFrom(t) != null;
 }
 
 public void tagAsEllipsisArgument() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index b2e589d..1a346c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -32,7 +32,6 @@
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBindingVisitor;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 
 public abstract class FunctionalExpression extends Expression {
 	
@@ -42,8 +41,8 @@
 	protected MethodBinding actualMethodBinding;  // void of synthetics.
 	boolean ignoreFurtherInvestigation;
 	protected ExpressionContext expressionContext = VANILLA_CONTEXT;
-	protected SimpleLookupTable resultExpressions;
-	protected boolean hasIgnoredMandatoryErrors = false;
+	static Expression [] NO_EXPRESSIONS = new Expression[0];
+	protected Expression [] resultExpressions = NO_EXPRESSIONS;
 	protected CompilationResult compilationResult;
 	protected BlockScope enclosingScope;
 	protected boolean ellipsisArgument;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 7379f43..66182df 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     TU Berlin - implementation of @role tag
@@ -459,7 +463,7 @@
 					if (CharOperation.equals(resolvedType.sourceName(), fieldRef.token)) {
 						fieldRef.methodBinding = scope.getConstructor(resolvedType, Binding.NO_TYPES, fieldRef);
 					} else {
-						fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef);
+						fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef, false);
 					}
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 2a290cb..66339a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -23,7 +23,6 @@
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.core.compiler.CategorizedProblem;
-import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.ClassFile;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -61,10 +60,10 @@
 import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
 import org.eclipse.jdt.internal.compiler.problem.AbortType;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 
 public class LambdaExpression extends FunctionalExpression implements ReferenceContext, ProblemSeverities {
 	public Argument [] arguments;
+	private TypeBinding [] argumentTypes = Binding.NO_PARAMETERS;
 	public Statement body;
 	public boolean hasParentheses;
 	public MethodScope scope;
@@ -73,7 +72,6 @@
 	private boolean shapeAnalysisComplete = false;
 	private boolean returnsValue;
 	private boolean returnsVoid;
-	private boolean throwsException;
 	private LambdaExpression original = this;
 	private SyntheticArgumentBinding[] outerLocalVariables = NO_SYNTHETIC_ARGUMENTS;
 	private int outerLocalVariablesSlotSize = 0;
@@ -145,7 +143,7 @@
 		this.enclosingScope = blockScope;
 		
 		if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
-			return new PolyTypeBinding(this);
+			return this.resolvedType = new PolyTypeBinding(this);
 		} 
 		
 		MethodScope methodScope = blockScope.methodScope();
@@ -186,6 +184,9 @@
 		TypeBinding[] newParameters = new TypeBinding[length];
 
 		AnnotationBinding [][] parameterAnnotations = null;
+		if (!argumentsTypeElided) {
+			this.argumentTypes = new TypeBinding[length];
+		}
 		for (int i = 0; i < length; i++) {
 			Argument argument = this.arguments[i];
 			if (argument.isVarArgs()) {
@@ -199,7 +200,7 @@
 			
 			TypeBinding parameterType;
 			final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null;
-			parameterType = argumentsTypeElided ? expectedParameterType : argument.type.resolveType(this.scope, true /* check bounds*/);
+			parameterType = argumentsTypeElided ? expectedParameterType : (this.argumentTypes[i] = argument.type.resolveType(this.scope, true /* check bounds*/));
 			if (parameterType == null) {
 				buggyArguments = true;
 			} else if (parameterType == TypeBinding.VOID) {
@@ -407,6 +408,18 @@
 		}
 	}
 
+	public boolean isPertinentToApplicability() {
+		if (argumentsTypeElided())
+			return false;
+		
+		Expression [] returnExpressions = this.resultExpressions;
+		for (int i = 0, length = returnExpressions.length; i < length; i++) {
+			if (!returnExpressions[i].isPertinentToApplicability())
+				return false;
+		}
+		return true;
+	}
+	
 	public StringBuffer printExpression(int tab, StringBuffer output) {
 		int parenthesesCount = (this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
 		String suffix = ""; //$NON-NLS-1$
@@ -450,10 +463,6 @@
 		return this.scope;
 	}
 		
-	protected boolean errorEqualsIncompatibility() {
-		return this.original.shapeAnalysisComplete; // so as not to abort shape analysis.
-	}
-	
 	public boolean isCompatibleWith(final TypeBinding left, final Scope someScope) {
 		
 		final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
@@ -463,107 +472,125 @@
 		if (sam.parameters.length != this.arguments.length)
 			return false;
 		
-		if (!this.shapeAnalysisComplete && this.body instanceof Expression) {
-			Expression expression = (Expression) this.body;
-			this.voidCompatible = expression.statementExpression();
-			this.valueCompatible = true;
-			this.shapeAnalysisComplete = true;
-		}
-
-		if (this.shapeAnalysisComplete) {
-			if (squarePegInRoundHole(sam))
-				return false;
-		} 
-
-		IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
-		this.hasIgnoredMandatoryErrors = false;
-		try {
-			final LambdaExpression copy = copy();
-			if (copy == null)
-				return false;
-			copy.setExpressionContext(this.expressionContext);
-			copy.setExpectedType(left);
-			if (this.resultExpressions == null)
-				this.resultExpressions = new SimpleLookupTable(); // gather result expressions for most specific method analysis.
-			this.resultExpressions.put(left, new Expression[0]);
-			copy.resolveType(this.enclosingScope);
-			if (!this.shapeAnalysisComplete) {
-				boolean lambdaIsFubar = this.hasIgnoredMandatoryErrors; // capture now, before doesNotCompleteNormally which runs analyzeCode on lambda body *without* the enclosing context being analyzed 
-				if (!this.returnsVoid && !this.returnsValue && this.throwsException) {  // () -> { throw new Exception(); } is value compatible.
-					Block block = (Block) this.body;
-					final Statement[] statements = block.statements;
-					final int statementsLength = statements == null ? 0 : statements.length;
-					Statement ultimateStatement = statementsLength == 0 ? null : statements[statementsLength - 1];
-					this.valueCompatible = ultimateStatement instanceof ThrowStatement ? true: copy.doesNotCompleteNormally(); 
-				}
-				this.shapeAnalysisComplete = true;
-				if (squarePegInRoundHole(sam) || lambdaIsFubar)
+		if (!this.shapeAnalysisComplete) {
+			IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
+			try {
+				final LambdaExpression copy = copy();
+				if (copy == null)
 					return false;
+				copy.setExpressionContext(this.expressionContext);
+				copy.setExpectedType(left);
+				copy.resolveType(this.enclosingScope);
+
+				if (!argumentsTypeElided()) {
+					this.argumentTypes = copy.argumentTypes;
+				}
+			
+				if (this.body instanceof Block) {
+					if (!this.returnsVoid) {
+						this.valueCompatible = copy.doesNotCompleteNormally();
+					}
+				} else {
+					this.voidCompatible = ((Expression) this.body).statementExpression();
+				}
+			
+			} finally {
+				this.shapeAnalysisComplete = true;
+				this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
 			}
-		} catch (IncongruentLambdaException e) {
-			return false;
-		} finally {
-			this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
-			this.hasIgnoredMandatoryErrors = false;
 		}
+
+		if (sam.returnType.id == TypeIds.T_void) {
+			if (!this.voidCompatible)
+				return false;
+		} else {
+			if (!this.valueCompatible)
+				return false;
+		}
+		
+		if (!isPertinentToApplicability())
+			return true;
+	
+		Expression [] returnExpressions = this.resultExpressions;
+		for (int i = 0, length = returnExpressions.length; i < length; i++) {
+			if (returnExpressions[i] instanceof FunctionalExpression) { // don't want to use the resolvedType - polluted from some other overload resolution candidate
+				if (!returnExpressions[i].isCompatibleWith(sam.returnType, this.enclosingScope))
+					return false;
+			} else {
+				if (this.enclosingScope.parameterCompatibilityLevel(returnExpressions[i].resolvedType, sam.returnType) == Scope.NOT_COMPATIBLE) {
+					if (sam.returnType.id != TypeIds.T_void || this.body instanceof Block)
+						return false;
+				}
+			}
+		}
+	
+		TypeBinding [] samPararameterTypes = sam.parameters;
+		for (int i = 0, length = samPararameterTypes.length; i < length; i++) { // lengths known to be equal.
+			if (TypeBinding.notEquals(samPararameterTypes[i], this.argumentTypes[i]))
+				return false;
+		}
+
 		return true;
 	}
 	
-	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
-		/* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here, 
-		   but have been left in for completeness/documentation sakes. These should be cheap anyways. 
-		*/
+	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
 		
-		// Both t and s are functional interface types ... 
-		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
-		if (tSam == null || !tSam.isValidBinding())
+		// 15.12.2.5 
+		
+		if (TypeBinding.equalsEquals(s,  t))
+			return true;
+		
+		if (argumentsTypeElided() || t.findSuperTypeOriginatingFrom(s) != null)
 			return false;
+		
+		s = s.capture(this.enclosingScope, this.sourceEnd);
 		MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
 		if (sSam == null || !sSam.isValidBinding())
 			return false;
-		
-		// t should neither be a subinterface nor a superinterface of s
-		if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+		TypeBinding r1 = sSam.returnType;
+		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		if (tSam == null || !tSam.isValidBinding())
 			return false;
-
-		// If the lambda expression's parameters have inferred types, then the descriptor parameter types of t are the same as the descriptor parameter types of s.
-		if (argumentsTypeElided()) {
-			if (tSam.parameters.length != sSam.parameters.length)
-				return false;
-			for (int i = 0, length = tSam.parameters.length; i < length; i++) {
-				if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
-					return false;
-			}
-		}
+		TypeBinding r2 = tSam.returnType;
 		
-		// either the descriptor return type of s is void or ...
-		if (sSam.returnType.id == TypeIds.T_void)
+		if (r2.id == TypeIds.T_void)
 			return true;
 		
-		/* ... or for all result expressions in the lambda body (or for the body itself if the body is an expression), 
-           the descriptor return type of the capture of T is more specific than the descriptor return type of S.
-		*/
-		Expression [] returnExpressions = (Expression[]) this.resultExpressions.get(t); // should be same as for s
-		int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
-		if (returnExpressionsLength == 0)
-			return true; // as good as or as bad as false.
+		if (r1.id == TypeIds.T_void)
+			return false;
 		
-		t = t.capture(this.enclosingScope, this.sourceEnd);
-		tSam = t.getSingleAbstractMethod(this.enclosingScope);
-		for (int i = 0; i < returnExpressionsLength; i++) {
-			Expression resultExpression = returnExpressions[i];
-			if (!resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType))
-				return false;
-		}
-		return true;
-	}
-
-	private boolean squarePegInRoundHole(final MethodBinding sam) {
-		if (sam.returnType.id == TypeIds.T_void) {
-			if (!this.voidCompatible)
+		// r1 <: r2
+		if (r1.isCompatibleWith(r2))
+			return true;
+		
+		Expression [] returnExpressions = this.resultExpressions;
+		int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
+		
+		int i;
+		// r1 is a primitive type, r2 is a reference type, and each result expression is a standalone expression (15.2) of a primitive type
+		if (r1.isBaseType() && !r2.isBaseType()) {
+			for (i = 0; i < returnExpressionsLength; i++) {
+				if (returnExpressions[i].isPolyExpression() || !returnExpressions[i].resolvedType.isBaseType())
+					break;
+			}
+			if (i == returnExpressionsLength)
 				return true;
-		} else {
-			if (!this.valueCompatible)
+		}
+		if (!r1.isBaseType() && r2.isBaseType()) {
+			for (i = 0; i < returnExpressionsLength; i++) {
+				if (returnExpressions[i].resolvedType.isBaseType())
+					break;
+			}
+			if (i == returnExpressionsLength)
+				return true;
+		}
+		if (r1.isFunctionalInterface(this.enclosingScope) && r2.isFunctionalInterface(this.enclosingScope)) {
+			for (i = 0; i < returnExpressionsLength; i++) {
+				Expression resultExpression = returnExpressions[i];
+				if (!resultExpression.sIsMoreSpecific(r1, r2))
+					break;
+			}
+			if (i == returnExpressionsLength)
 				return true;
 		}
 		return false;
@@ -584,15 +611,22 @@
 	public void returnsExpression(Expression expression, TypeBinding resultType) {
 		if (this.original == this) // not in overload resolution context.
 			return;
+		if (this.body instanceof Expression) {
+			this.original.valueCompatible = resultType != null && resultType.id != TypeIds.T_void;
+			this.original.resultExpressions = new Expression[1];
+			this.original.resultExpressions[0] = expression;
+			return; // void compatibility determined via statementExpression()
+		}
 		if (expression != null) {
 			this.original.returnsValue = true;
 			this.original.voidCompatible = false;
 			this.original.valueCompatible = !this.original.returnsVoid;
 			if (resultType != null) {
-				Expression [] results = (Expression[]) this.original.resultExpressions.get(this.expectedType);
-				int resultsLength = results.length;
-				System.arraycopy(results, 0, results = new Expression[resultsLength + 1], 0, resultsLength);
-				results[resultsLength] = expression;
+				Expression [] returnExpressions = this.original.resultExpressions;
+				int resultsLength = returnExpressions.length;
+				System.arraycopy(returnExpressions, 0, returnExpressions = new Expression[resultsLength + 1], 0, resultsLength);
+				returnExpressions[resultsLength] = expression;
+				this.original.resultExpressions = returnExpressions;
 			}
 		} else {
 			this.original.returnsVoid = true;
@@ -600,12 +634,6 @@
 			this.original.voidCompatible = !this.original.returnsValue;
 		}
 	}
-
-	public void throwsException(TypeBinding exceptionType) {
-		if (this.expressionContext != INVOCATION_CONTEXT)
-			return;
-		this.original.throwsException = true;
-	}
 	
 	public CompilationResult compilationResult() {
 		return this.compilationResult;
@@ -655,21 +683,6 @@
 		}
 	}
 	
-	public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
-		// 15.27.3 requires exception throw related errors to not influence congruence. Other errors should. Also don't abort shape analysis.
-		switch (problemId) {
-			case IProblem.UnhandledExceptionOnAutoClose:
-			case IProblem.UnhandledExceptionInDefaultConstructor:
-			case IProblem.UnhandledException:
-				return;
-			default: 
-				if (errorEqualsIncompatibility())
-					throw new IncongruentLambdaException();
-				this.original().hasIgnoredMandatoryErrors = true;
-				return;
-		}
-	}
-
 	public void generateCode(ClassScope classScope, ClassFile classFile) {
 		int problemResetPC = 0;
 		classFile.codeStream.wideMode = false;
@@ -803,7 +816,4 @@
 		}
 		return this.actualMethodBinding;
 	}
-}
-class IncongruentLambdaException extends RuntimeException {
-	private static final long serialVersionUID = 4145723509219836114L;
 }
\ No newline at end of file
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 5176ad0..d2f4a4a 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
@@ -863,7 +863,7 @@
 				this.binding =
 					this.receiver.isImplicitThis()
 						? scope.getImplicitMethod(this.selector, pseudoArgs, this)
-						: scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this);
+						: scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this, false);
 				if (this.binding != null && !this.binding.isValidBinding()) {
 					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
 					// record the closest match, for clients who may still need hint about possible method match
@@ -1319,7 +1319,7 @@
 		// methods found in a predefined confined type are actually methods of Object
 		// (except for _OT$getTeam() which is generated for each role):
 		ReferenceBinding object = scope.getJavaLangObject();
-		this.binding = scope.findMethod(object, this.binding.selector, this.binding.parameters, this);
+		this.binding = scope.findMethod(object, this.binding.selector, this.binding.parameters, this, false);
 	}
 
 	// check whether all anchors in the signature are final
@@ -1472,8 +1472,8 @@
 	return false;
 }
 
-public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
-	return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+	return isPolyExpression() ? !s.isBaseType() && t.isBaseType() : super.sIsMoreSpecific(s, t);
 }
 
 public void setFieldIndex(int depth) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
index 7dbbe88..66ef722 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -361,6 +361,7 @@
 	    	keep = ((ClassScope) scope).superTypeReference;
 	    	((ClassScope) scope).superTypeReference = null;
 	    }
+	    final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
 		int argLength = this.typeArguments.length;
 		TypeBinding[] argTypes = new TypeBinding[argLength];
 		boolean argHasError = false;
@@ -397,7 +398,6 @@
 				return null;
 		}
 
-		final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
 		TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
 		if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
 			boolean isCompliant15 = scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
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 2994364..9d3d4ec 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
@@ -522,7 +522,7 @@
 					for (int i = length; --i >= 0;) {
 						pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
 					}
-					this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this);
+					this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this, false);
 					if (this.binding != null && !this.binding.isValidBinding()) {
 						MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
 						// record the closest match, for clients who may still need hint about possible method match
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 7c7bb6f..5a9d040 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
@@ -55,7 +55,6 @@
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 
 public class ReferenceExpression extends FunctionalExpression implements InvocationSite {
 	
@@ -70,6 +69,7 @@
 	
 	MethodBinding syntheticAccessor;	// synthetic accessor for inner-emulation
 	private int depth;
+	private MethodBinding exactMethodBinding; // != null ==> exact method reference.
 	
 	public ReferenceExpression(CompilationResult compilationResult, Expression lhs, TypeReference [] typeArguments, char [] selector, int sourceEnd) {
 		super(compilationResult);
@@ -85,9 +85,9 @@
 		SourceTypeBinding sourceType = currentScope.enclosingSourceType();
 		if (this.receiverType.isArrayType()) {
 			if (isConstructorReference()) {
-				this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
+				this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
 			} else if (CharOperation.equals(this.selector, TypeConstants.CLONE)) {
-				this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
+				this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
 			}
 		} else if (this.syntheticAccessor != null) {
 			if (this.lhs.isSuper() || isMethodReference())
@@ -258,7 +258,10 @@
     	}
 
     	if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
-			return new PolyTypeBinding(this);
+    		if (isConstructorReference()) {
+    			this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
+    		}
+			return this.resolvedType = new PolyTypeBinding(this);
 		}
 		super.resolveType(scope);
 		
@@ -303,11 +306,12 @@
         		scope.problemReporter().invalidArrayConstructorReference(this, lhsType, descriptorParameters);
         		return this.resolvedType = null;
         	}
-        	if (!lhsType.isCompatibleWith(this.descriptor.returnType)) {
+        	if (!lhsType.isCompatibleWith(this.descriptor.returnType) && this.descriptor.returnType.id != TypeIds.T_void) {
         		scope.problemReporter().constructedArrayIncompatible(this, lhsType, this.descriptor.returnType);
         		return this.resolvedType = null;
         	}
-        	return this.resolvedType; // No binding construction possible right now. Code generator will have to conjure up a rabbit.
+        	this.binding = this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
+        	return this.resolvedType;
         }
 		
 		this.haveReceiver = true;
@@ -577,7 +581,7 @@
 	}
 
 	public boolean isCompatibleWith(TypeBinding left, Scope scope) {
-		// 15.28.1
+		// 15.28.2
 		final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
 		if (sam == null || !sam.isValidBinding())
 			return false;
@@ -587,58 +591,45 @@
 		try {
 			this.binding = null;
 			resolveType(this.enclosingScope);
-		} catch (IncongruentLambdaException e) {
-			return false;
 		} finally {
 			this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
 			isCompatible = this.binding != null && this.binding.isValidBinding();
-			if (isCompatible) {
-				if (this.resultExpressions == null)
-					this.resultExpressions = new SimpleLookupTable(); // gather for more specific analysis later.
-				this.resultExpressions.put(left, this.binding.returnType);
-			}
 			this.binding = null;
 			setExpectedType(null);
 		}
 		return isCompatible;
 	}
-	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
-		/* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here, 
-		   but have been left in for completeness/documentation sakes. These should be cheap anyways. 
-		*/
+	
+	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
 		
-		// Both t and s are functional interface types ... 
-		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
-		if (tSam == null || !tSam.isValidBinding())
+		if (TypeBinding.equalsEquals(s, t))
+			return true;
+		
+		if (this.exactMethodBinding == null)
 			return false;
+		
+		s = s.capture(this.enclosingScope, this.sourceEnd);
 		MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
 		if (sSam == null || !sSam.isValidBinding())
 			return false;
+		TypeBinding r1 = sSam.returnType;
 		
-		// t should neither be a subinterface nor a superinterface of s
-		if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		if (tSam == null || !tSam.isValidBinding())
 			return false;
-
-		// The descriptor parameter types of t are the same as the descriptor parameter types of s.
-		if (tSam.parameters.length != sSam.parameters.length)
-			return false;
-		for (int i = 0, length = tSam.parameters.length; i < length; i++) {
-			if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
-				return false;
-		}
+		TypeBinding r2 = tSam.returnType;
 		
-		// Either the descriptor return type of s is void or ...
-		if (sSam.returnType.id == TypeIds.T_void)
+		if (r2.id == TypeIds.T_void)
 			return true;
 		
-		/* ... or the descriptor return type of the capture of T is more specific than the descriptor return type of S for 
-		   an invocation expression of the same form as the method reference..
-		*/
-		Expression resultExpression = (Expression) this.resultExpressions.get(t); // should be same as for s
+		if (r1.id == TypeIds.T_void)
+			return false;
 		
-		t = t.capture(this.enclosingScope, this.sourceEnd);
-		tSam = t.getSingleAbstractMethod(this.enclosingScope);
-		return resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType);
+		// r1 <: r2
+		if (r1.isCompatibleWith(r2))
+			return true;
+		
+		return r1.isBaseType() != r2.isBaseType() && r1.isBaseType() == this.exactMethodBinding.returnType.isBaseType();
 	}
 
 	public org.eclipse.jdt.internal.compiler.lookup.MethodBinding getMethodBinding() {
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 3e8132d..36788ea 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
@@ -317,7 +317,7 @@
 			return;
 		}
 		expressionType = this.expression.resolveType(scope);
-		if (lambda != null && !this.implicitReturn)
+		if (lambda != null)
 			lambda.returnsExpression(this.expression, expressionType);
 		if (this.implicitReturn && (expressionType == TypeBinding.VOID || this.expression.statementExpression()))
 			return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index 307b49f..775dd3e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -27,7 +27,6 @@
 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
@@ -83,11 +82,6 @@
 
 public void resolve(BlockScope scope) {
 	this.exceptionType = this.exception.resolveType(scope);
-	MethodScope methodScope = scope.methodScope();
-	LambdaExpression lambda = methodScope.referenceContext instanceof LambdaExpression ? (LambdaExpression) methodScope.referenceContext : null;
-	if (lambda != null) {
-		lambda.throwsException(this.exceptionType);
-	}
 	if (this.exceptionType != null && this.exceptionType.isValidBinding()) {
 //{ObjectTeams: lowering roles of exceptions:
 		if (this.exceptionType.isRole()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 472bfe8..08e624b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -2081,10 +2081,6 @@
 	this.ignoreFurtherInvestigation = true;
 }
 
-public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
-	// Nothing to do for this context;
-}
-
 //{ObjectTeams: untag class and interface part:
 public void resetErrorFlag() {
 	if (isRole() && this.roleModel != null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index 9393a34..06144ad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -762,7 +762,7 @@
 	public int literalIndexForMethodHandle(MethodBinding binding) {
 		boolean isInterface = binding.declaringClass.isInterface();
 		int referenceKind =
-			isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : MethodHandleRefKindInvokeInterface
+			isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial : MethodHandleRefKindInvokeInterface
 			: binding.isConstructor() ? MethodHandleRefKindNewInvokeSpecial
 			: binding.isStatic() ? MethodHandleRefKindInvokeStatic
 			: MethodHandleRefKindInvokeVirtual;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
index 34f2e86..b2130e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
@@ -38,8 +38,6 @@
 	boolean hasErrors();
 
 	void tagAsHavingErrors();
-	
-	void tagAsHavingIgnoredMandatoryErrors(int problemId);
 
 //{ObjectTeams: some errors will have to be removed
 	void resetErrorFlag();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 9785fa9..f4eae16 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -406,7 +406,7 @@
 public TypeBinding maybeWrapRoleType(ASTNode typedNode, TypeArgumentUpdater updater) {
 	if (!this.leafComponentType.isBaseType()) {
 		TypeBinding updated = this.leafComponentType.maybeWrapRoleType(typedNode, updater);
-		if (updated != this.leafComponentType)
+		if (updated != this.leafComponentType) //$IDENTITY-COMPARISON$
 			return this.environment.createArrayType(updated, this.dimensions);
 	}
 	return this;
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 43df563..0423f35 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
@@ -77,7 +77,7 @@
 	public static final CallinCalloutBinding[] NO_CALLIN_CALLOUT_BINDINGS = new CallinCalloutBinding[0];
 	public static final SyntheticArgumentBinding[] NO_SYNTH_ARGUMENTS = new SyntheticArgumentBinding[0];
 //Markus Witte}
-
+	
 	public static final FieldBinding[] UNINITIALIZED_FIELDS = new FieldBinding[0];
 	public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
 	public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index f3ca840..c089af7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -29,6 +29,7 @@
  *								bug 409473 - [compiler] JDT cannot compile against JRE 1.8
  *								Bug 420080 - [1.8] Overridden Default method is reported as duplicated
  *								Bug 418235 - [compiler][null] Unreported nullness error when using generic
+ *								Bug 404690 - [1.8][compiler] revisit bridge generation after VM bug is fixed
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
@@ -529,7 +530,7 @@
 			int length = inherited.length;
 			for (int i = 0; i < length; i++) {
 				MethodBinding inheritedMethod = inherited[i];
-				if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic())
+				if (inheritedMethod.isPublic() && (!inheritedMethod.declaringClass.isInterface() && !inheritedMethod.declaringClass.isPublic()))
 					this.type.addSyntheticBridgeMethod(inheritedMethod.original());
 			}
 		}
@@ -623,7 +624,7 @@
 			
 			if (matchMethod == null && current != null && this.type.isPublic()) { // current == null case handled already.
 				MethodBinding inheritedMethod = inherited[i];
-				if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic()) {
+				if (inheritedMethod.isPublic() && (!inheritedMethod.declaringClass.isInterface() && !inheritedMethod.declaringClass.isPublic())) {
 					this.type.addSyntheticBridgeMethod(inheritedMethod.original());
 				}
 			}
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 c8cb7f4..cee3903 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
@@ -91,9 +91,7 @@
 	 * May return an UnresolvedReferenceBinding.
 	 * @see ParameterizedTypeBinding#genericType()
 	 */
-//{ObjectTeams: made public (was protected):
 	public ReferenceBinding actualType() {
-// SH}
 		return this.type;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
index f48bb45..5b81510 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
@@ -49,6 +49,10 @@
 		return this.expression.printExpression(0,  new StringBuffer()).toString().toCharArray();
 	}
 	
+	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+		return this.expression.sIsMoreSpecific(s, t);
+	}
+	
 	public String toString() {
 		StringBuffer buffer = new StringBuffer("PolyTypeBinding for: "); //$NON-NLS-1$
 		return this.expression.printExpression(0,  buffer).toString();
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 32dfc41..a051f07 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
@@ -1105,7 +1105,11 @@
 		return ((CompilationUnitScope) unitScope).environment;
 	}
 
-	// abstract method lookup lookup (since maybe missing default abstract methods)
+	/* Abstract method lookup (since maybe missing default abstract methods). "Default abstract methods" are methods that used to be emitted into 
+	   abstract classes for unimplemented interface methods at JDK 1.1 time frame. See SourceTypeBinding.addDefaultAbstractMethods()
+	   See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=174588 for details of problem addressed here. Problem was in the method call in the 
+	   *abstract* class. Unless the interface methods are looked up, we will emit code that results in infinite recursion.
+	*/
 	protected MethodBinding findDefaultAbstractMethod(
 		ReferenceBinding receiverType,
 		char[] selector,
@@ -1543,11 +1547,6 @@
 	}
 
 	// Internal use only - use findMethod()
-	public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
-		return findMethod(receiverType, selector, argumentTypes, invocationSite, false);
-	}
-
-	// Internal use only - use findMethod()
 	public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) {
 //{ObjectTeams: access to private method from "within" (need class part)?
 		if (   RoleTypeBinding.isRoleWithoutExplicitAnchor(receiverType)
@@ -1875,7 +1874,7 @@
 			if (methodBinding.canBeSeenBy(receiverType, invocationSite, this))
 				return methodBinding;
 		}
-		methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+		methodBinding = findMethod(object, selector, argumentTypes, invocationSite, false);
 		if (methodBinding == null)
 			return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
 		return methodBinding;
@@ -2248,6 +2247,41 @@
 	}
 // SH}
 
+	// For exact constructor references. 15.28.1
+	public MethodBinding getExactConstructor(TypeBinding receiverType, InvocationSite invocationSite) {
+		if (receiverType == null || !receiverType.canBeInstantiated())
+			return null;
+		if (receiverType.isArrayType()) {
+			if (!receiverType.leafComponentType().isReifiable())
+				return null;
+			return new MethodBinding(ClassFileConstants.AccPublic, TypeConstants.INIT,
+								receiverType,
+								new TypeBinding[] { TypeBinding.INT },
+								Binding.NO_EXCEPTIONS,
+								getJavaLangObject()); // just lie.
+		}
+
+		CompilationUnitScope unitScope = compilationUnitScope();
+		MethodBinding exactConstructor = null;
+		unitScope.recordTypeReference(receiverType);
+		MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT);
+		for (int i = 0, length = methods.length; i < length; i++) {
+			MethodBinding constructor = methods[i];
+			if (!constructor.canBeSeenBy(invocationSite, this))
+				continue;
+			if (constructor.isVarargs())
+				return null;
+			if (constructor.typeVariables() != Binding.NO_TYPE_VARIABLES && invocationSite.genericTypeArguments() == null)
+				return null;
+			if (exactConstructor == null) {
+				exactConstructor = constructor;
+			} else {
+				return null;
+			}
+		}
+		return exactConstructor;
+	}
+	
 	public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
 		CompilationUnitScope unitScope = compilationUnitScope();
 		LookupEnvironment env = unitScope.environment;
@@ -2457,7 +2491,7 @@
 						classScope.origImplicitScope = null;
 // SH}
 						if (methodBinding == null)
-							methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite);
+							methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite, false);
 						if (methodBinding != null) { // skip it if we did not find anything
 							if (foundMethod == null) {
 								if (methodBinding.isValidBinding()) {
@@ -2797,7 +2831,7 @@
 			MethodBinding methodBinding = findExactMethod(currentType, selector, argumentTypes, invocationSite);
 			if (methodBinding != null) return methodBinding;
 
-			methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+			methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite, false);
 //{ObjectTeams: callout to private role method goes through the role class-part:
 			// (will later be replaced by synthetic accessor)
 			if (   methodBinding == null
@@ -2806,7 +2840,7 @@
 				&& currentType.isRole())
 			{
 				currentType = currentType.getRealClass();
-				methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+				methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite, false);
 			}
 // SH}
 			if (methodBinding == null)
@@ -4334,6 +4368,43 @@
 
 	// caveat: this is not a direct implementation of JLS
 	protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, int visibleSize, TypeBinding[] argumentTypes, final InvocationSite invocationSite, ReferenceBinding receiverType) {
+		// Apply one level of filtering per poly expression more specific rules.
+		if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
+			MethodBinding[] moreSpecific = new MethodBinding[visibleSize];
+			int count = 0;
+			for (int i = 0, length = argumentTypes.length; i < length; i++) {
+				TypeBinding argumentType = argumentTypes[i];
+				if (argumentType.kind() != Binding.POLY_TYPE)
+					continue;
+				next:
+					for (int j = 0; j < visibleSize; j++) {
+						final TypeBinding[] mbjParameters = visible[j].parameters;
+						final int mbjParametersLength = mbjParameters.length;
+						TypeBinding t = i < mbjParametersLength ? mbjParameters[i] : mbjParameters[mbjParametersLength - 1];
+						boolean tIsMoreSpecific = false;
+						for (int k = 0; k < visibleSize; k++) {
+							if (j == k) continue;
+							final TypeBinding[] mbkParameters = visible[k].parameters;
+							final int mbkParametersLength = mbkParameters.length;
+							TypeBinding s = i < mbkParametersLength ? mbkParameters[i] : mbkParameters[mbkParametersLength - 1];
+							if (TypeBinding.equalsEquals(t, s))
+								continue;
+							if (!argumentType.sIsMoreSpecific(t,s)) 
+								continue next;
+							tIsMoreSpecific = true;
+						}
+						if (tIsMoreSpecific)
+							moreSpecific[count++] = visible[j];
+					}
+			}
+			if (count != 0) {
+				visible = moreSpecific;
+				visibleSize = count;
+			}
+		}
+	
+		// JLS7 implementation  
+		
 		int[] compatibilityLevels = new int[visibleSize];
 //{ObjectTeams: also record whether translation is required:
 		boolean[] useTranslation = new boolean[visibleSize];
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 5d0ea39..3cde2bc 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
@@ -1021,6 +1021,7 @@
 /*
  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658. Generate a bridge method if a public method is inherited
  * from a non-public class into a public class (only in 1.6 or greater)
+ * https://bugs.eclipse.org/404690 : this doesn't apply to inherited interface methods (i.e., default methods)
  */
 public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
 	if (!isPrototype()) throw new IllegalStateException();
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 029d5b6..b94ae5f 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
@@ -570,7 +570,10 @@
 	public void initializeMethodAccessor(MethodBinding accessedMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
 
 		this.targetMethod = accessedMethod;
-		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
+		if (isSuperAccess && receiverType.isInterface() && !accessedMethod.isStatic())
+			this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccSynthetic;
+		else
+			this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
 //{ObjectTeams: different visibility for team accessors:
 		if (receiverType.isTeam())
 			this.modifiers |= ClassFileConstants.AccPublic;
@@ -593,7 +596,7 @@
 			System.arraycopy(accessedMethod.parameters, 0, this.parameters, 2, accessedMethod.parameters.length);
 		} else 
 // SH}
-		if (accessedMethod.isStatic()) {
+		if (accessedMethod.isStatic() || (isSuperAccess && receiverType.isInterface())) {
 			this.parameters = accessedMethod.parameters;
 		} else {
 			this.parameters = new TypeBinding[accessedMethod.parameters.length + 1];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 3ac2ab4..603744f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -136,7 +136,7 @@
 	}
 }
 
-protected ReferenceBinding actualType() {
+public ReferenceBinding actualType() {
 	return null; // overridden in ParameterizedTypeBinding & WildcardBinding
 }
 
@@ -617,7 +617,7 @@
 	return false;
 }
 
-public boolean isFunctionalInterface() {
+public boolean isFunctionalInterface(Scope scope) {
 	return false;
 }
 
@@ -1530,4 +1530,12 @@
 public boolean hasTypeBit(int bit) {
 	return false;
 }
+
+public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t) {
+	throw new UnsupportedOperationException("abstract virtual method called"); //$NON-NLS-1$
+}
+
+public MethodBinding[] getMethods(char[] selector) {
+	return Binding.NO_METHODS;
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index a83009f..48db7d5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -109,7 +109,7 @@
 		return this.boundKind;
 	}
 	
-	protected ReferenceBinding actualType() {
+	public ReferenceBinding actualType() {
 		return this.genericType;
 	}
 	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
index 7ab9175..3fe6499 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
@@ -147,16 +147,9 @@
 		CompilationResult unitResult)
 {
 // SH}
-	if (severity == ProblemSeverities.Ignore)
-		return;
 
-	 boolean mandatory = (severity & (ProblemSeverities.Error | ProblemSeverities.Optional)) == ProblemSeverities.Error;
-	 if (this.policy.ignoreAllErrors()) { 
-		 // Error is not to be exposed, but clients may need still notification as to whether there are silently-ignored-errors.
-		 if (mandatory)
-			 referenceContext.tagAsHavingIgnoredMandatoryErrors(problemId);
-		 return;
-	 }
+	if (severity == ProblemSeverities.Ignore || this.policy.ignoreAllErrors())
+		return;
 
 	if ((severity & ProblemSeverities.Optional) != 0 && problemId != IProblem.Task  && !this.options.ignoreSourceFolderWarningOption) {
 //{ObjectTeams: NPE prevention:
@@ -300,6 +293,7 @@
 
 	switch (severity & ProblemSeverities.Error) {
 		case ProblemSeverities.Error :
+			boolean mandatory = ((severity & ProblemSeverities.Optional) == 0);
 			record(problem, unitResult, referenceContext, mandatory);
 			if ((severity & ProblemSeverities.Fatal) != 0) {
 				// don't abort or tag as error if the error is suppressed
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index 8437289..d2362c5 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -247,7 +247,7 @@
 		if (argHasError) {
 			if(this.actualReceiverType instanceof ReferenceBinding) {
 				// record any selector match, for clients who may still need hint about possible method match
-				this.binding = scope.findMethod((ReferenceBinding)this.actualReceiverType, this.selector, new TypeBinding[]{}, this);
+				this.binding = scope.findMethod((ReferenceBinding)this.actualReceiverType, this.selector, new TypeBinding[]{}, this, false);
 			}
 			return null;
 		}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
index b07ddf3..16a7723 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -4,6 +4,10 @@
  * 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
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -369,8 +373,8 @@
 	return null;
 }
 // Internal use only
-public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
-	MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite);
+public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) {
+	MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite, inStaticContext);
 	if (methodBinding != null && methodBinding.isValidBinding())
 		if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
 			return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible);
@@ -390,7 +394,7 @@
 	}
 
 	// answers closest approximation, may not check argumentTypes or visibility
-	methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+	methodBinding = findMethod(object, selector, argumentTypes, invocationSite, false);
 	if (methodBinding == null)
 		return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
 	if (methodBinding.isValidBinding()) {
@@ -600,7 +604,7 @@
 	// retrieve an exact visible match (if possible)
 	MethodBinding methodBinding = findExactMethod(receiverType, selector, argumentTypes, invocationSite);
 	if (methodBinding == null)
-		methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
+		methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite, false);
 	if (methodBinding != null) { // skip it if we did not find anything
 		if (methodBinding.isValidBinding())
 		    if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))