Bug 502350 - Eclipse compiler gets stuck in infinite loop

Change-Id: I21da1e95475e3050da9c95ec6371d73df704928b
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index be3330b..f632841 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -7031,4 +7031,45 @@
 			"}\n"
 		});
 }
+public void testBug502350() {
+	runNegativeTest(
+		new String[] {
+			"makeCompilerFreeze/EclipseJava8Bug.java",
+			"package makeCompilerFreeze;\n" +
+			"\n" +
+			"interface Comparable<E> {} \n" +
+			"\n" +
+			"interface Comparator<A> {\n" +
+			"  public static <B extends Comparable<B>> Comparator<B> naturalOrder() {\n" +
+			"    return null;\n" +
+			"  }\n" +
+			"}\n" +
+			"\n" +
+			"\n" +
+			"class Stuff {\n" +
+			"  public static <T, S extends T> Object func(Comparator<T> comparator) {\n" +
+			"    return null;\n" +
+			"  }\n" +
+			"}\n" +
+			"\n" +
+			"public class EclipseJava8Bug {\n" +
+			"  static final Object BORKED =\n" +
+			"      Stuff.func(Comparator.naturalOrder());\n" +
+			"}\n" +
+			"\n" +
+			"",
+		},
+		"----------\n" + 
+		"1. ERROR in makeCompilerFreeze\\EclipseJava8Bug.java (at line 20)\n" + 
+		"	Stuff.func(Comparator.naturalOrder());\n" + 
+		"	      ^^^^\n" + 
+		"The method func(Comparator<T>) in the type Stuff is not applicable for the arguments (Comparator<Comparable<Comparable<B>>>)\n" + 
+		"----------\n" + 
+		"2. ERROR in makeCompilerFreeze\\EclipseJava8Bug.java (at line 20)\n" + 
+		"	Stuff.func(Comparator.naturalOrder());\n" + 
+		"	           ^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Type mismatch: cannot convert from Comparator<Comparable<Comparable<B>>> to Comparator<T>\n" + 
+		"----------\n"
+	);
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
index a004158..b8ebe83 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
@@ -849,19 +849,27 @@
 		//  α = S and T <: α imply ⟨T <: S⟩
 		InferenceVariable alpha = boundS.left;
 		TypeBinding s = boundS.right;
-		if (TypeBinding.equalsEquals(alpha,boundT.left))
-			return ConstraintTypeFormula.create(s, boundT.right, boundT.relation, boundT.isSoft||boundS.isSoft);
-		if (TypeBinding.equalsEquals(alpha, boundT.right))
-			return ConstraintTypeFormula.create(boundT.right, s, boundT.relation, boundT.isSoft||boundS.isSoft);
+		if (TypeBinding.equalsEquals(alpha, boundT.left)) {
+			TypeBinding t = boundT.right;
+			return ConstraintTypeFormula.create(s, t, boundT.relation, boundT.isSoft||boundS.isSoft);
+		}
+		if (TypeBinding.equalsEquals(alpha, boundT.right)) {
+			TypeBinding t = boundT.left;
+			return ConstraintTypeFormula.create(t, s, boundT.relation, boundT.isSoft||boundS.isSoft);
+		}
 
 		if (boundS.right instanceof InferenceVariable) {
 			// reverse:
 			alpha = (InferenceVariable) boundS.right;
 			s = boundS.left;
-			if (TypeBinding.equalsEquals(alpha, boundT.left))
-				return ConstraintTypeFormula.create(s, boundT.right, boundT.relation, boundT.isSoft||boundS.isSoft);
-			if (TypeBinding.equalsEquals(alpha, boundT.right))
-				return ConstraintTypeFormula.create(boundT.right, s, boundT.relation, boundT.isSoft||boundS.isSoft);			
+			if (TypeBinding.equalsEquals(alpha, boundT.left)) {
+				TypeBinding t = boundT.right;
+				return ConstraintTypeFormula.create(s, t, boundT.relation, boundT.isSoft||boundS.isSoft);
+			}
+			if (TypeBinding.equalsEquals(alpha, boundT.right)) {
+				TypeBinding t = boundT.left;
+				return ConstraintTypeFormula.create(t, s, boundT.relation, boundT.isSoft||boundS.isSoft);
+			}			
 		}
 		
 		//  α = U and S <: T imply ⟨S[α:=U] <: T[α:=U]⟩