Update jdt.core from origin BETA_JAVA8 with
72578ba43287462a0c91a7de026e07610ac80a95
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index de96949..ba6ca11 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -1488,7 +1488,7 @@
 
 		// do not add twice the same type
 		for (int i = 0; i <= this.expectedTypesPtr; i++) {
-			if (this.expectedTypes[i] == type) return;
+			if (TypeBinding.equalsEquals(this.expectedTypes[i], type)) return;
 		}
 
 		int length = this.expectedTypes.length;
@@ -1496,7 +1496,7 @@
 			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
 		this.expectedTypes[this.expectedTypesPtr] = type;
 
-		if(type == scope.getJavaLangObject()) {
+		if(TypeBinding.equalsEquals(type, scope.getJavaLangObject())) {
 			this.hasJavaLangObjectAsExpectedType = true;
 		}
 	}
@@ -1546,12 +1546,12 @@
 			if (paramLength == argLength) { // accept X[] but not X or X[][]
 				TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition
 				TypeBinding lastArgument = arguments[lastIndex];
-				if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
+				if (TypeBinding.notEquals(varArgType, lastArgument) && !lastArgument.isCompatibleWith(varArgType))
 					return false;
 			} else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
 				TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType();
 				for (int i = lastIndex; i < argLength; i++)
-					if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
+					if (TypeBinding.notEquals(varArgType, arguments[i]) && !arguments[i].isCompatibleWith(varArgType))
 						return false;
 			} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
 				return false;
@@ -1562,7 +1562,7 @@
 				return false;
 		}
 		for (int i = 0; i < lastIndex; i++)
-			if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i]))
+			if (TypeBinding.notEquals(parameters[i], arguments[i]) && !arguments[i].isCompatibleWith(parameters[i]))
 				return false;
 		return true;
 	}
@@ -3531,7 +3531,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -3572,7 +3572,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -4040,7 +4040,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -4126,7 +4126,7 @@
 		if (isStatic) {
 			completion.append(declarationType.sourceName());
 
-		} else if (declarationType == invocationType) {
+		} else if (TypeBinding.equalsEquals(declarationType, invocationType)) {
 			completion.append(THIS);
 
 		} else {
@@ -4216,7 +4216,7 @@
 				this.expectedTypes != null) {
 			for (int i = 0; i <= this.expectedTypesPtr; i++) {
 				if (proposalType.isEnum() &&
-						proposalType == this.expectedTypes[i]) {
+						TypeBinding.equalsEquals(proposalType, this.expectedTypes[i])) {
 					return R_ENUM + R_ENUM_CONSTANT;
 				}
 
@@ -4298,7 +4298,7 @@
 	}
 
 	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
-		if (receiverType == declaringClass) return R_NON_INHERITED;
+		if (TypeBinding.equalsEquals(receiverType, declaringClass)) return R_NON_INHERITED;
 		return 0;
 	}
 
@@ -4929,27 +4929,27 @@
 		completion.append(typeVariable.sourceName);
 
 //{ObjectTeams:
-		if (typeVariable.roletype != null && typeVariable.firstBound == typeVariable.roletype) {
+		if (typeVariable.roletype != null && TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.roletype)) {
 		    completion.append(' ');
 		    completion.append(BASE);
 		    completion.append(' ');
 		    createType(typeVariable.roletype, scope, completion);
 		}
 // SH}
-		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
+		if (typeVariable.superclass != null && TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) {
 		    completion.append(' ');
 		    completion.append(EXTENDS);
 		    completion.append(' ');
 		    createType(typeVariable.superclass, scope, completion);
 		}
 		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
-		   if (typeVariable.firstBound != typeVariable.superclass) {
+		   if (TypeBinding.notEquals(typeVariable.firstBound, typeVariable.superclass)) {
 			   completion.append(' ');
 			   completion.append(EXTENDS);
 			   completion.append(' ');
 		   }
 		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
-			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
+			   if (i > 0 || TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) {
 				   completion.append(' ');
 				   completion.append(EXTENDS);
 				   completion.append(' ');
@@ -6085,9 +6085,9 @@
 
 		if (searchSuperClasses) {
 			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
-			if (exceptionType != javaLangThrowable) {
+			if (TypeBinding.notEquals(exceptionType, javaLangThrowable)) {
 				ReferenceBinding superClass = exceptionType.superclass();
-				while(superClass != null && superClass != javaLangThrowable) {
+				while(superClass != null && TypeBinding.notEquals(superClass, javaLangThrowable)) {
 					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
 					superClass = superClass.superclass();
 				}
@@ -6123,7 +6123,7 @@
 		for (int j = typesFound.size; --j >= 0;) {
 			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
 
-			if (exceptionType == otherType)
+			if (TypeBinding.equalsEquals(exceptionType, otherType))
 				return;
 
 			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
@@ -6176,7 +6176,7 @@
 								SourceTypeBinding localType =
 									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
 
-								if (localType == exceptionType) {
+								if (TypeBinding.equalsEquals(localType, exceptionType)) {
 									isQualified = false;
 									break done;
 								}
@@ -6189,7 +6189,7 @@
 						ReferenceBinding[] memberTypes = type.memberTypes();
 						if (memberTypes != null) {
 							for (int j = 0; j < memberTypes.length; j++) {
-								if (memberTypes[j] == exceptionType) {
+								if (TypeBinding.equalsEquals(memberTypes[j], exceptionType)) {
 									isQualified = false;
 									break done;
 								}
@@ -6203,7 +6203,7 @@
 						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
 						if (types != null) {
 							for (int j = 0; j < types.length; j++) {
-								if (types[j] == exceptionType) {
+								if (TypeBinding.equalsEquals(types[j], exceptionType)) {
 									isQualified = false;
 									break done;
 								}
@@ -6487,13 +6487,13 @@
 				Object[] other = (Object[])fieldsFound.elementAt(i);
 				FieldBinding otherField = (FieldBinding) other[0];
 				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
-				if (field == otherField && receiverType == otherReceiverType)
+				if (field == otherField && TypeBinding.equalsEquals(receiverType, otherReceiverType))
 					continue next;
 				if (CharOperation.equals(field.name, otherField.name, true)) {
 					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
 						continue next;
 					if (otherField.declaringClass.isInterface()) {
-						if (field.declaringClass == scope.getJavaLangObject())
+						if (TypeBinding.equalsEquals(field.declaringClass, scope.getJavaLangObject()))
 							continue next;
 						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
 							continue next;
@@ -6514,7 +6514,7 @@
 
 				if (CharOperation.equals(field.name, local.name, true)) {
 					SourceTypeBinding declarationType = scope.enclosingSourceType();
-					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
+					if (declarationType.isAnonymousType() && TypeBinding.notEquals(declarationType, invocationScope.enclosingSourceType())) {
 						continue next;
 					}
 					if(canBePrefixed) {
@@ -6805,7 +6805,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -6918,7 +6918,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -8274,7 +8274,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -8352,7 +8352,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -8978,11 +8978,11 @@
 				Object[] other = (Object[]) methodsFound.elementAt(i);
 				MethodBinding otherMethod = (MethodBinding) other[0];
 				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
-				if (method == otherMethod && receiverType == otherReceiverType)
+				if (method == otherMethod && TypeBinding.equalsEquals(receiverType, otherReceiverType))
 					continue next;
 
 				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
-					if (receiverType == otherReceiverType) {
+					if (TypeBinding.equalsEquals(receiverType, otherReceiverType)) {
 						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
 							if (!superCall || !otherMethod.declaringClass.isInterface()) {
 								continue next;
@@ -9336,7 +9336,7 @@
 					if (method == otherMethod) continue next;
 
 					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
-						if (otherMethod.declaringClass == method.declaringClass &&
+						if (TypeBinding.equalsEquals(otherMethod.declaringClass, method.declaringClass) &&
 								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
 							continue next;
 						}
@@ -9379,7 +9379,7 @@
 				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
 
 				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
-				if (method.declaringClass != superTypeWithSameErasure) {
+				if (TypeBinding.notEquals(method.declaringClass, superTypeWithSameErasure)) {
 					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
 					for (int i = 0; i < otherMethods.length; i++) {
 						if(otherMethods[i].original() == method.original()) {
@@ -9608,7 +9608,7 @@
 				Object[] other = (Object[]) methodsFound.elementAt(i);
 				MethodBinding otherMethod = (MethodBinding) other[0];
 				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
-				if (method == otherMethod && receiverType == otherReceiverType)
+				if (method == otherMethod && TypeBinding.equalsEquals(receiverType, otherReceiverType))
 					continue next;
 
 				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
@@ -9920,7 +9920,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -9948,7 +9948,7 @@
 		if(proposeAllMemberTypes) {
 			ReferenceBinding[] memberTypes = receiverType.memberTypes();
 			for (int i = 0; i < memberTypes.length; i++) {
-				if(memberTypes[i] != typeToIgnore) {
+				if(TypeBinding.notEquals(memberTypes[i], typeToIgnore)) {
 					findSubMemberTypes(
 						typeName,
 						memberTypes[i],
@@ -9989,7 +9989,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -10094,7 +10094,7 @@
 			for (int i = typesFound.size; --i >= 0;) {
 				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
 
-				if (memberType == otherType)
+				if (TypeBinding.equalsEquals(memberType, otherType))
 					continue next;
 
 				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
@@ -10717,7 +10717,7 @@
 								for (int j = typesFound.size; --j >= 0;) {
 									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
 
-									if (localType == otherType)
+									if (TypeBinding.equalsEquals(localType, otherType))
 										continue next;
 								}
 
@@ -11031,7 +11031,7 @@
 	private void findTrueOrFalseKeywords(char[][] choices) {
 		if(choices == null || choices.length == 0) return;
 
-		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
+		if(this.expectedTypesPtr != 0 || TypeBinding.notEquals(this.expectedTypes[0], TypeBinding.BOOLEAN)) return;
 
 		for (int i = 0; i < choices.length; i++) {
 			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
@@ -11188,7 +11188,7 @@
 				if(isForbidden(sourceType)) continue next;
 
 				if(proposeAllMemberTypes &&
-					sourceType != outerInvocationType) {
+					TypeBinding.notEquals(sourceType, outerInvocationType)) {
 					findSubMemberTypes(
 							token,
 							sourceType,
@@ -11215,7 +11215,7 @@
 				for (int j = typesFound.size; --j >= 0;) {
 					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
 
-					if (sourceType == otherType) continue next;
+					if (TypeBinding.equalsEquals(sourceType, otherType)) continue next;
 				}
 				
 				typesFound.add(sourceType);
@@ -11622,7 +11622,7 @@
 
 					for (int j = 0; j < typesFound.size(); j++) {
 						ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
-						if (typeFound == refBinding.erasure()) {
+						if (TypeBinding.equalsEquals(typeFound, refBinding.erasure())) {
 							continue next;
 						}
 					}
@@ -12315,7 +12315,7 @@
 			TypeBinding tb = type.resolvedType;
 
 			if (tb.problemId() == ProblemReasons.NoError &&
-					tb != Scope.getBaseType(VOID)) {
+					TypeBinding.notEquals(tb, Scope.getBaseType(VOID))) {
 				findVariableName(
 					name,
 					tb.leafComponentType().qualifiedPackageName(),
@@ -12934,7 +12934,7 @@
 					for (int i = 0; i < memberTypes.length; i++) {
 						if (CharOperation.equals(memberTypes[i].sourceName, type.sourceName()) &&
 								memberTypes[i].canBeSeenBy(scope)) {
-							return memberTypes[i] != type;
+							return TypeBinding.notEquals(memberTypes[i], type);
 						}
 					}
 				}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
index 0c1c62e..503d6c0 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
@@ -535,7 +535,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -581,7 +581,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -623,7 +623,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index f28d859..271b9a7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -1,10 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 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
- * $Id: SelectionEngine.java 23405 2010-02-03 17:02:18Z stephan $
+ *
+ * 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
@@ -1319,7 +1322,7 @@
 					typeParameterNames[i] = typeVariable.sourceName;
 					if (typeVariable.firstBound == null) {
 						typeParameterBoundNames[i] = new char[0][];
-					} else if (typeVariable.firstBound == typeVariable.superclass) {
+					} else if (TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) {
 						int boundCount = 1 + (typeVariable.superInterfaces == null ? 0 : typeVariable.superInterfaces.length);
 						typeParameterBoundNames[i] = new char[boundCount][];
 						typeParameterBoundNames[i][0] = typeVariable.superclass.sourceName;
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
index 3f4004e..aca7d4b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
@@ -211,7 +211,7 @@
 		for (int i = 0; i < exceptions.length; i++) {
 			ReferenceBinding exception = (ReferenceBinding)exceptions[i];
 			if (exception != null) {
-				if (exception == caughtException) {
+				if (TypeBinding.equalsEquals(exception, caughtException)) {
 					this.thrownExceptions.remove(exception);
 				} else if (caughtException.isSuperclassOf(exception)) {
 					// catching the sub-exception when super has been caught already will give an error
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java
index 86a957c..7ad1ad6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 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
  *     Technical University Berlin - extended API and implementation
@@ -283,7 +287,7 @@
 				boolean found = false;
 				int paramNameRefCount = 0;
 				for (int j = 0; j < paramTypeParamLength && !found; j++) {
-					if (parameter.binding == this.paramTypeParameters[j].resolvedType) {
+					if (TypeBinding.equalsEquals(parameter.binding, this.paramTypeParameters[j].resolvedType)) {
 						if (parameter.binding == paramNameRefBinding) { // do not count first occurence of param nmae reference
 							paramNameRefCount++;
 							found = paramNameRefCount > 1;
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
index fca2f0f..ead885d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
@@ -1,11 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 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
- * $Id: SelectionOnMessageSend.java 23404 2010-02-03 14:10:22Z stephan $
  *
+ * 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -71,7 +74,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 8e4da1b..b60d321 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -329,7 +329,7 @@
 			}
 		}
 		TypeBinding checkedParameterType = parameterType; // originalParameterType == null ? parameterType : originalParameterType;
-		if (argumentType != checkedParameterType && argumentType.needsUncheckedConversion(checkedParameterType)) {
+		if (TypeBinding.notEquals(argumentType, checkedParameterType) && argumentType.needsUncheckedConversion(checkedParameterType)) {
 			scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
 			return INVOCATION_ARGUMENT_UNCHECKED;
 		}
@@ -411,8 +411,8 @@
 						if (varargsType.dimensions < dimensions) {
 							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
 						} else if (varargsType.dimensions == dimensions
-										&& lastArgType != varargsType
-										&& lastArgType.leafComponentType().erasure() != varargsType.leafComponentType.erasure()
+										&& TypeBinding.notEquals(lastArgType, varargsType)
+										&& TypeBinding.notEquals(lastArgType.leafComponentType().erasure(), varargsType.leafComponentType.erasure())
 										&& lastArgType.isCompatibleWith(varargsType.elementsType())
 										&& lastArgType.isCompatibleWith(varargsType)) {
 							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
@@ -887,7 +887,7 @@
 				for (int j = i+1; j < length; j++) {
 					AnnotationBinding otherAnnotation = distinctAnnotations[j];
 					if (otherAnnotation == null) continue;
-					if (otherAnnotation.getAnnotationType() == annotationType) {
+					if (TypeBinding.equalsEquals(otherAnnotation.getAnnotationType(), annotationType)) {
 						if (distinctAnnotations == annotations) {
 							System.arraycopy(distinctAnnotations, 0, distinctAnnotations = new AnnotationBinding[length], 0, length);
 						}
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 19f0b60..6f07112 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
@@ -319,7 +319,7 @@
 // SH}
 
 	ReferenceBinding declaringClass;
-	if (codegenBinding.isPrivate() && currentScope.enclosingSourceType() != (declaringClass = codegenBinding.declaringClass)) {
+	if (codegenBinding.isPrivate() && TypeBinding.notEquals(currentScope.enclosingSourceType(), (declaringClass = codegenBinding.declaringClass))) {
 
 		// from 1.4 on, local type constructor can lose their private flag to ease emulation
 		if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
@@ -639,7 +639,7 @@
 			// eg. X<String> x = new X<String>()
 			int i;
 			for (i = 0; i < allocationType.arguments.length; i++) {
-				if (allocationType.arguments[i] != expected.arguments[i])
+				if (TypeBinding.notEquals(allocationType.arguments[i], expected.arguments[i]))
 					break;
 			}
 			if (i == allocationType.arguments.length) {
@@ -653,7 +653,7 @@
 		return;
 	}
 	for (int i = 0; i < inferredTypes.length; i++) {
-		if (inferredTypes[i] != allocationType.arguments[i])
+		if (TypeBinding.notEquals(inferredTypes[i], allocationType.arguments[i]))
 			return;
 	}
 	reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
index caa6e5b..0da505f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -190,7 +190,7 @@
 					continue;
 
 				// Compile-time conversion required?
-				if (elementType != expressionType) // must call before computeConversion() and typeMismatchError()
+				if (TypeBinding.notEquals(elementType, expressionType)) // must call before computeConversion() and typeMismatchError()
 					scope.compilationUnitScope().recordTypeConversion(elementType, expressionType);
 
 				if (expression.isConstantValueOfTypeAssignableToType(expressionType, elementType) 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index f06335b..7e884bb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -249,7 +249,7 @@
 
 	// Compile-time conversion of base-types : implicit narrowing integer into byte/short/character
 	// may require to widen the rhs expression at runtime
-	if (lhsType != rhsType) { // must call before computeConversion() and typeMismatchError()
+	if (TypeBinding.notEquals(lhsType, rhsType)) { // must call before computeConversion() and typeMismatchError()
 		scope.compilationUnitScope().recordTypeConversion(lhsType, rhsType);
 	}
 	if (this.expression.isConstantValueOfTypeAssignableToType(rhsType, lhsType)
@@ -304,8 +304,8 @@
 	TypeBinding lhsType = this.resolvedType;
 	TypeBinding rhsType = this.expression.resolvedType;
 	// signal possible accidental boolean assignment (instead of using '==' operator)
-	if (expectedType == TypeBinding.BOOLEAN
-			&& lhsType == TypeBinding.BOOLEAN
+	if (TypeBinding.equalsEquals(expectedType, TypeBinding.BOOLEAN)
+			&& TypeBinding.equalsEquals(lhsType, TypeBinding.BOOLEAN)
 			&& (this.lhs.bits & IsStrictlyAssigned) != 0) {
 		scope.problemReporter().possibleAccidentalBooleanAssignment(this);
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
index cf9cc9f..9404a33 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
@@ -1670,13 +1670,13 @@
 	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
 		if (leftTypeID == TypeIds.T_JavaLangString) {
 			this.left.computeConversion(scope, leftType, leftType);
-			if (rightType.isArrayType() && ((ArrayBinding) rightType).elementsType() == TypeBinding.CHAR) {
+			if (rightType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) rightType).elementsType(), TypeBinding.CHAR)) {
 				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
 			}
 		}
 		if (rightTypeID == TypeIds.T_JavaLangString) {
 			this.right.computeConversion(scope, rightType, rightType);
-			if (leftType.isArrayType() && ((ArrayBinding) leftType).elementsType() == TypeBinding.CHAR) {
+			if (leftType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) leftType).elementsType(), TypeBinding.CHAR)) {
 				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.left);
 			}
 		}
@@ -1849,13 +1849,13 @@
 	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
 		if (leftTypeID == TypeIds.T_JavaLangString) {
 			this.left.computeConversion(scope, leftType, leftType);
-			if (rightType.isArrayType() && ((ArrayBinding) rightType).elementsType() == TypeBinding.CHAR) {
+			if (rightType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) rightType).elementsType(), TypeBinding.CHAR)) {
 				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
 			}
 		}
 		if (rightTypeID == TypeIds.T_JavaLangString) {
 			this.right.computeConversion(scope, rightType, rightType);
-			if (leftType.isArrayType() && ((ArrayBinding) leftType).elementsType() == TypeBinding.CHAR) {
+			if (leftType.isArrayType() && TypeBinding.equalsEquals(((ArrayBinding) leftType).elementsType(), TypeBinding.CHAR)) {
 				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.left);
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index 62d413f..d1c6dd5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -214,7 +214,7 @@
 	TypeBinding castedExpressionType = ((CastExpression)enclosingInstance).expression.resolvedType;
 	if (castedExpressionType == null) return; // cannot do better
 	// obvious identity cast
-	if (castedExpressionType == enclosingInstanceType) {
+	if (TypeBinding.equalsEquals(castedExpressionType, enclosingInstanceType)) {
 		scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance);
 	} else if (castedExpressionType == TypeBinding.NULL){
 		return; // tolerate null enclosing instance cast
@@ -222,7 +222,7 @@
 		TypeBinding alternateEnclosingInstanceType = castedExpressionType;
 		if (castedExpressionType.isBaseType() || castedExpressionType.isArrayType()) return; // error case
 //{ObjectTeams: don't use beautified name.
-		if (memberType == scope.getMemberType(memberType.internalName(), (ReferenceBinding) alternateEnclosingInstanceType)) {
+		if (TypeBinding.equalsEquals(memberType, scope.getMemberType(memberType.internalName(), (ReferenceBinding) alternateEnclosingInstanceType))) {
 // SH}
 			scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance);
 		}
@@ -270,7 +270,7 @@
 			TypeBinding castedExpressionType = ((CastExpression)argument).expression.resolvedType;
 			if (castedExpressionType == null) return; // cannot do better
 			// obvious identity cast
-			if (castedExpressionType == argumentTypes[i]) {
+			if (TypeBinding.equalsEquals(castedExpressionType, argumentTypes[i])) {
 				scope.problemReporter().unnecessaryCast((CastExpression)argument);
 			} else if (castedExpressionType == TypeBinding.NULL){
 				continue; // tolerate null argument cast
@@ -401,7 +401,7 @@
 				}
 			}
 			for (int i = 0; i < argumentLength; i++) {
-				if (originalArgumentTypes[i] != alternateArgumentTypes[i]
+				if (TypeBinding.notEquals(originalArgumentTypes[i], alternateArgumentTypes[i])
                        /*&& !originalArgumentTypes[i].needsUncheckedConversion(alternateArgumentTypes[i])*/) {
 					scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
 				}
@@ -469,7 +469,7 @@
 									alternateArguments[i] = scope.getJavaLangObject();
 									LookupEnvironment environment = scope.environment();
 									ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)castType.erasure(), alternateArguments, castType.enclosingType());
-									if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
+									if (TypeBinding.equalsEquals(alternateCastType.findSuperTypeOriginatingFrom(expressionType), match)) {
 										this.bits |= ASTNode.UnsafeCast;
 										break;
 									}
@@ -515,7 +515,7 @@
 //			}
 //			break;
 	}
-	if (!isNarrowing && match == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
+	if (!isNarrowing && TypeBinding.equalsEquals(match, this.resolvedType.leafComponentType())) { // do not tag as unnecessary when recursing through upper bounds
 		tagAsUnnecessaryCast(scope, castType);
 	}
 	return true;
@@ -547,7 +547,7 @@
 		return;
 	}
 	this.expression.generateCode(currentScope, codeStream, valueRequired || needRuntimeCheckcast);
-	if (annotatedCast || (needRuntimeCheckcast && this.expression.postConversionType(currentScope) != this.resolvedType.erasure())) { // no need to issue a checkcast if already done as genericCast
+	if (annotatedCast || (needRuntimeCheckcast && TypeBinding.notEquals(this.expression.postConversionType(currentScope), this.resolvedType.erasure()))) { // no need to issue a checkcast if already done as genericCast
 		codeStream.checkcast(this.type, this.resolvedType);
 	}
 	if (valueRequired) {
@@ -666,7 +666,7 @@
 		MethodBinding methodBinding = messageSend.binding;
 		if (methodBinding != null && methodBinding.isPolymorphic()) {
 			messageSend.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) methodBinding, castType);
-			if (expressionType != castType) {
+			if (TypeBinding.notEquals(expressionType, castType)) {
 				expressionType = castType;
 				this.bits |= ASTNode.DisableUnnecessaryCastCheck;
 			}
@@ -761,7 +761,7 @@
 					&& ((ParameterizedGenericMethodBinding)method).inferredReturnType) {
 			if (this.expectedType == null)
 				return true;
-			if (this.resolvedType != this.expectedType)
+			if (TypeBinding.notEquals(this.resolvedType, this.expectedType))
 				return true;
 		}
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index 3b16167..bc287ea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -144,7 +144,7 @@
 		if (use15specifics) {
 			if (!lhsType.isBaseType() && expressionType.id != T_JavaLangString && expressionType.id != T_null) {
 				TypeBinding unboxedType = env.computeBoxingType(lhsType);
-				if (unboxedType != lhsType) {
+				if (TypeBinding.notEquals(unboxedType, lhsType)) {
 					lhsType = unboxedType;
 					unboxedLhs = true;
 				}
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 1d09d07..06f318c 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
@@ -520,7 +520,7 @@
 		if (TypeBinding.equalsEquals(valueIfTrueType, valueIfFalseType)) { // harmed the implicit conversion
 			this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
 			this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
-			if (valueIfTrueType == TypeBinding.BOOLEAN) {
+			if (TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.BOOLEAN)) {
 				this.optimizedIfTrueConstant = this.valueIfTrue.optimizedBooleanConstant();
 				this.optimizedIfFalseConstant = this.valueIfFalse.optimizedBooleanConstant();
 				if (this.optimizedIfTrueConstant != Constant.NotAConstant
@@ -540,24 +540,24 @@
 		// Numeric types
 		if (valueIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) {
 			// (Short x Byte) or (Byte x Short)"
-			if ((valueIfTrueType == TypeBinding.BYTE && valueIfFalseType == TypeBinding.SHORT)
-				|| (valueIfTrueType == TypeBinding.SHORT && valueIfFalseType == TypeBinding.BYTE)) {
+			if ((TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.BYTE) && TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.SHORT))
+				|| (TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.SHORT) && TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.BYTE))) {
 				this.valueIfTrue.computeConversion(scope, TypeBinding.SHORT, this.originalValueIfTrueType);
 				this.valueIfFalse.computeConversion(scope, TypeBinding.SHORT, this.originalValueIfFalseType);
 				return this.resolvedType = TypeBinding.SHORT;
 			}
 			// <Byte|Short|Char> x constant(Int)  ---> <Byte|Short|Char>   and reciprocally
-			if ((valueIfTrueType == TypeBinding.BYTE || valueIfTrueType == TypeBinding.SHORT || valueIfTrueType == TypeBinding.CHAR)
-					&& (valueIfFalseType == TypeBinding.INT
+			if ((TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.BYTE) || TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.SHORT) || TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.CHAR))
+					&& (TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.INT)
 						&& this.valueIfFalse.isConstantValueOfTypeAssignableToType(valueIfFalseType, valueIfTrueType))) {
 				this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
 				this.valueIfFalse.computeConversion(scope, valueIfTrueType, this.originalValueIfFalseType);
 				return this.resolvedType = valueIfTrueType;
 			}
-			if ((valueIfFalseType == TypeBinding.BYTE
-					|| valueIfFalseType == TypeBinding.SHORT
-					|| valueIfFalseType == TypeBinding.CHAR)
-					&& (valueIfTrueType == TypeBinding.INT
+			if ((TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.BYTE)
+					|| TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.SHORT)
+					|| TypeBinding.equalsEquals(valueIfFalseType, TypeBinding.CHAR))
+					&& (TypeBinding.equalsEquals(valueIfTrueType, TypeBinding.INT)
 						&& this.valueIfTrue.isConstantValueOfTypeAssignableToType(valueIfTrueType, valueIfFalseType))) {
 				this.valueIfTrue.computeConversion(scope, valueIfFalseType, this.originalValueIfTrueType);
 				this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
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 2227eac..0a79e7f 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
@@ -464,7 +464,7 @@
 					TypeBinding castElementType = ((ArrayBinding) castType).elementsType();
 					TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType();
 					if (exprElementType.isBaseType() || castElementType.isBaseType()) {
-						if (castElementType == exprElementType) {
+						if (TypeBinding.equalsEquals(castElementType, exprElementType)) {
 							tagAsNeedCheckCast();
 							return true;
 						}
@@ -579,7 +579,7 @@
 								int exprMethodsLength = expressionTypeMethods.length;
 								for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) {
 									for (int j = 0; j < exprMethodsLength; j++) {
-										if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
+										if ((TypeBinding.notEquals(castTypeMethods[i].returnType, expressionTypeMethods[j].returnType))
 												&& (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector))
 												&& castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
 											return false;
@@ -791,7 +791,7 @@
 }
 
 public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
-	if (match == castType) {
+	if (TypeBinding.equalsEquals(match, castType)) {
 		if (!isNarrowing) tagAsUnnecessaryCast(scope, castType);
 		return true;
 	}
@@ -827,7 +827,7 @@
 		}
 	} else if (compileTimeType != TypeBinding.NULL && compileTimeType.isBaseType()) {
 		TypeBinding boxedType = scope.environment().computeBoxingType(runtimeType);
-		if (boxedType == runtimeType) // Object o = 12;
+		if (TypeBinding.equalsEquals(boxedType, runtimeType)) // Object o = 12;
 			boxedType = compileTimeType;
 		this.implicitConversion = TypeIds.BOXING | (boxedType.id << 4) + compileTimeType.id;
 		scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType));
@@ -1077,7 +1077,7 @@
 
 	if (this.constant == Constant.NotAConstant)
 		return false;
-	if (constantType == targetType)
+	if (TypeBinding.equalsEquals(constantType, targetType))
 		return true;
 	//No free assignment conversion from anything but to integral ones.
 	if (BaseTypeBinding.isWidening(TypeIds.T_int, constantType.id)
@@ -1220,7 +1220,7 @@
 	setExpectedType(expectedType); // needed in case of generic method invocation
 	TypeBinding expressionType = this.resolveType(scope);
 	if (expressionType == null) return null;
-	if (expressionType == expectedType) return expressionType;
+	if (TypeBinding.equalsEquals(expressionType, expectedType)) return expressionType;
 
 	if (!expressionType.isCompatibleWith(expectedType)) {
 		if (scope.isBoxingCompatibleWith(expressionType, expectedType)) {
@@ -1247,12 +1247,12 @@
 			if (field.type.isRawType()) {
 				if (referenceContext instanceof AbstractMethodDeclaration) {
 					AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) referenceContext;
-					if (field.declaringClass != methodDecl.binding.declaringClass) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+					if (TypeBinding.notEquals(field.declaringClass, methodDecl.binding.declaringClass)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
 						return true;
 					}
 				} else if (referenceContext instanceof TypeDeclaration) {
 					TypeDeclaration type = (TypeDeclaration) referenceContext;
-					if (field.declaringClass != type.binding) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+					if (TypeBinding.notEquals(field.declaringClass, type.binding)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
 						return true;
 					}
 				}
@@ -1272,12 +1272,12 @@
 		if (field.type.isRawType()) {
 			if (referenceContext instanceof AbstractMethodDeclaration) {
 				AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) referenceContext;
-				if (field.declaringClass != methodDecl.binding.declaringClass) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+				if (TypeBinding.notEquals(field.declaringClass, methodDecl.binding.declaringClass)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
 					return true;
 				}
 			} else if (referenceContext instanceof TypeDeclaration) {
 				TypeDeclaration type = (TypeDeclaration) referenceContext;
-				if (field.declaringClass != type.binding) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+				if (TypeBinding.notEquals(field.declaringClass, type.binding)) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
 					return true;
 				}
 			}
@@ -1328,7 +1328,7 @@
 	if (expressionType == null || !expressionType.isValidBinding()) // Shouldn't get here, just to play it safe
 		return false; // trigger ambiguity.
 	
-	if (t.findSuperTypeOriginatingFrom(s) == s)
+	if (TypeBinding.equalsEquals(t.findSuperTypeOriginatingFrom(s), s))
 		return true;
 	
 	final boolean tIsBaseType = t.isBaseType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index 94c2f6b..7b049bd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -166,7 +166,7 @@
 		if (   !isCompound
 			&& this.receiver.isThis()
 			&& !(this.receiver instanceof QualifiedThisReference)
-			&& this.receiver.resolvedType == this.binding.declaringClass // inherited fields are not tracked here
+			&& TypeBinding.equalsEquals(this.receiver.resolvedType, this.binding.declaringClass) // inherited fields are not tracked here
 			&& ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0)) { // (this).x is forbidden
 			flowInfo.markAsDefinitelyAssigned(this.binding);
 		}		
@@ -334,7 +334,7 @@
 		if (isThisReceiver) {
 			if (isStatic){
 				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
-				if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) {
+				if (TypeBinding.notEquals(this.binding.original().declaringClass, this.actualReceiverType.erasure())) {
 					MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ];
 					if (accessor == null) {
 						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
@@ -561,7 +561,7 @@
 	// if field from parameterized type got found, use the original field at codegen time
 	FieldBinding codegenBinding = this.binding.original();
 	if (this.binding.isPrivate()) {
-		if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass)
+		if ((TypeBinding.notEquals(currentScope.enclosingSourceType(), codegenBinding.declaringClass))
 				&& this.binding.constant() == Constant.NotAConstant) {
 			if (this.syntheticAccessors == null)
 				this.syntheticAccessors = new MethodBinding[2];
@@ -714,7 +714,7 @@
 // SH}
 	if (receiverCast) {
 		 // due to change of declaring class with receiver type, only identity cast should be notified
-		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+		if (TypeBinding.equalsEquals(((CastExpression)this.receiver).expression.resolvedType, this.actualReceiverType)) {
 				scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
 		}
 	}
@@ -784,7 +784,7 @@
 	TypeBinding oldReceiverType = this.actualReceiverType;
 	this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(fieldBinding.declaringClass);
 	this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
-	if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+	if (TypeBinding.notEquals(this.actualReceiverType, oldReceiverType) && TypeBinding.notEquals(this.receiver.postConversionType(scope), this.actualReceiverType)) { // record need for explicit cast at codegen since receiver could not handle it
 		this.bits |= NeedReceiverGenericCast;
 	}
 	if (isFieldUseDeprecated(fieldBinding, scope, this.bits)) {
@@ -801,7 +801,7 @@
 		}
 		ReferenceBinding declaringClass = this.binding.declaringClass;
 		if (!isImplicitThisRcv
-				&& declaringClass != this.actualReceiverType
+				&& TypeBinding.notEquals(declaringClass, this.actualReceiverType)
 				&& declaringClass.canBeSeenBy(scope)) {
 			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
 		}
@@ -811,7 +811,7 @@
 			SourceTypeBinding sourceType = scope.enclosingSourceType();
 			if (this.constant == Constant.NotAConstant
 					&& !methodScope.isStatic
-					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+					&& (TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) // enum constant body
 					&& methodScope.isInsideInitializerOrConstructor()) {
 				scope.problemReporter().enumStaticFieldUsedDuringInitialization(this.binding, this);
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
index fc51a50..ad13cdf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
@@ -91,7 +91,7 @@
 				continue;
 			}
 			for (int j = 0; j < i; j++) {
-				if (intersectingTypes[j] == type) {
+				if (TypeBinding.equalsEquals(intersectingTypes[j], type)) {
 					scope.problemReporter().duplicateBoundInIntersectionCast(typeReference);
 					hasError = true;
 					continue;
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 96edbc1..7379f43 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
@@ -342,7 +342,7 @@
 						if (messageSend.binding != null && messageSend.binding.isValidBinding() && messageSend.actualReceiverType instanceof ReferenceBinding) {
 							ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
 							TypeBinding superType = methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(methodReceiverType);
-							if (superType != null && superType.original() != methDecl.binding.declaringClass && CharOperation.equals(messageSend.selector, methDecl.selector)) {
+							if (superType != null && TypeBinding.notEquals(superType.original(), methDecl.binding.declaringClass) && CharOperation.equals(messageSend.selector, methDecl.selector)) {
 								if (methScope.environment().methodVerifier().doesMethodOverride(methDecl.binding, messageSend.binding.original())) {
 									superRef = true;
 								}
@@ -355,7 +355,7 @@
 					if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) {
 						ReferenceBinding allocType = (ReferenceBinding) allocationExpr.resolvedType.original();
 						ReferenceBinding superType = (ReferenceBinding) methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(allocType);
-						if (superType != null && superType.original() != methDecl.binding.declaringClass) {
+						if (superType != null && TypeBinding.notEquals(superType.original(), methDecl.binding.declaringClass)) {
 							MethodBinding superConstructor = methScope.getConstructor(superType, methDecl.binding.parameters, allocationExpr);
 							if (superConstructor.isValidBinding() && superConstructor.original() == allocationExpr.binding.original()) {
 								if (superConstructor.areParametersEqual(methDecl.binding)) {
@@ -668,7 +668,7 @@
 							// Verify duplicated tags
 							boolean duplicate = false;
 							for (int j = 0; j < i && !duplicate; j++) {
-								if (bindings[j] == param.resolvedType) {
+								if (TypeBinding.equalsEquals(bindings[j], param.resolvedType)) {
 									scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers);
 									duplicate = true;
 								}
@@ -687,7 +687,7 @@
 					TypeParameter parameter = parameters[i];
 					boolean found = false;
 					for (int j = 0; j < paramTypeParamLength && !found; j++) {
-						if (parameter.binding == bindings[j]) {
+						if (TypeBinding.equalsEquals(parameter.binding, bindings[j])) {
 							found = true;
 							bindings[j] = null;
 						}
@@ -742,7 +742,7 @@
 					ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i];
 					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
 						int j=i;
-						while (j<thrownExceptionLength && exceptionBinding != md.thrownExceptions[j].resolvedType) j++;
+						while (j<thrownExceptionLength && TypeBinding.notEquals(exceptionBinding, md.thrownExceptions[j].resolvedType)) j++;
 						if (j<thrownExceptionLength) {
 							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[j], md.binding.modifiers);
 						}
@@ -773,7 +773,7 @@
 				for (int j = 0; j < maxRef && !found; j++) {
 					if (typeReferences[j] != null) {
 						TypeBinding typeBinding = typeReferences[j].resolvedType;
-						if (exceptionBinding == typeBinding) {
+						if (TypeBinding.equalsEquals(exceptionBinding, typeBinding)) {
 							found = true;
 							typeReferences[j] = null;
 						}
@@ -782,7 +782,7 @@
 				if (!found && reportMissing) {
 					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
 						int k=i;
-						while (k<thrownExceptionLength && exceptionBinding != md.thrownExceptions[k].resolvedType) k++;
+						while (k<thrownExceptionLength && TypeBinding.notEquals(exceptionBinding, md.thrownExceptions[k].resolvedType)) k++;
 						if (k<thrownExceptionLength) {
 							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[k], md.binding.modifiers);
 						}
@@ -856,7 +856,7 @@
 					topLevelScope = topLevelScope.outerMostClassScope();
 					if (typeReference instanceof JavadocSingleTypeReference) {
 						// inner class single reference can only be done in same unit
-						if ((!source15 && depth == 1) || topLevelType != topLevelScope.referenceContext.binding) {
+						if ((!source15 && depth == 1) || TypeBinding.notEquals(topLevelType, topLevelScope.referenceContext.binding)) {
 							// search for corresponding import
 							boolean hasValidImport = false;
 							if (source15) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
index a5022f4..005fcc8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
@@ -128,8 +128,8 @@
 			if (paramMethodBinding.hasSubstitutedParameters()) {
 				int length = argumentTypes.length;
 				for (int i=0; i<length; i++) {
-					if (paramMethodBinding.parameters[i] != argumentTypes[i] &&
-							paramMethodBinding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+					if (TypeBinding.notEquals(paramMethodBinding.parameters[i], argumentTypes[i]) &&
+							TypeBinding.notEquals(paramMethodBinding.parameters[i].erasure(), argumentTypes[i].erasure())) {
 						MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
 						scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
 						break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
index 65f5b3b..ef5ed42 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -187,7 +187,7 @@
 		} else {
 			int length = argumentTypes.length;
 			for (int i=0; i<length; i++) {
-				if (this.binding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+				if (TypeBinding.notEquals(this.binding.parameters[i].erasure(), argumentTypes[i].erasure())) {
 					MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
 					scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
 					break;
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 ea45475..e6ffe70 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
@@ -529,7 +529,7 @@
 			if (tSam.parameters.length != sSam.parameters.length)
 				return false;
 			for (int i = 0, length = tSam.parameters.length; i < length; i++) {
-				if (tSam.parameters[i] != sSam.parameters[i])
+				if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
 					return false;
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index b233bdb..4aa54cc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -323,7 +323,7 @@
 //{ObjectTeams: wrap rhs type:
 					initializationType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(initializationType, scope, this.initialization);
 // SH}
-					if (variableType != initializationType) // must call before computeConversion() and typeMismatchError()
+					if (TypeBinding.notEquals(variableType, initializationType)) // must call before computeConversion() and typeMismatchError()
 						scope.compilationUnitScope().recordTypeConversion(variableType, initializationType);
 					if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, variableType)
 						|| initializationType.isCompatibleWith(variableType, scope)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 693360a..82db3bd 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
@@ -648,7 +648,7 @@
 	{
 
 		// depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy)
-		if (currentScope.enclosingSourceType() != codegenBinding.declaringClass){
+		if (TypeBinding.notEquals(currentScope.enclosingSourceType(), codegenBinding.declaringClass)){
 			this.syntheticAccessor = ((SourceTypeBinding)codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, false /* not super access there */);
 			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
 			return;
@@ -797,7 +797,7 @@
 // MW,JH,SH}
 	if (receiverCast && this.actualReceiverType != null) {
 		 // due to change of declaring class with receiver type, only identity cast should be notified
-		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+		if (TypeBinding.equalsEquals(((CastExpression)this.receiver).expression.resolvedType, this.actualReceiverType)) {
 			scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
 		}
 	}
@@ -1145,7 +1145,7 @@
 			TypeBinding oldReceiverType = this.actualReceiverType;
 			this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(this.binding.declaringClass);
 			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
-			if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+			if (TypeBinding.notEquals(this.actualReceiverType, oldReceiverType) && TypeBinding.notEquals(this.receiver.postConversionType(scope), this.actualReceiverType)) { // record need for explicit cast at codegen since receiver could not handle it
 				this.bits |= NeedReceiverGenericCast;
 			}
 		}
@@ -1154,7 +1154,7 @@
 		if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || receiverIsType)) {
 			scope.problemReporter().nonStaticAccessToStaticMethod(this, this.binding);
 		}
-		if (!this.receiver.isImplicitThis() && this.binding.declaringClass != this.actualReceiverType) {
+		if (!this.receiver.isImplicitThis() && TypeBinding.notEquals(this.binding.declaringClass, this.actualReceiverType)) {
 			scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
 		}
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index d287ba5..e6a1533 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -288,7 +288,7 @@
 				TypeParameter typeParameter = this.typeParameters[i];
 				this.bits |= (typeParameter.bits & ASTNode.HasTypeAnnotations);
 				// typeParameter is already resolved from Scope#connectTypeVariables()
-				if (returnsUndeclTypeVar && this.typeParameters[i].binding == this.returnType.resolvedType) {
+				if (returnsUndeclTypeVar && TypeBinding.equalsEquals(this.typeParameters[i].binding, this.returnType.resolvedType)) {
 					returnsUndeclTypeVar = false;
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
index d280a36..b1dc981 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -264,7 +264,7 @@
 					typeIsConsistent = false;
 				}
 				ReferenceBinding enclosingType = currentType.enclosingType();
-				if (enclosingType != null && enclosingType.erasure() != qualifyingType.erasure()) { // qualifier != declaring/enclosing
+				if (enclosingType != null && TypeBinding.notEquals(enclosingType.erasure(), qualifyingType.erasure())) { // qualifier != declaring/enclosing
 					qualifyingType = enclosingType; // inherited member type, leave it associated with its enclosing rather than subtype
 				}
 			}
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 eff0e7c..7dbbe88 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
@@ -349,7 +349,7 @@
 			if (isTypeUseDeprecated(currentType, scope))
 				scope.problemReporter().deprecatedType(currentType, this);
 			ReferenceBinding currentEnclosing = currentType.enclosingType();
-			if (currentEnclosing != null && currentEnclosing.erasure() != enclosingType.erasure()) {
+			if (currentEnclosing != null && TypeBinding.notEquals(currentEnclosing.erasure(), enclosingType.erasure())) {
 				enclosingType = currentEnclosing; // inherited member type, leave it associated with its enclosing rather than subtype
 			}
 		}
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 819decd..fc4ac39 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
@@ -619,7 +619,7 @@
 		 	}
 			// The enclosing instance must be compatible with the innermost enclosing type
 			ReferenceBinding expectedType = this.binding.declaringClass.enclosingType();
-			if (expectedType != enclosingInstanceType) // must call before computeConversion() and typeMismatchError()
+			if (TypeBinding.notEquals(expectedType, enclosingInstanceType)) // must call before computeConversion() and typeMismatchError()
 				scope.compilationUnitScope().recordTypeConversion(expectedType, enclosingInstanceType);
 			if (enclosingInstanceType.isCompatibleWith(expectedType) || scope.isBoxingCompatibleWith(enclosingInstanceType, expectedType)) {
 				this.enclosingInstance.computeConversion(scope, expectedType, enclosingInstanceType);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index eebe55f..712384c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -397,7 +397,7 @@
 				}
 			} else {
 				boolean isFirst = lastFieldBinding == this.binding
-												&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+												&& (this.indexOfFirstFieldBinding == 1 || TypeBinding.equalsEquals(lastFieldBinding.declaringClass, currentScope.enclosingReceiverType()))
 												&& this.otherBindings == null; // could be dup: next.next.next
 				TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
 				if (valueRequired
@@ -463,7 +463,7 @@
 	// check if compound assignment is the only usage of a private field
 	reportOnlyUselesslyReadPrivateField(currentScope, lastFieldBinding, valueRequired);
 	boolean isFirst = lastFieldBinding == this.binding
-		&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+		&& (this.indexOfFirstFieldBinding == 1 || TypeBinding.equalsEquals(lastFieldBinding.declaringClass, currentScope.enclosingReceiverType()))
 		&& this.otherBindings == null; // could be dup: next.next.next
 	TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);			
 	SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
@@ -516,7 +516,7 @@
 	// check if this post increment is the only usage of a private field
 	reportOnlyUselesslyReadPrivateField(currentScope, lastFieldBinding, valueRequired);
 	boolean isFirst = lastFieldBinding == this.binding
-		&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+		&& (this.indexOfFirstFieldBinding == 1 || TypeBinding.equalsEquals(lastFieldBinding.declaringClass, currentScope.enclosingReceiverType()))
 		&& this.otherBindings == null; // could be dup: next.next.next
 	TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);			
 	SyntheticMethodBinding accessor = this.syntheticReadAccessors == null
@@ -683,7 +683,7 @@
 						if (lastFieldBinding == initialFieldBinding) {
 							if (lastFieldBinding.isStatic()){
 								// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
-								if (initialFieldBinding.declaringClass != this.actualReceiverType.erasure()) {
+								if (TypeBinding.notEquals(initialFieldBinding.declaringClass, this.actualReceiverType.erasure())) {
 									MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
 									if (accessor == null) {
 										TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
@@ -799,7 +799,7 @@
 				TypeBinding oldReceiverType = fieldReceiverType;
 				fieldReceiverType = fieldReceiverType.getErasureCompatibleType(field.declaringClass);// handle indirect inheritance thru variable secondary bound
 				FieldBinding originalBinding = previousField.original();
-				if (fieldReceiverType != oldReceiverType || originalBinding.type.leafComponentType().isTypeVariable()) { // record need for explicit cast at codegen
+				if (TypeBinding.notEquals(fieldReceiverType, oldReceiverType) || originalBinding.type.leafComponentType().isTypeVariable()) { // record need for explicit cast at codegen
 			    	setGenericCast(index-1,originalBinding.type.genericCast(fieldReceiverType)); // type cannot be base-type even in boxing case
 				}				
 		    }
@@ -818,14 +818,14 @@
 					MethodScope methodScope = scope.methodScope();
 					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
 					if ((this.bits & ASTNode.IsStrictlyAssigned) == 0
-							&& sourceType == declaringClass
+							&& TypeBinding.equalsEquals(sourceType, declaringClass)
 							&& methodScope.lastVisibleFieldID >= 0
 							&& field.id >= methodScope.lastVisibleFieldID
 							&& (!field.isStatic() || methodScope.isStatic)) {
 						scope.problemReporter().forwardReference(this, index, field);
 					}					
 					// check if accessing enum static field in initializer
-					if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+					if ((TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) // enum constant body
 							&& field.constant() == Constant.NotAConstant
 							&& !methodScope.isStatic
 							&& methodScope.isInsideInitializerOrConstructor()) {
@@ -835,7 +835,7 @@
 				// static field accessed through receiver? legal but unoptimal (optional warning)
 				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
 				// indirect static reference ?
-				if (field.declaringClass != type) {
+				if (TypeBinding.notEquals(field.declaringClass, type)) {
 					scope.problemReporter().indirectAccessToStaticField(this, field);
 				}
 			}
@@ -1058,7 +1058,7 @@
 	if (fieldBinding.isPrivate()) { // private access
 	    FieldBinding codegenField = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index);
 	    ReferenceBinding declaringClass = codegenField.declaringClass;
-		if (declaringClass != currentScope.enclosingSourceType()) {
+		if (TypeBinding.notEquals(declaringClass, currentScope.enclosingSourceType())) {
 		    setSyntheticAccessor(fieldBinding, index, ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenField, index >= 0 /*read-access?*/, false /*not super access*/,
 //{ObjectTeams: added 3. arg (externalizedReceiver):
 								true));
@@ -1219,7 +1219,7 @@
 					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
 					// check for forward references
 					if ((this.indexOfFirstFieldBinding == 1 || (fieldBinding.modifiers & ClassFileConstants.AccEnum) != 0 || (!fieldBinding.isFinal() && declaringClass.isEnum())) // enum constants are checked even when qualified
-							&& sourceType == declaringClass
+							&& TypeBinding.equalsEquals(sourceType, declaringClass)
 							&& methodScope.lastVisibleFieldID >= 0
 							&& fieldBinding.id >= methodScope.lastVisibleFieldID
 							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
@@ -1236,7 +1236,7 @@
 						// only last field is actually a write access if any
 						// check if accessing enum static field in initializer
 						if (declaringClass.isEnum()) {
-							if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+							if ((TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) // enum constant body
 									&& fieldBinding.constant() == Constant.NotAConstant
 									&& !methodScope.isStatic
 									&& methodScope.isInsideInitializerOrConstructor()) {
@@ -1244,7 +1244,7 @@
 							}
 						}
 						if (this.indexOfFirstFieldBinding > 1
-								&& fieldBinding.declaringClass != this.actualReceiverType
+								&& TypeBinding.notEquals(fieldBinding.declaringClass, this.actualReceiverType)
 								&& fieldBinding.declaringClass.canBeSeenBy(scope)) {
 							scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
 						}						
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
index 66f2e82..86101de 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
@@ -70,7 +70,7 @@
 		char[][] compoundName = null;
 		ReferenceBinding closestMatch = null;
 		for (int i = 0; i < length; i++) {
-			if (supers[i].erasure() == type) {
+			if (TypeBinding.equalsEquals(supers[i].erasure(), type)) {
 				this.currentCompatibleType = closestMatch = supers[i];
 			} else if (supers[i].erasure().isCompatibleWith(type)) {
 				isLegal = false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
index 07a6d45..2922b23 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
@@ -164,7 +164,7 @@
 	int findCompatibleEnclosing(ReferenceBinding enclosingType, TypeBinding type) {
 		int depth = 0;
 		this.currentCompatibleType = enclosingType;
-		while (this.currentCompatibleType != null && this.currentCompatibleType != type) {
+		while (this.currentCompatibleType != null && TypeBinding.notEquals(this.currentCompatibleType, type)) {
 			depth++;
 			this.currentCompatibleType = this.currentCompatibleType.isStatic() ? null : this.currentCompatibleType.enclosingType();
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index 3c896c5..0959314 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -225,7 +225,7 @@
 					rejectAnnotationsOnStaticMemberQualififer(scope, currentType, this.annotations[i-1]);
 				}
 				ReferenceBinding enclosingType = currentType.enclosingType();
-				if (enclosingType != null && enclosingType.erasure() != qualifiedType.erasure()) {
+				if (enclosingType != null && TypeBinding.notEquals(enclosingType.erasure(), qualifiedType.erasure())) {
 					qualifiedType = enclosingType; // inherited member type, leave it associated with its enclosing rather than subtype
 				}
 				boolean rawQualified;
@@ -233,7 +233,7 @@
 					qualifiedType = scope.environment().createRawType(currentType, qualifiedType);
 				} else if ((rawQualified = qualifiedType.isRawType()) && !currentType.isStatic()) {
 					qualifiedType = scope.environment().createRawType((ReferenceBinding)currentType.erasure(), qualifiedType);
-				} else if ((rawQualified || qualifiedType.isParameterizedType()) && qualifiedType.erasure() == currentType.enclosingType().erasure()) {
+				} else if ((rawQualified || qualifiedType.isParameterizedType()) && TypeBinding.equalsEquals(qualifiedType.erasure(), currentType.enclosingType().erasure())) {
 					qualifiedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType);
 				} else {
 					qualifiedType = currentType;
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 b80d1b8..c663416 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
@@ -170,7 +170,7 @@
 		
 		if (this.isConstructorReference()) {
 			ReferenceBinding allocatedType = codegenBinding.declaringClass;
-			if (codegenBinding.isPrivate() && enclosingSourceType != (allocatedType = codegenBinding.declaringClass)) {
+			if (codegenBinding.isPrivate() && TypeBinding.notEquals(enclosingSourceType, (allocatedType = codegenBinding.declaringClass))) {
 				if ((allocatedType.tagBits & TagBits.IsLocalType) != 0) {
 					codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
 				} else {
@@ -183,7 +183,7 @@
 	
 		// -----------------------------------   Only method references from now on -----------
 		if (this.binding.isPrivate()) {
-			if (enclosingSourceType != codegenBinding.declaringClass){
+			if (TypeBinding.notEquals(enclosingSourceType, codegenBinding.declaringClass)){
 				this.syntheticAccessor = ((SourceTypeBinding)codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, false /* not super access */);
 				currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
 			}
@@ -414,7 +414,7 @@
         	scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
         
         if (this.binding.isStatic()) {
-        	if (this.binding.declaringClass != this.receiverType)
+        	if (TypeBinding.notEquals(this.binding.declaringClass, this.receiverType))
         		scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
         } else {
         	AbstractMethodDeclaration srcMethod = this.binding.sourceMethod();
@@ -621,7 +621,7 @@
 		if (tSam.parameters.length != sSam.parameters.length)
 			return false;
 		for (int i = 0, length = tSam.parameters.length; i < length; i++) {
-			if (tSam.parameters[i] != sSam.parameters[i])
+			if (TypeBinding.notEquals(tSam.parameters[i], sSam.parameters[i]))
 				return false;
 		}
 		
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 9d0f40d..8e4673e 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
@@ -155,7 +155,7 @@
 		}
 	} else {
 		this.saveValueVariable = null;
-		if (((this.bits & ASTNode.IsSynchronized) == 0) && this.expression != null && this.expression.resolvedType == TypeBinding.BOOLEAN) {
+		if (((this.bits & ASTNode.IsSynchronized) == 0) && this.expression != null && TypeBinding.equalsEquals(this.expression.resolvedType, TypeBinding.BOOLEAN)) {
 			if (noAutoCloseables) { // can't abruptly return in the presence of autocloseables. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566
 				this.expression.bits |= ASTNode.IsReturnedValue;
 			}
@@ -336,7 +336,7 @@
 	if (methodType == null)
 		return;
 
-	if (methodType != expressionType) // must call before computeConversion() and typeMismatchError()
+	if (TypeBinding.notEquals(methodType, expressionType)) // must call before computeConversion() and typeMismatchError()
 		scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
 	if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)
 			|| expressionType.isCompatibleWith(methodType)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 88b387d..b369c77 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -146,7 +146,7 @@
 					currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this);
 				}
 			} else if (!isCompound && fieldBinding.isNonNull()
-						&& fieldBinding.declaringClass == currentScope.enclosingReceiverType()) { // inherited fields are not tracked here
+						&& TypeBinding.equalsEquals(fieldBinding.declaringClass, currentScope.enclosingReceiverType())) { // inherited fields are not tracked here
 				// record assignment for detecting uninitialized non-null fields:
 				flowInfo.markAsDefinitelyAssigned(fieldBinding);
 			}
@@ -242,7 +242,7 @@
 			SourceTypeBinding sourceType = scope.enclosingSourceType();
 			if (this.constant == Constant.NotAConstant
 					&& !methodScope.isStatic
-					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+					&& (TypeBinding.equalsEquals(sourceType, declaringClass) || TypeBinding.equalsEquals(sourceType.superclass, declaringClass)) // enum constant body
 					&& methodScope.isInsideInitializerOrConstructor()) {
 				scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
 			}
@@ -268,7 +268,7 @@
 		scope.problemReporter().deprecatedField(fieldBinding, this);
 
 	if ((this.bits & ASTNode.IsStrictlyAssigned) == 0
-			&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass
+			&& TypeBinding.equalsEquals(methodScope.enclosingSourceType(), fieldBinding.original().declaringClass)
 			&& methodScope.lastVisibleFieldID >= 0
 			&& fieldBinding.id >= methodScope.lastVisibleFieldID
 			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
@@ -450,7 +450,7 @@
 				if (codegenField.isStatic()) {
 					if (!valueRequired
 							// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
-							&& ((FieldBinding)this.binding).original().declaringClass == this.actualReceiverType.erasure()
+							&& TypeBinding.equalsEquals(((FieldBinding)this.binding).original().declaringClass, this.actualReceiverType.erasure())
 							&& ((this.implicitConversion & TypeIds.UNBOXING) == 0)
 							&& this.genericCast == null) {
 						// if no valueRequired, optimize out entire gen
@@ -813,7 +813,7 @@
 			}
 
 			// using incr bytecode if possible
-			if (localBinding.type == TypeBinding.INT) {
+			if (TypeBinding.equalsEquals(localBinding.type, TypeBinding.INT)) {
 				if (valueRequired) {
 					codeStream.load(localBinding);
 				}
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 c51aeb0..0a592e2 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
@@ -842,7 +842,7 @@
 	if (memberTypeBinding != null && this.memberTypes != null) {
 		for (int i = 0, max = this.memberTypes.length; i < max; i++) {
 			TypeDeclaration memberTypeDecl;
-			if ((memberTypeDecl = this.memberTypes[i]).binding == memberTypeBinding)
+			if (TypeBinding.equalsEquals((memberTypeDecl = this.memberTypes[i]).binding, memberTypeBinding))
 				return memberTypeDecl;
 		}
 	}
@@ -1848,7 +1848,7 @@
 						if (needSerialVersion
 								&& ((fieldBinding.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) == (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal))
 								&& CharOperation.equals(TypeConstants.SERIALVERSIONUID, fieldBinding.name)
-								&& TypeBinding.LONG == fieldBinding.type) {
+								&& TypeBinding.equalsEquals(TypeBinding.LONG, fieldBinding.type)) {
 							needSerialVersion = false;
 						}
 						localMaxFieldCount++;
@@ -1876,7 +1876,7 @@
 			if (javaxRmiCorbaStub.isValidBinding()) {
 				ReferenceBinding superclassBinding = this.binding.superclass;
 				loop: while (superclassBinding != null) {
-					if (superclassBinding == javaxRmiCorbaStub) {
+					if (TypeBinding.equalsEquals(superclassBinding, javaxRmiCorbaStub)) {
 						needSerialVersion = false;
 						break loop;
 					}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 6b1ebdb..39d3130 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -2728,7 +2728,7 @@
 	    if (arguments != null) { // for bridge methods
 		    TypeBinding argument = arguments[i];
 			load(argument, resolvedPosition);
-			if (argument != parameter)
+			if (TypeBinding.notEquals(argument, parameter))
 			    checkcast(parameter);
 	    } else {
 			load(parameter, resolvedPosition);
@@ -2914,7 +2914,7 @@
 		boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
 		for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
 			ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
-			if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
+			if (hasExtraEnclosingInstance && TypeBinding.equalsEquals(syntheticArgType, targetEnclosingType)) {
 				hasExtraEnclosingInstance = false;
 				enclosingInstance.generateCode(currentScope, this, true);
 				if (complyTo14){
@@ -3180,7 +3180,7 @@
 	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
 	// and not from Object or implicit static field access.
-	if (constantPoolDeclaringClass != actualReceiverType.erasure()
+	if (TypeBinding.notEquals(constantPoolDeclaringClass, actualReceiverType.erasure())
 			&& !actualReceiverType.isArrayType()
 			&& constantPoolDeclaringClass != null // array.length
 			&& codegenBinding.constant() == Constant.NotAConstant) {
@@ -3218,7 +3218,7 @@
 		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
 		// and not from Object or implicit static method call.
-		if (constantPoolDeclaringClass != actualReceiverType.erasure() && !actualReceiverType.isArrayType()) {
+		if (TypeBinding.notEquals(constantPoolDeclaringClass, actualReceiverType.erasure()) && !actualReceiverType.isArrayType()) {
 			CompilerOptions options = currentScope.compilerOptions();
 			if ((options.targetJDK >= ClassFileConstants.JDK1_2
 						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index d860a8d..44d19f6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -148,7 +148,7 @@
 		int index = this.indexes.get(this.handledExceptions[i]);
 		if ((this.isReached[index / ExceptionHandlingFlowContext.BitCacheSize] & 1 << (index % ExceptionHandlingFlowContext.BitCacheSize)) == 0) {
 			for (int j = 0; j < docCommentReferencesLength; j++) {
-				if (docCommentReferences[j] == this.handledExceptions[i]) {
+				if (TypeBinding.equalsEquals(docCommentReferences[j], this.handledExceptions[i])) {
 					continue nextHandledException;
 				}
 			}
@@ -193,7 +193,7 @@
 		TypeReference[] typeRefs = ((UnionTypeReference)node).typeReferences;
 		for (int i = 0, len = typeRefs.length; i < len; i++) {
 			TypeReference typeRef = typeRefs[i];
-			if (typeRef.resolvedType == this.handledExceptions[index]) return typeRef;
+			if (TypeBinding.equalsEquals(typeRef.resolvedType, this.handledExceptions[index])) return typeRef;
 		}	
 	} 
 	return node;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 4804eec..aea95e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -477,7 +477,7 @@
 		if ((exception = raisedExceptions[i]) != null) {
 			// only one complaint if same exception declared to be thrown more than once
 			for (int j = 0; j < i; j++) {
-				if (raisedExceptions[j] == exception) continue nextReport; // already reported
+				if (TypeBinding.equalsEquals(raisedExceptions[j], exception)) continue nextReport; // already reported
 			}
 			scope.problemReporter().unhandledException(exception, location);
 		}
@@ -494,7 +494,7 @@
 	do {
 		if (current instanceof InitializationFlowContext) {
 			InitializationFlowContext initializationContext = (InitializationFlowContext) current;
-			if (((TypeDeclaration)initializationContext.associatedNode).binding == declaringType) {
+			if (TypeBinding.equalsEquals(((TypeDeclaration)initializationContext.associatedNode).binding, declaringType)) {
 				return inits;
 			}
 			inits = initializationContext.initsBeforeContext;
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 e8782d5..2e21029 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
@@ -200,7 +200,7 @@
  */
 public TypeBinding erasure() {
     TypeBinding erasedType = this.leafComponentType.erasure();
-    if (this.leafComponentType != erasedType)
+    if (TypeBinding.notEquals(this.leafComponentType, erasedType))
         return this.environment.createArrayType(erasedType, this.dimensions);
     return this;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index efb4b8e..aa7813f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -1249,7 +1249,7 @@
 			for (int j = 0; j < currentMethodParameterLength; j++) {
 //{ObjectTeams: weaker form of equality:
 /* orig:
-				if (parameters[j] != parameters2[j] && parameters[j].erasure() != parameters2[j].erasure()) {
+				if (TypeBinding.notEquals(parameters[j], parameters2[j]) && TypeBinding.notEquals(parameters[j].erasure(), parameters2[j].erasure())) {
   :giro */
 				if (   !AnchorMapping.areTypesEqual(parameters[j], parameters2[j], currentMethod) 
 					&& !AnchorMapping.areTypesEqual(parameters[j].erasure(), parameters2[j].erasure(), currentMethod)) {
@@ -1296,7 +1296,7 @@
 				for (int iarg = 0; iarg < argCount; iarg++)
 //{ObjectTeams: weaker form of equality:
 /* orig:
-					if (toMatch[iarg] != argumentTypes[iarg])
+					if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
   :giro */
 					if (!AnchorMapping.areTypesEqual(toMatch[iarg], argumentTypes[iarg], method))
 // SH}
@@ -1338,7 +1338,7 @@
 				for (int iarg = 0; iarg < argCount; iarg++)
 //{ObjectTeams: weaker form of equality:
 /* orig:
-					if (toMatch[iarg] != argumentTypes[iarg])
+					if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
   :giro */
 					if (!AnchorMapping.areTypesEqual(toMatch[iarg], argumentTypes[iarg], method))
 // SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index ed0057e..4aa756a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -199,7 +199,7 @@
 		return true;
 // SH}
 
-	if (enclosingReceiverType() != binding.declaringClass)
+	if (TypeBinding.notEquals(enclosingReceiverType(), binding.declaringClass))
 		return false;
 
 	MethodScope methodScope = methodScope();
@@ -319,7 +319,7 @@
 				// assign variable position
 				local.resolvedPosition = this.offset;
 
-				if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) {
+				if ((TypeBinding.equalsEquals(local.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(local.type, TypeBinding.DOUBLE))) {
 					this.offset += 2;
 				} else {
 					this.offset++;
@@ -919,7 +919,7 @@
 
 	// use 'this' if possible
 	if (!currentMethodScope.isStatic && !currentMethodScope.isConstructorCall) {
-		if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) {
+		if (TypeBinding.equalsEquals(sourceType, targetEnclosingType) || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) {
 			return BlockScope.EmulationPathToImplicitThis; // implicit this is good enough
 		}
 	}
@@ -942,7 +942,7 @@
 			if (denyEnclosingArgInConstructorCall
 					&& currentMethodScope.isConstructorCall
 					&& !isAnonymousAndHasEnclosing
-					&& (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null))) {
+					&& (TypeBinding.equalsEquals(sourceType, targetEnclosingType) || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null))) {
 				return BlockScope.NoEnclosingInstanceInConstructorCall;
 			}
 			return new Object[] { syntheticArg };
@@ -976,7 +976,7 @@
 			if (enclosingArgument != null) {
 				FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument);
 				if (syntheticField != null) {
-					if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeOriginatingFrom(targetEnclosingType) != null))
+					if (TypeBinding.equalsEquals(syntheticField.type, targetEnclosingType) || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeOriginatingFrom(targetEnclosingType) != null))
 						return new Object[] { syntheticField };
 				}
 			}
@@ -1019,7 +1019,7 @@
 		while ((currentEnclosingType = currentType.enclosingType()) != null) {
 
 			//done?
-			if (currentType == targetEnclosingType
+			if (TypeBinding.equalsEquals(currentType, targetEnclosingType)
 				|| (!onlyExactMatch && currentType.findSuperTypeOriginatingFrom(targetEnclosingType) != null))	break;
 
 			if (currentMethodScope != null) {
@@ -1058,7 +1058,7 @@
 // SH}
 			currentType = currentEnclosingType;
 		}
-		if (currentType == targetEnclosingType
+		if (TypeBinding.equalsEquals(currentType, targetEnclosingType)
 			|| (!onlyExactMatch && currentType.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) {
 			return path;
 		}
@@ -1112,7 +1112,7 @@
 			return false; // found some non-initializer context
 		}
 		ReferenceBinding enclosingType = methodScope.enclosingReceiverType();
-		if (enclosingType == fieldDeclaringClass) {
+		if (TypeBinding.equalsEquals(enclosingType, fieldDeclaringClass)) {
 			return true; // found the field context, no need to check any further
 		}
 		if (!enclosingType.erasure().isAnonymousType()) {
@@ -1146,7 +1146,7 @@
 			SyntheticArgumentBinding syntheticArg = syntheticArguments[i];
 			// need to filter out the one that could match a supplied enclosing instance
 			if (!(isEnclosingInstanceSupplied
-				&& (syntheticArg.type == targetType.enclosingType()))) {
+				&& (TypeBinding.equalsEquals(syntheticArg.type, targetType.enclosingType())))) {
 				emulateOuterAccess(syntheticArg.actualOuterLocalVariable);
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
index b63d851..2264fb1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -126,7 +126,7 @@
 					} else {
 						// the wildcard bound should be a subtype of variable superclass
 						// it may occur that the bound is less specific, then consider glb (202404)
-						if (capturedWildcardBound.isArrayType() || capturedWildcardBound == this) {
+						if (capturedWildcardBound.isArrayType() || TypeBinding.equalsEquals(capturedWildcardBound, this)) {
 							this.setSuperClass(scope.getJavaLangObject());
 						} else {
 							this.setSuperClass((ReferenceBinding) capturedWildcardBound);
@@ -155,14 +155,14 @@
 		ReferenceBinding originalVariableSuperclass = wildcardVariable.superclass;
 		ReferenceBinding substitutedVariableSuperclass = (ReferenceBinding) Scope.substitute(capturedParameterizedType, originalVariableSuperclass);
 		// prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
-		if (substitutedVariableSuperclass == this) substitutedVariableSuperclass = originalVariableSuperclass;
+		if (TypeBinding.equalsEquals(substitutedVariableSuperclass, this)) substitutedVariableSuperclass = originalVariableSuperclass;
 
 		ReferenceBinding[] originalVariableInterfaces = wildcardVariable.superInterfaces();
 		ReferenceBinding[] substitutedVariableInterfaces = Scope.substitute(capturedParameterizedType, originalVariableInterfaces);
 		if (substitutedVariableInterfaces != originalVariableInterfaces) {
 			// prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
 			for (int i = 0, length = substitutedVariableInterfaces.length; i < length; i++) {
-				if (substitutedVariableInterfaces[i] == this) substitutedVariableInterfaces[i] = originalVariableInterfaces[i];
+				if (TypeBinding.equalsEquals(substitutedVariableInterfaces[i], this)) substitutedVariableInterfaces[i] = originalVariableInterfaces[i];
 			}
 		}
 		// no substitution for wildcard bound (only formal bounds from type variables are to be substituted: 104082)
@@ -190,7 +190,7 @@
 				} else {
 					// the wildcard bound should be a subtype of variable superclass
 					// it may occur that the bound is less specific, then consider glb (202404)
-					if (capturedWildcardBound.isArrayType() || capturedWildcardBound == this) {
+					if (capturedWildcardBound.isArrayType() || TypeBinding.equalsEquals(capturedWildcardBound, this)) {
 						this.setSuperClass(substitutedVariableSuperclass);
 					} else {
 						this.setSuperClass((ReferenceBinding) capturedWildcardBound);
@@ -211,7 +211,7 @@
 				break;
 			case Wildcard.SUPER :
 				this.setSuperClass(substitutedVariableSuperclass);
-				if (wildcardVariable.firstBound == substitutedVariableSuperclass || originalWildcardBound == substitutedVariableSuperclass) {
+				if (TypeBinding.equalsEquals(wildcardVariable.firstBound, substitutedVariableSuperclass) || TypeBinding.equalsEquals(originalWildcardBound, substitutedVariableSuperclass)) {
 					this.setFirstBound(substitutedVariableSuperclass);
 				}
 				this.setSuperInterfaces(substitutedVariableInterfaces);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
index fa8bcbd..15e1556 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
@@ -31,7 +31,7 @@
 	public void setPreciseType(TypeBinding raisedException) {
 		int length = this.preciseTypes.length;
 		for (int i = 0; i < length; ++i) {
-			if (this.preciseTypes[i] == raisedException)
+			if (TypeBinding.equalsEquals(this.preciseTypes[i], raisedException))
 				return;
 		}
 		System.arraycopy(this.preciseTypes, 0, this.preciseTypes = new TypeBinding [length + 1], 0, length);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 42c4db4..b8bdc8f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -1345,7 +1345,7 @@
 
 			TypeReference[] boundRefs = typeParameter.bounds;
 			if (boundRefs != null) {
-				boolean checkSuperclass = typeVariable.firstBound == typeVariable.superclass;
+				boolean checkSuperclass = TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass);
 				for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
 					TypeReference typeRef = boundRefs[j];
 					TypeBinding superType = typeRef.resolvedType;
@@ -1397,7 +1397,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -1422,7 +1422,7 @@
 						nextInterface : for (int a = 0; a < itsLength; a++) {
 							ReferenceBinding next = itsInterfaces[a];
 							for (int b = 0; b < nextPosition; b++)
-								if (next == interfacesToVisit[b]) continue nextInterface;
+								if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 							interfacesToVisit[nextPosition++] = next;
 						}
 					}
@@ -2068,7 +2068,7 @@
 			// check for simple interface collisions
 			// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
 			for (int j = 0; j < i; j++) {
-				if (interfaceBindings[j] == superInterface) {
+				if (TypeBinding.equalsEquals(interfaceBindings[j], superInterface)) {
 					problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface);
 					sourceType.tagBits |= TagBits.HierarchyHasProblems;
 					noProblems = false;
@@ -2251,7 +2251,7 @@
 			superType = ((RawTypeBinding) superType).genericType();
 		// by this point the superType must be a binary or source type
 
-		if (sourceType == superType) {
+		if (TypeBinding.equalsEquals(sourceType, superType)) {
 			problemReporter().hierarchyCircularity(sourceType, superType, reference);
 			sourceType.tagBits |= TagBits.HierarchyHasProblems;
 			return true;
@@ -2260,7 +2260,7 @@
 		if (superType.isMemberType()) {
 			ReferenceBinding current = superType.enclosingType();
 			do {
-				if (current.isHierarchyBeingActivelyConnected() && current == sourceType) {
+				if (current.isHierarchyBeingActivelyConnected() && TypeBinding.equalsEquals(current, sourceType)) {
 					problemReporter().hierarchyCircularity(sourceType, current, reference);
 					sourceType.tagBits |= TagBits.HierarchyHasProblems;
 					current.tagBits |= TagBits.HierarchyHasProblems;
@@ -2276,7 +2276,7 @@
 			boolean hasCycle = false;
 			ReferenceBinding parentType = superType.superclass();
 			if (parentType != null) {
-				if (sourceType == parentType) {
+				if (TypeBinding.equalsEquals(sourceType, parentType)) {
 					problemReporter().hierarchyCircularity(sourceType, superType, reference);
 					sourceType.tagBits |= TagBits.HierarchyHasProblems;
 					superType.tagBits |= TagBits.HierarchyHasProblems;
@@ -2295,7 +2295,7 @@
 			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
 				for (int i = 0, length = itsInterfaces.length; i < length; i++) {
 					ReferenceBinding anInterface = itsInterfaces[i];
-					if (sourceType == anInterface) {
+					if (TypeBinding.equalsEquals(sourceType, anInterface)) {
 						problemReporter().hierarchyCircularity(sourceType, superType, reference);
 						sourceType.tagBits |= TagBits.HierarchyHasProblems;
 						superType.tagBits |= TagBits.HierarchyHasProblems;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 93304d5..f953c7f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -1186,14 +1186,14 @@
 		ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]);
 		if (existingType != null) {
 			// duplicate test above should have caught this case, but make sure
-			if (existingType == referenceBinding) {
+			if (TypeBinding.equalsEquals(existingType, referenceBinding)) {
 				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865
 				// Check all resolved imports to see if this import qualifies as a duplicate
 				for (int j = 0; j < this.importPtr; j++) {
 					ImportBinding resolved = this.tempImports[j];
 					if (resolved instanceof ImportConflictBinding) {
 						ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved;
-						if (importConflictBinding.conflictingTypeBinding == referenceBinding) {
+						if (TypeBinding.equalsEquals(importConflictBinding.conflictingTypeBinding, referenceBinding)) {
 							if (!importReference.isStatic()) {
 								// resolved is implicitly static
 								problemReporter().duplicateImport(importReference);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index 7434c19..6f8236f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -532,7 +532,7 @@
 				switch (two.kind()) {
 					case Binding.PARAMETERIZED_TYPE:
 					case Binding.RAW_TYPE:
-						if (one == two.erasure())
+						if (TypeBinding.equalsEquals(one, two.erasure()))
 							return true;
 				}
 				break;
@@ -540,7 +540,7 @@
 			case Binding.PARAMETERIZED_TYPE:
 				switch(two.kind()) {
 					case Binding.TYPE:
-						if (one.erasure() == two)
+						if (TypeBinding.equalsEquals(one.erasure(), two))
 							return true;
 				}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
index dd1a922..b33387a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
@@ -90,7 +90,7 @@
 * all its dependents so as to update them (see updateInnerEmulationDependents()).
 */
 public void addInnerEmulationDependent(BlockScope dependentScope, boolean wasEnclosingInstanceSupplied) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	int index;
 	if (this.dependents == null) {
 		index = 0;
@@ -110,7 +110,7 @@
  * Returns the anonymous original super type (in some error cases, superclass may get substituted with Object)
  */
 public ReferenceBinding anonymousOriginalSuperType() {
-	if (this != this.prototype)
+	if (!isPrototype())
 		return ((LocalTypeBinding) this.prototype).anonymousOriginalSuperType();
 	
 	if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
@@ -130,7 +130,7 @@
 
 protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
 	
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	
 	long outerDefault = this.enclosingMethod != null ? this.enclosingMethod.tagBits & ((TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault)) : 0;
 	if (outerDefault != 0) {
@@ -143,7 +143,7 @@
 }
 
 public char[] computeUniqueKey(boolean isLeaf) {
-	if (this != this.prototype)
+	if (!isPrototype())
 		return this.prototype.computeUniqueKey(isLeaf);
 	
 	char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf);
@@ -174,7 +174,7 @@
 public char[] constantPoolName() /* java/lang/Object */ {
 	if (this.constantPoolName != null)
 		return this.constantPoolName;
-	if (this != this.prototype)
+	if (!isPrototype())
 		return this.constantPoolName = this.prototype.constantPoolName();
 	if (this.constantPoolName == null && this.scope != null) {
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322154, we do have some
@@ -200,7 +200,7 @@
  */
 public char[] genericTypeSignature() {
 	
-	if (this != this.prototype)
+	if (!isPrototype())
 		return this.prototype.genericTypeSignature();
 	
 	if (this.genericReferenceTypeSignature == null && this.constantPoolName == null) {
@@ -264,7 +264,7 @@
 
 // Record that the type is a local member type
 public void setAsMemberType() {
-	if (this != this.prototype) {
+	if (!isPrototype()) {
 		this.tagBits |= TagBits.MemberTypeMask;
 		((LocalTypeBinding) this.prototype).setAsMemberType();
 		return;
@@ -273,7 +273,7 @@
 }
 
 public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
-	if (this != this.prototype) {
+	if (!isPrototype()) {
 		this.constantPoolName = computedConstantPoolName;
 		((LocalTypeBinding) this.prototype).setConstantPoolName(computedConstantPoolName);
 		return;
@@ -298,7 +298,7 @@
  */
 public char[] signature() {
 	
-	if (this != this.prototype)
+	if (!isPrototype())
 		return this.prototype.signature();
 	
 	if (this.signature == null && this.constantPoolName == null) {
@@ -332,7 +332,7 @@
 * to be propagated to all dependent source types.
 */
 public void updateInnerEmulationDependents() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	if (this.dependents != null) {
 		for (int i = 0; i < this.dependents.length; i++) {
 			InnerEmulationDependency dependency = this.dependents[i];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 73b42bd..816f22d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -709,7 +709,7 @@
 			convertedEnclosingType = originalType.isStatic()
 				? (ReferenceBinding) convertToRawType(originalEnclosingType, false /*do not force conversion of enclosing types*/)
 				: convertToParameterizedType(originalEnclosingType);
-			needToConvert |= originalEnclosingType != convertedEnclosingType;
+			needToConvert |= TypeBinding.notEquals(originalEnclosingType, convertedEnclosingType);
 		}
 		if (needToConvert) {
 			return createParameterizedType(originalType, isGeneric ? originalType.typeVariables() : null, convertedEnclosingType);
@@ -770,7 +770,7 @@
 			convertedEnclosing = originalEnclosing;
 		} else if (forceRawEnclosingType && !needToConvert/*stop recursion when conversion occurs*/) {
 			convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing, forceRawEnclosingType);
-			needToConvert = originalEnclosing != convertedEnclosing; // only convert generic or parameterized types
+			needToConvert = TypeBinding.notEquals(originalEnclosing, convertedEnclosing); // only convert generic or parameterized types
 		} else if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
 			convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing, false);
 		} else {
@@ -778,13 +778,13 @@
 		}
 		if (needToConvert) {
 			convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
-		} else if (originalEnclosing != convertedEnclosing) {
+		} else if (TypeBinding.notEquals(originalEnclosing, convertedEnclosing)) {
 			convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
 		} else {
 			convertedType = originalType;
 		}
 	}
-	if (originalType != convertedType) {
+	if (TypeBinding.notEquals(originalType, convertedType)) {
 		return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
 	}
 	return type;
@@ -800,7 +800,7 @@
     for (int i = 0, length = originalTypes.length; i < length; i++) {
         ReferenceBinding originalType = originalTypes[i];
         ReferenceBinding convertedType = (ReferenceBinding) convertToRawType(forceErasure ? originalType.erasure() : originalType, forceRawEnclosingType);
-        if (convertedType != originalType) {        
+        if (TypeBinding.notEquals(convertedType, originalType)) {        
             if (convertedTypes == originalTypes) {
                 System.arraycopy(originalTypes, 0, convertedTypes = new ReferenceBinding[length], 0, i);
             }
@@ -854,18 +854,18 @@
 		convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
 	} else {
 		ReferenceBinding convertedEnclosing = (ReferenceBinding) convertUnresolvedBinaryToRawType(originalEnclosing);
-		if (convertedEnclosing != originalEnclosing) {
+		if (TypeBinding.notEquals(convertedEnclosing, originalEnclosing)) {
 			needToConvert |= !((ReferenceBinding)originalType).isStatic();
 		}
 		if (needToConvert) {
 			convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
-		} else if (originalEnclosing != convertedEnclosing) {
+		} else if (TypeBinding.notEquals(originalEnclosing, convertedEnclosing)) {
 			convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
 		} else {
 			convertedType = originalType;
 		}
 	}
-	if (originalType != convertedType) {
+	if (TypeBinding.notEquals(originalType, convertedType)) {
 		return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
 	}
 	return type;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
index a4cefa4..6316d84 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
@@ -54,7 +54,7 @@
 }
 
 void checkSyntheticArgsAndFields() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 //{ObjectTeams: role ifcs require synth args too
 /* orig:
 	if (isStatic()) return;
@@ -67,7 +67,7 @@
 	}
 	if (isStatic()) return;
 // SH}
-	if (this != this.prototype) {
+	if (!isPrototype()) {
 		((MemberTypeBinding) this.prototype).checkSyntheticArgsAndFields();
 		return;
 	}
@@ -83,7 +83,7 @@
 	if (this.constantPoolName != null)
 		return this.constantPoolName;
 	
-	if (this != this.prototype) {
+	if (!isPrototype()) {
 		return this.prototype.constantPoolName();
 	}
 
@@ -100,7 +100,7 @@
  * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
  */
 public void initializeDeprecatedAnnotationTagBits() {
-	if (this != this.prototype) {
+	if (!isPrototype()) {
 		this.prototype.initializeDeprecatedAnnotationTagBits();
 		return;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index 403aaed..bd21547 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -316,12 +316,12 @@
 		if (paramLength == argLength) { // accept X[] but not X or X[][]
 			TypeBinding varArgType = this.parameters[lastIndex]; // is an ArrayBinding by definition
 			TypeBinding lastArgument = arguments[lastIndex];
-			if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
+			if (TypeBinding.notEquals(varArgType, lastArgument) && !lastArgument.isCompatibleWith(varArgType))
 				return false;
 		} else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
 			TypeBinding varArgType = ((ArrayBinding) this.parameters[lastIndex]).elementsType();
 			for (int i = lastIndex; i < argLength; i++)
-				if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
+				if (TypeBinding.notEquals(varArgType, arguments[i]) && !arguments[i].isCompatibleWith(varArgType))
 					return false;
 		} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
 			return false;
@@ -329,7 +329,7 @@
 		// now compare standard arguments from 0 to lastIndex
 	}
 	for (int i = 0; i < lastIndex; i++)
-		if (this.parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(this.parameters[i]))
+		if (TypeBinding.notEquals(this.parameters[i], arguments[i]) && !arguments[i].isCompatibleWith(this.parameters[i]))
 			return false;
 	return true;
 }
@@ -366,7 +366,7 @@
 		return false;
 
 	for (int i = 0; i < length; i++)
-		if (this.typeVariables[i] != vars[i] && this.typeVariables[i].erasure() != vars[i].erasure())
+		if (TypeBinding.notEquals(this.typeVariables[i], vars[i]) && TypeBinding.notEquals(this.typeVariables[i].erasure(), vars[i].erasure()))
 			return false;
 	return true;
 }
@@ -415,7 +415,7 @@
 	if (isPublic()) return true;
 
 	SourceTypeBinding invocationType = scope.enclosingSourceType();
-	if (invocationType == this.declaringClass) return true;
+	if (TypeBinding.equalsEquals(invocationType, this.declaringClass)) return true;
 
 	if (isProtected()) {
 //{ObjectTeams: for role check enclosing team rather than package:
@@ -450,7 +450,7 @@
 			outerDeclaringClass = temp;
 			temp = temp.enclosingType();
 		}
-		return outerInvocationType == outerDeclaringClass;
+		return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
 	}
 
 	// isDefault()
@@ -952,7 +952,7 @@
 	TypeBinding superType = this.declaringClass.findSuperTypeOriginatingFrom(inheritedOriginal.declaringClass);
 	if (superType == null || !(superType instanceof ReferenceBinding)) return null;
 
-	if (inheritedOriginal.declaringClass != superType) {
+	if (TypeBinding.notEquals(inheritedOriginal.declaringClass, superType)) {
 		// must find inherited method with the same substituted variables
 		MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(inheritedOriginal.selector, inheritedOriginal.parameters.length);
 		for (int m = 0, l = superMethods.length; m < l; m++)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index 3224ea3..f68f16d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -388,7 +388,7 @@
 		// assign variable position
 		local.resolvedPosition = this.offset;
 
-		if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) {
+		if ((TypeBinding.equalsEquals(local.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(local.type, TypeBinding.DOUBLE))) {
 			this.offset += 2;
 		} else {
 			this.offset++;
@@ -405,7 +405,7 @@
 		for (int iarg = 0, maxArguments = this.extraSyntheticArguments.length; iarg < maxArguments; iarg++){
 			SyntheticArgumentBinding argument = this.extraSyntheticArguments[iarg];
 			argument.resolvedPosition = this.offset;
-			if ((argument.type == TypeBinding.LONG) || (argument.type == TypeBinding.DOUBLE)){
+			if ((TypeBinding.equalsEquals(argument.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(argument.type, TypeBinding.DOUBLE))){
 				this.offset += 2;
 			} else {
 				this.offset++;
@@ -521,7 +521,7 @@
 	if (field.isStatic())
 		return field; // static fields are always accessible
 
-	if (!this.isConstructorCall || receiverType != enclosingSourceType())
+	if (!this.isConstructorCall || TypeBinding.notEquals(receiverType, enclosingSourceType()))
 		return field;
 
 	if (invocationSite instanceof SingleNameReference)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 3c4ed92..71b5c08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -146,7 +146,7 @@
 }
 boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
 	return two == null // already know one is not null
-		|| one.declaringClass == two.declaringClass;
+		|| TypeBinding.equalsEquals(one.declaringClass, two.declaringClass);
 }
 void checkAbstractMethod(MethodBinding abstractMethod) {
 //{ObjectTeams: shortcut for special methods:
@@ -490,7 +490,7 @@
 					continue;
 // SH}
 				for (int r = 0, rl = refs.length; r < rl; r++) {
-					if (refs[r].resolvedType == toCheck) {
+					if (TypeBinding.equalsEquals(refs[r].resolvedType, toCheck)) {
 						problemReporter().redundantSuperInterface(this.type, refs[j], implementedInterface, toCheck);
 						break; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=320911
 					}
@@ -517,7 +517,7 @@
 						redundantInterfaces.add(inheritedInterface);
 						TypeReference[] refs = this.type.scope.referenceContext.superInterfaces;
 						for (int r = 0, rl = refs.length; r < rl; r++) {
-							if (refs[r].resolvedType == inheritedInterface) {
+							if (TypeBinding.equalsEquals(refs[r].resolvedType, inheritedInterface)) {
 								problemReporter().redundantSuperInterface(this.type, refs[r], inheritedInterface, superType);
 								break;
 							}
@@ -553,7 +553,7 @@
 						redundantInterfaces.add(inheritedInterface);
 						TypeReference[] refs = this.type.scope.referenceContext.superInterfaces;
 						for (int r = 0, rl = refs.length; r < rl; r++) {
-							if (refs[r].resolvedType == inheritedInterface) {
+							if (TypeBinding.equalsEquals(refs[r].resolvedType, inheritedInterface)) {
 								problemReporter().redundantSuperInterface(this.type, refs[r], inheritedInterface, superType);
 								break;
 							}
@@ -684,7 +684,7 @@
 					return; // found concrete implementation of abstract method in same package
 			}
 		}
-	} while ((superType = superType.superclass()) != abstractMethod.declaringClass);
+	} while (TypeBinding.notEquals((superType = superType.superclass()), abstractMethod.declaringClass));
 
 	// non visible abstract methods cannot be overridden so the type must be defined abstract
 	problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
@@ -732,7 +732,7 @@
 					MethodBinding existingMethod = existingMethods[i];
 					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358, skip inherited method only if any overriding version
 					// in a subclass is guaranteed to have the same erasure as an existing method.
-					if (existingMethod.declaringClass != inheritedMethod.declaringClass && areMethodsCompatible(existingMethod, inheritedMethod) && !canOverridingMethodDifferInErasure(existingMethod, inheritedMethod)) {
+					if (TypeBinding.notEquals(existingMethod.declaringClass, inheritedMethod.declaringClass) && areMethodsCompatible(existingMethod, inheritedMethod) && !canOverridingMethodDifferInErasure(existingMethod, inheritedMethod)) {
 						if (inheritedMethod.isDefault()) {
 							if (inheritedMethod.isAbstract()) {
 								checkPackagePrivateAbstractMethod(inheritedMethod);
@@ -923,14 +923,14 @@
 	for (int i = 0; i < inheritedLength; i++) {
 		TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i];
 		TypeVariableBinding typeVariable = (TypeVariableBinding) arguments[i]; // cast is safe by construction: arguments is copied from TypeVariableBinding[]
-		if (typeVariable.firstBound == inheritedTypeVariable.firstBound) {
+		if (TypeBinding.equalsEquals(typeVariable.firstBound, inheritedTypeVariable.firstBound)) {
 			if (typeVariable.firstBound == null)
 				continue; // both are null
 		} else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) {
 			if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass())
 				return inheritedMethod; // not a match
 		}
-		if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass)
+		if (TypeBinding.notEquals(Scope.substitute(substitute, inheritedTypeVariable.superclass), typeVariable.superclass))
 			return inheritedMethod; // not a match
 		int interfaceLength = inheritedTypeVariable.superInterfaces.length;
 		ReferenceBinding[] interfaces = typeVariable.superInterfaces;
@@ -939,7 +939,7 @@
 		next : for (int j = 0; j < interfaceLength; j++) {
 			TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]);
 			for (int k = 0; k < interfaceLength; k++)
-				if (superType == interfaces[k])
+				if (TypeBinding.equalsEquals(superType, interfaces[k]))
 					continue next;
 			return inheritedMethod; // not a match
 		}
@@ -1023,7 +1023,7 @@
 		// only keep methods from the closest superclass, all others from higher superclasses can be skipped
 		// NOTE: methods were added in order by walking up the superclass hierarchy
 		ReferenceBinding declaringClass2 = methods[++i].declaringClass;
-		while (declaringClass == declaringClass2) {
+		while (TypeBinding.equalsEquals(declaringClass, declaringClass2)) {
 			if (++i == length) return null;
 			declaringClass2 = methods[i].declaringClass;
 		}
@@ -1046,7 +1046,7 @@
 		for (int j = i + 1; j < length; j++) {
 			if (toSkip != null && toSkip[j] == -1) continue;
 			ReferenceBinding declaringClass2 = methods[j].declaringClass;
-			if (declaringClass == declaringClass2) continue;
+			if (TypeBinding.equalsEquals(declaringClass, declaringClass2)) continue;
 			if (declaringClass.implementsInterface(declaringClass2, true)) {
 				if (toSkip == null)
 					toSkip = new int[length];
@@ -1157,7 +1157,7 @@
 
 boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
 	do {
-		if (testClass == superclass) return true;
+		if (TypeBinding.equalsEquals(testClass, superclass)) return true;
 	} while ((testClass = testClass.superclass()) != null);
 	return false;
 }
@@ -1190,7 +1190,7 @@
 	if (!mustImplementAbstractMethods()) return false;
 	ReferenceBinding superclass = this.type.superclass();
 	if (declaringClass.isClass()) {
-		while (superclass.isAbstract() && superclass != declaringClass)
+		while (superclass.isAbstract() && TypeBinding.notEquals(superclass, declaringClass))
 			superclass = superclass.superclass(); // find the first concrete superclass or the abstract declaringClass
 	} else {
 		if (this.type.implementsInterface(declaringClass, false))
@@ -1212,7 +1212,7 @@
 
 ProblemReporter problemReporter(MethodBinding currentMethod) {
 	ProblemReporter reporter = problemReporter();
-	if (currentMethod.declaringClass == this.type && currentMethod.sourceMethod() != null)	// only report against the currentMethod if its implemented by the type
+	if (TypeBinding.equalsEquals(currentMethod.declaringClass, this.type) && currentMethod.sourceMethod() != null)	// only report against the currentMethod if its implemented by the type
 		reporter.referenceContext = currentMethod.sourceMethod();
 	return reporter;
 }
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 d7317d2..1d8c5fc 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
@@ -76,7 +76,7 @@
 }
 boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
 	return two == null // already know one is not null
-		|| (one.declaringClass == two.declaringClass && !one.declaringClass.isParameterizedType());
+		|| (TypeBinding.equalsEquals(one.declaringClass, two.declaringClass) && !one.declaringClass.isParameterizedType());
 }
 void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
 	super.checkConcreteInheritedMethod(concreteMethod, abstractMethods);
@@ -93,7 +93,7 @@
 
 		// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
 		MethodBinding originalInherited = abstractMethod.original();
-		if (originalInherited.returnType != concreteMethod.returnType)
+		if (TypeBinding.notEquals(originalInherited.returnType, concreteMethod.returnType))
 			if (!isAcceptableReturnTypeOverride(concreteMethod, abstractMethod))
 				problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type);
 
@@ -102,7 +102,7 @@
 		// bridge will be/would have been generated in the context of the super class since
 		// the bridge itself will be inherited. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=298362
 		if (originalInherited.declaringClass.isInterface()) {
-			if ((concreteMethod.declaringClass == this.type.superclass && this.type.superclass.isParameterizedType() && !areMethodsCompatible(concreteMethod, originalInherited))
+			if ((TypeBinding.equalsEquals(concreteMethod.declaringClass, this.type.superclass) && this.type.superclass.isParameterizedType() && !areMethodsCompatible(concreteMethod, originalInherited))
 				|| this.type.superclass.erasure().findSuperTypeOriginatingFrom(originalInherited.declaringClass) == null)
 					this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
 		}
@@ -139,7 +139,7 @@
 		MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(bridge.selector);
 		for (int i = current.length - 1; i >= 0; --i) {
 			final MethodBinding thisMethod = current[i];
-			if (thisMethod.areParameterErasuresEqual(bridge) && thisMethod.returnType.erasure() == bridge.returnType.erasure()) {
+			if (thisMethod.areParameterErasuresEqual(bridge) && TypeBinding.equalsEquals(thisMethod.returnType.erasure(), bridge.returnType.erasure())) {
 				// use inherited method for problem reporting.
 				problemReporter(thisMethod).methodNameClash(thisMethod, inheritedMethod.declaringClass.isRawType() ? inheritedMethod : inheritedMethod.original(), ProblemSeverities.Error);
 				return;	
@@ -195,7 +195,7 @@
 		if (length != inheritedParams.length) return; // no match
 
 		for (int i = 0; i < length; i++)
-			if (currentParams[i] != inheritedParams[i])
+			if (TypeBinding.notEquals(currentParams[i], inheritedParams[i]))
 				if (currentParams[i].isBaseType() != inheritedParams[i].isBaseType() || !inheritedParams[i].isCompatibleWith(currentParams[i]))
 					return; // no chance that another inherited method's bridge method can collide
 
@@ -226,7 +226,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -250,7 +250,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -284,7 +284,7 @@
 	boolean playingTrump = false; // invariant: playingTrump => (concreteMethod == null)
 	for (int i = 0; i < length; i++) {
 		if (!methods[i].declaringClass.isInterface()
-				&& methods[i].declaringClass != this.type
+				&& TypeBinding.notEquals(methods[i].declaringClass, this.type)
 				&& methods[i].isAbstract())
 		{
 			abstractSuperClassMethod = methods[i];
@@ -404,7 +404,7 @@
 		return;
 	}
 	// in this context currentMethod can be inherited, too. Recurse if needed.
-	if (currentMethod.declaringClass != this.type 
+	if (TypeBinding.notEquals(currentMethod.declaringClass, this.type) 
 			&& (currentMethod.tagBits & TagBits.IsNullnessKnown) == 0) 
 	{
 		this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, scope);
@@ -634,7 +634,7 @@
 				// Skip the otherInheritedMethod if it is completely replaced by inheritedMethod
 				// This elimination used to happen rather eagerly in computeInheritedMethods step
 				// itself earlier. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358)
-				if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass) {
+				if (TypeBinding.notEquals(inheritedMethod.declaringClass, otherInheritedMethod.declaringClass)) {
 					// these method calls produce their effect as side-effects into skip and isOverridden:
 					if (isSkippableOrOverridden(inheritedMethod, otherInheritedMethod, skip, isOverridden, j))
 						continue;
@@ -825,11 +825,11 @@
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323693
 	// When reporting a name clash between two inherited methods, we should not look for a
 	// signature clash, but instead should be looking for method descriptor clash. 
-	if (inherited.returnType.erasure() != otherInherited.returnType.erasure())
+	if (TypeBinding.notEquals(inherited.returnType.erasure(), otherInherited.returnType.erasure()))
 		return false;
 	// skip it if otherInherited is defined by a subtype of inherited's declaringClass or vice versa.
 	// avoid being order sensitive and check with the roles reversed also.
-	if (inherited.declaringClass.erasure() != otherInherited.declaringClass.erasure()) {
+	if (TypeBinding.notEquals(inherited.declaringClass.erasure(), otherInherited.declaringClass.erasure())) {
 		if (inherited.declaringClass.findSuperTypeOriginatingFrom(otherInherited.declaringClass) != null)
 			return false;
 		if (otherInherited.declaringClass.findSuperTypeOriginatingFrom(inherited.declaringClass) != null)
@@ -848,7 +848,7 @@
 	if (this.environment.globalOptions.complianceLevel == ClassFileConstants.JDK1_6) {
 		// for 1.6 return types also need to be checked
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719
-		if (current.returnType.erasure() != original.returnType.erasure())
+		if (TypeBinding.notEquals(current.returnType.erasure(), original.returnType.erasure()))
 			severity = ProblemSeverities.Warning;
 	}
 	if (!treatAsSynthetic) {
@@ -906,7 +906,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -925,7 +925,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -940,7 +940,7 @@
 			TypeBinding erasure = current.erasure();
 			for (int j = i + 1; j < nextPosition; j++) {
 				ReferenceBinding next = interfacesToVisit[j];
-				if (next.isValidBinding() && next.erasure() == erasure) {
+				if (next.isValidBinding() && TypeBinding.equalsEquals(next.erasure(), erasure)) {
 					if (copy == null)
 						copy = new SimpleSet(nextPosition);
 					copy.add(interfacesToVisit[i]);
@@ -965,7 +965,7 @@
 	TypeBinding currentReturnType = currentMethod.returnType.leafComponentType();
 	switch (currentReturnType.kind()) {
 	   	case Binding.TYPE_PARAMETER :
-	   		if (currentReturnType == inheritedMethod.returnType.leafComponentType())
+	   		if (TypeBinding.equalsEquals(currentReturnType, inheritedMethod.returnType.leafComponentType()))
 	   			return true;
 	   		//$FALL-THROUGH$
 		default :
@@ -982,8 +982,8 @@
 
 	inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
 	return inheritedMethod != null
-		&& (inheritedMethod.returnType == existingMethod.returnType	// need to keep around to produce bridge methods? ...
-			|| (this.type != existingMethod.declaringClass 			// ... not if inheriting the bridge situation from a superclass
+		&& (TypeBinding.equalsEquals(inheritedMethod.returnType, existingMethod.returnType)	// need to keep around to produce bridge methods? ...
+			|| (TypeBinding.notEquals(this.type, existingMethod.declaringClass) 			// ... not if inheriting the bridge situation from a superclass
 					&& !existingMethod.declaringClass.isInterface()))
 		&& doesMethodOverride(existingMethod, inheritedMethod);
 }
@@ -1002,7 +1002,7 @@
 	// called when currentMethod's return type is NOT compatible with inheritedMethod's return type
 
 	// JLS 3 �8.4.5: more are accepted, with an unchecked conversion
-	if (currentMethod.returnType == inheritedMethod.returnType.erasure()) {
+	if (TypeBinding.equalsEquals(currentMethod.returnType, inheritedMethod.returnType.erasure())) {
 		TypeBinding[] currentParams = currentMethod.parameters;
 		TypeBinding[] inheritedParams = inheritedMethod.parameters;
 		for (int i = 0, l = currentParams.length; i < l; i++)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
index 97d4c3c..f2f9e62 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
@@ -51,7 +51,7 @@
 */
 public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
 	
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	
 	SyntheticArgumentBinding synthLocal = null;
 
@@ -83,7 +83,7 @@
 * Answer the new argument or the existing argument if one already existed.
 */
 public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding targetEnclosingType) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	SyntheticArgumentBinding synthLocal = null;
 	if (this.enclosingInstances == null) {
 		synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
@@ -91,7 +91,7 @@
 	} else {
 		int size = this.enclosingInstances.length;
 		int newArgIndex = size;
-		if (enclosingType() == targetEnclosingType)
+		if (TypeBinding.equalsEquals(enclosingType(), targetEnclosingType))
 			newArgIndex = 0;
 		SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1];
 		System.arraycopy(this.enclosingInstances, 0, newInstances, newArgIndex == 0 ? 1 : 0, size);
@@ -108,7 +108,7 @@
 * Answer the new argument or the existing argument if one already existed.
 */
 public SyntheticArgumentBinding addSyntheticArgumentAndField(LocalVariableBinding actualOuterLocalVariable) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable);
 	if (synthLocal == null) return null;
 
@@ -121,7 +121,7 @@
 * Answer the new argument or the existing argument if one already existed.
 */
 public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding targetEnclosingType) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	SyntheticArgumentBinding synthLocal = addSyntheticArgument(targetEnclosingType);
 	if (synthLocal == null) return null;
 
@@ -131,7 +131,7 @@
 }
 
 protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	ReferenceBinding currentType = this.enclosingType;
 	do {
 		if (!((SourceTypeBinding)currentType).checkRedundantNullnessDefaultOne(location, annotations, annotationTagBits)) {
@@ -152,7 +152,7 @@
  * @return the enclosingInstancesSlotSize
  */
 public int getEnclosingInstancesSlotSize() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	return this.enclosingInstances == null ? 0 : this.enclosingInstances.length;
 }
 
@@ -160,7 +160,7 @@
  * @return the outerLocalVariablesSlotSize
  */
 public int getOuterLocalVariablesSlotSize() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	if (this.outerLocalVariablesSlotSize < 0) {
 		this.outerLocalVariablesSlotSize = 0;
 		int outerLocalsCount = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length;
@@ -183,7 +183,7 @@
 /* Answer the synthetic argument for <actualOuterLocalVariable> or null if one does not exist.
 */
 public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	if (this.outerLocalVariables == null) return null;		// is null if no outer local variables are known
 	for (int i = this.outerLocalVariables.length; --i >= 0;)
 		if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
@@ -195,7 +195,7 @@
 */
 public SyntheticArgumentBinding getSyntheticArgument(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean scopeIsConstructorCall) {
 	
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	
 	if (this.enclosingInstances == null) return null;		// is null if no enclosing instances are known
 	
@@ -212,13 +212,13 @@
 	//   }
 	// }
 	if (scopeIsConstructorCall && this.enclosingInstances.length > 0)
-		if (this.enclosingInstances[0].type == targetEnclosingType) 
+		if (TypeBinding.equalsEquals(this.enclosingInstances[0].type, targetEnclosingType)) 
 			if (this.enclosingInstances[0].actualOuterLocalVariable == null)
 				return this.enclosingInstances[0];
 	
 	// then check other possibility
 	for (int i = this.enclosingInstances.length; --i >= 0;)
-		if (this.enclosingInstances[i].type == targetEnclosingType)
+		if (TypeBinding.equalsEquals(this.enclosingInstances[i].type, targetEnclosingType))
 			if (this.enclosingInstances[i].actualOuterLocalVariable == null)
 				return this.enclosingInstances[i];
 
@@ -235,12 +235,12 @@
 }
 
 public SyntheticArgumentBinding[] syntheticEnclosingInstances() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	return this.enclosingInstances;		// is null if no enclosing instances are required
 }
 
 public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	if (this.enclosingTypes == UNINITIALIZED_REFERENCE_TYPES) {
 //{ObjectTeams: enclosing instances of local types are set during analyzeCode:
 		if (this.isLocalType())
@@ -260,7 +260,7 @@
 }
 
 public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
-	if (this != this.prototype) throw new IllegalStateException();
+	if (!isPrototype()) throw new IllegalStateException();
 	return this.outerLocalVariables;		// is null if no outer locals are required
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 621fa2b..78e2960 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -240,11 +240,11 @@
 						for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
 							TypeBinding equalSubstitute = equalSubstitutes[j];
 							if (equalSubstitute == null) continue nextConstraint;
-							if (equalSubstitute == current) {
+							if (TypeBinding.equalsEquals(equalSubstitute, current)) {
 								// try to find a better different match if any in subsequent equal candidates
 								for (int k = j+1; k < equalLength; k++) {
 									equalSubstitute = equalSubstitutes[k];
-									if (equalSubstitute != current && equalSubstitute != null) {
+									if (TypeBinding.notEquals(equalSubstitute, current) && equalSubstitute != null) {
 										substitutes[i] = equalSubstitute;
 										continue nextTypeParameter;
 									}
@@ -462,8 +462,8 @@
 		for (int i = 0; i < varLength; i++) {
 			TypeVariableBinding originalVariable = originalVariables[i];
 			TypeBinding argument = this.typeArguments[i];
-			boolean argAlreadyInferred = argument != originalVariable;
-			if (originalVariable.firstBound == originalVariable.superclass) {
+			boolean argAlreadyInferred = TypeBinding.notEquals(argument, originalVariable);
+			if (TypeBinding.equalsEquals(originalVariable.firstBound, originalVariable.superclass)) {
 				TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superclass);
 				argument.collectSubstitutes(scope, substitutedBound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
 				if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
@@ -511,7 +511,7 @@
     	// adjust method types to reflect latest inference
 		TypeBinding oldReturnType = this.returnType;
 		this.returnType = Scope.substitute(this, this.returnType);
-		this.inferredReturnType = inferenceContext.hasExplicitExpectedType && this.returnType != oldReturnType;
+		this.inferredReturnType = inferenceContext.hasExplicitExpectedType && TypeBinding.notEquals(this.returnType, oldReturnType);
 	    this.parameters = Scope.substitute(this, this.parameters);
 	    this.thrownExceptions = Scope.substitute(this, this.thrownExceptions);
 	    // error case where exception type variable would have been substituted by a non-reference type (207573)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
index 653f0cf..6769775 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
@@ -109,7 +109,7 @@
 				ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
 				if (originalVariable.firstBound != null) {
 					TypeBinding firstBound;
-					firstBound = originalVariable.firstBound == originalVariable.superclass
+					firstBound = TypeBinding.equalsEquals(originalVariable.firstBound, originalVariable.superclass)
 						? substitutedSuperclass // could be array type or interface
 						: substitutedInterfaces[0];
 					substitutedVariable.setFirstBound(firstBound);
@@ -251,7 +251,7 @@
 				ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
 				if (originalVariable.firstBound != null) {
 					TypeBinding firstBound;
-					firstBound = originalVariable.firstBound == originalVariable.superclass
+					firstBound = TypeBinding.equalsEquals(originalVariable.firstBound, originalVariable.superclass)
 						? substitutedSuperclass // could be array type or interface
 						: substitutedInterfaces[0];
 					substitutedVariable.setFirstBound(firstBound);
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 697028f..e0f5d3c 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
@@ -345,7 +345,7 @@
 		    sig.append('>');
 		}
 		sig.append(';');
-		if (captureSourceType != null && captureSourceType != this.type) {
+		if (captureSourceType != null && TypeBinding.notEquals(captureSourceType, this.type)) {
 			// contains a capture binding
 			sig.insert(0, "&"); //$NON-NLS-1$
 			sig.insert(0, captureSourceType.computeUniqueKey(false/*not a leaf*/));
@@ -539,7 +539,7 @@
 					if (method.parameters.length == argCount) {
 						TypeBinding[] toMatch = method.parameters;
 						for (int iarg = 0; iarg < argCount; iarg++)
-							if (toMatch[iarg] != argumentTypes[iarg])
+							if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
 								continue nextMethod;
 						if (match != null) return null; // collision case
 						match = method;
@@ -553,7 +553,7 @@
 				TypeBinding[] toMatch = method.parameters;
 				if (toMatch.length == argCount) {
 					for (int p = 0; p < argCount; p++)
-						if (toMatch[p] != argumentTypes[p])
+						if (TypeBinding.notEquals(toMatch[p], argumentTypes[p]))
 							continue nextMethod;
 						if (match != null) return null; // collision case
 						match = method;
@@ -581,7 +581,7 @@
 					if (method.parameters.length == argCount) {
 						TypeBinding[] toMatch = method.parameters;
 						for (int iarg = 0; iarg < argCount; iarg++)
-							if (toMatch[iarg] != argumentTypes[iarg])
+							if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
 								continue nextMethod;
 						if (match != null) return null; // collision case
 						match = method;
@@ -596,7 +596,7 @@
 				TypeBinding[] toMatch = method.parameters;
 				if (toMatch.length == argCount) {
 					for (int p = 0; p < argCount; p++)
-						if (toMatch[p] != argumentTypes[p])
+						if (TypeBinding.notEquals(toMatch[p], argumentTypes[p]))
 							continue nextMethod;
 						if (match != null) return null; // collision case
 						match = method;
@@ -864,7 +864,7 @@
 	            return true;
 
 	    	case Binding.RAW_TYPE :
-	            return erasure() == otherType.erasure();
+	            return TypeBinding.equalsEquals(erasure(), otherType.erasure());
 	    }
 	    /* With the hybrid 1.4/1.5+ projects modes, while establishing type equivalence, we need to
 	       be prepared for a type such as Map appearing in one of three forms: As (a) a ParameterizedTypeBinding 
@@ -873,7 +873,7 @@
 	       on whether the underlying type was "seen to be" a generic type in the particular build environment or
 	       not. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827 
 	     */
-	    if (erasure() == otherType) {
+	    if (TypeBinding.equalsEquals(erasure(), otherType)) {
 	    	return true;
 	    }
 	    return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
index c41e93a..5d1c4ff 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
@@ -56,7 +56,7 @@
 			return false;
 		}
 		for (int j = 0; j < cachedParametersLength; j++){
-			if (this.parameters[j] != matchingParameters[j]) {
+			if (TypeBinding.notEquals(this.parameters[j], matchingParameters[j])) {
 				return false;
 			}
 		}
@@ -67,7 +67,7 @@
 			}
 		} else if (cachedReturnType == null) {
 			return false;
-		} else if (matchingReturnType != cachedReturnType) {
+		} else if (TypeBinding.notEquals(matchingReturnType, cachedReturnType)) {
 			return false;
 		}
 		// all arguments match
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
index 55dbdb9..0fbea9b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -157,13 +157,13 @@
 	    	case Binding.GENERIC_TYPE :
 	    	case Binding.PARAMETERIZED_TYPE :
 	    	case Binding.RAW_TYPE :
-	            return erasure() == otherType.erasure();
+	            return TypeBinding.equalsEquals(erasure(), otherType.erasure());
 	    }
         return false;
 	}
 
     public boolean isProvablyDistinct(TypeBinding otherType) {
-		if (this == otherType || erasure() == otherType) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+		if (TypeBinding.equalsEquals(this, otherType) || TypeBinding.equalsEquals(erasure(), otherType)) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
 		    return false;
 	    if (otherType == null)
 	        return true;
@@ -172,7 +172,7 @@
 	    	case Binding.GENERIC_TYPE :
 	    	case Binding.PARAMETERIZED_TYPE :
 	    	case Binding.RAW_TYPE :
-	            return erasure() != otherType.erasure();
+	            return TypeBinding.notEquals(erasure(), otherType.erasure());
 	    }
         return true;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index 0834d07..3eab7b4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -492,7 +492,7 @@
 	if (isPublic()) return true;
 
 	SourceTypeBinding invocationType = scope.enclosingSourceType();
-	if (invocationType == this) return true;
+	if (TypeBinding.equalsEquals(invocationType, this)) return true;
 
 	if (invocationType == null) // static import call
 		return !isPrivate() && scope.getCurrentPackage() == this.fPackage;
@@ -511,7 +511,7 @@
 		TypeBinding currentType = invocationType.erasure();
 		// int depth = 0;
 		do {
-			if (declaringClass == invocationType) return true;
+			if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
 			if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
 			// depth++;
 			currentType = currentType.enclosingType();
@@ -534,7 +534,7 @@
 			outerDeclaringClass = temp;
 			temp = temp.enclosingType();
 		}
-		return outerInvocationType == outerDeclaringClass;
+		return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
 	}
 
 	// isDefault()
@@ -1061,7 +1061,7 @@
 	boolean inCycle = false; // check each method before failing
 	for (int i = 0, l = currentMethods.length; i < l; i++) {
 		TypeBinding returnType = currentMethods[i].returnType.leafComponentType().erasure();
-		if (this == returnType) {
+		if (TypeBinding.equalsEquals(this, returnType)) {
 			if (this instanceof SourceTypeBinding) {
 				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
 				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null);
@@ -1305,7 +1305,7 @@
  */
 public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {
 
-    if (this == otherType) return false;
+    if (TypeBinding.equalsEquals(this, otherType)) return false;
 
 	ReferenceBinding[] interfacesToVisit = null;
 	int nextPosition = 0;
@@ -1328,7 +1328,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -1337,7 +1337,7 @@
 
 	for (int i = 0; i < nextPosition; i++) {
 		currentType = interfacesToVisit[i];
-		if (currentType == otherType) return false;
+		if (TypeBinding.equalsEquals(currentType, otherType)) return false;
 		match = otherType.findSuperTypeOriginatingFrom(currentType);
 		if (match != null && match.isProvablyDistinct(currentType))
 			return true;
@@ -1350,7 +1350,7 @@
 			nextInterface : for (int a = 0; a < itsLength; a++) {
 				ReferenceBinding next = itsInterfaces[a];
 				for (int b = 0; b < nextPosition; b++)
-					if (next == interfacesToVisit[b]) continue nextInterface;
+					if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 				interfacesToVisit[nextPosition++] = next;
 			}
 		}
@@ -1401,7 +1401,7 @@
 * NOTE: Assume that anInterface is an interface.
 */
 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
-	if (this == anInterface)
+	if (TypeBinding.equalsEquals(this, anInterface))
 		return true;
 
 	ReferenceBinding[] interfacesToVisit = null;
@@ -1420,7 +1420,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -1440,7 +1440,7 @@
 			nextInterface : for (int a = 0; a < itsLength; a++) {
 				ReferenceBinding next = itsInterfaces[a];
 				for (int b = 0; b < nextPosition; b++)
-					if (next == interfacesToVisit[b]) continue nextInterface;
+					if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 				interfacesToVisit[nextPosition++] = next;
 			}
 		}
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 50b9573..d58fec3 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
@@ -158,7 +158,7 @@
 					ArrayBinding originalArrayType = (ArrayBinding) originalType;
 					TypeBinding originalLeafComponentType = originalArrayType.leafComponentType;
 					TypeBinding substitute = convertEliminatingTypeVariables(originalLeafComponentType, genericType, rank, eliminatedVariables); // substitute could itself be array type
-					if (substitute != originalLeafComponentType) {
+					if (TypeBinding.notEquals(substitute, originalLeafComponentType)) {
 						return originalArrayType.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalArrayType.dimensions());
 					}
 					break;
@@ -174,7 +174,7 @@
 					for (int i = 0, length = originalArguments == null ? 0 : originalArguments.length; i < length; i++) {
 						TypeBinding originalArgument = originalArguments[i];
 						TypeBinding substitutedArgument = convertEliminatingTypeVariables(originalArgument, paramType.genericType(), i, eliminatedVariables);
-						if (substitutedArgument != originalArgument) {
+						if (TypeBinding.notEquals(substitutedArgument, originalArgument)) {
 							if (substitutedArguments == originalArguments) {
 								System.arraycopy(originalArguments, 0, substitutedArguments = new TypeBinding[length], 0, i);
 							}
@@ -183,7 +183,7 @@
 							substitutedArguments[i] = originalArgument;
 						}
 					}
-					if (originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments) {
+					if (TypeBinding.notEquals(originalEnclosing, substitutedEnclosing) || originalArguments != substitutedArguments) {
 						return paramType.environment.createParameterizedType(paramType.genericType(), substitutedArguments, substitutedEnclosing);
 					}
 					break;
@@ -217,7 +217,7 @@
 					for (int i = 0, length = originalArguments == null ? 0 : originalArguments.length; i < length; i++) {
 						TypeBinding originalArgument = originalArguments[i];
 						TypeBinding substitutedArgument = convertEliminatingTypeVariables(originalArgument, currentType, i, eliminatedVariables);
-						if (substitutedArgument != originalArgument) {
+						if (TypeBinding.notEquals(substitutedArgument, originalArgument)) {
 							if (substitutedArguments == originalArguments) {
 								System.arraycopy(originalArguments, 0, substitutedArguments = new TypeBinding[length], 0, i);
 							}
@@ -226,7 +226,7 @@
 							substitutedArguments[i] = originalArgument;
 						}
 					}
-					if (originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments) {
+					if (TypeBinding.notEquals(originalEnclosing, substitutedEnclosing) || originalArguments != substitutedArguments) {
 						return ((TypeVariableBinding)originalArguments[0]).environment.createParameterizedType(genericType, substitutedArguments, substitutedEnclosing);
 					}
 					break;
@@ -236,7 +236,7 @@
 					TypeBinding substitutedBound = originalBound;
 					if (originalBound != null) {
 						substitutedBound = convertEliminatingTypeVariables(originalBound, genericType, rank, eliminatedVariables);
-						if (substitutedBound != originalBound) {
+						if (TypeBinding.notEquals(substitutedBound, originalBound)) {
 							return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, null, wildcard.boundKind);
 						}
 					}
@@ -253,7 +253,7 @@
 					for (int i = 0, length = originalOtherBounds == null ? 0 : originalOtherBounds.length; i < length; i++) {
 						TypeBinding originalOtherBound = originalOtherBounds[i];
 						TypeBinding substitutedOtherBound = convertEliminatingTypeVariables(originalOtherBound, genericType, rank, eliminatedVariables);
-						if (substitutedOtherBound != originalOtherBound) {
+						if (TypeBinding.notEquals(substitutedOtherBound, originalOtherBound)) {
 							if (substitutedOtherBounds == originalOtherBounds) {
 								System.arraycopy(originalOtherBounds, 0, substitutedOtherBounds = new TypeBinding[length], 0, i);
 							}
@@ -262,7 +262,7 @@
 							substitutedOtherBounds[i] = originalOtherBound;
 						}
 					}
-					if (substitutedBound != originalBound || substitutedOtherBounds != originalOtherBounds) {
+					if (TypeBinding.notEquals(substitutedBound, originalBound) || substitutedOtherBounds != originalOtherBounds) {
 						return intersection.environment.createWildcard(intersection.genericType, intersection.rank, substitutedBound, substitutedOtherBounds, intersection.boundKind);
 					}
 					break;
@@ -925,7 +925,7 @@
 							}
 						}
 						// check against superclass
-						if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) {
+						if (checkForErasedCandidateCollisions && TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) {
 							if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) {
 								continue nextBound;
 							}
@@ -934,7 +934,7 @@
 						ReferenceBinding superRefType = (ReferenceBinding) superType;
 						for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
 							ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
-							if (previousInterface == superRefType) {
+							if (TypeBinding.equalsEquals(previousInterface, superRefType)) {
 								problemReporter().duplicateBounds(typeRef, superType);
 								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
 								continue nextBound;
@@ -1350,7 +1350,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -1404,7 +1404,7 @@
 						nextInterface : for (int a = 0; a < itsLength; a++) {
 							ReferenceBinding next = itsInterfaces[a];
 							for (int b = 0; b < nextPosition; b++)
-								if (next == interfacesToVisit[b]) continue nextInterface;
+								if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 							interfacesToVisit[nextPosition++] = next;
 						}
 					}
@@ -1479,7 +1479,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -1526,7 +1526,7 @@
 						nextInterface : for (int a = 0; a < itsLength; a++) {
 							ReferenceBinding next = itsInterfaces[a];
 							for (int b = 0; b < nextPosition; b++)
-								if (next == interfacesToVisit[b]) continue nextInterface;
+								if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 							interfacesToVisit[nextPosition++] = next;
 						}
 					}
@@ -1726,7 +1726,7 @@
 				next: for (int a = 0; a < argLength; a++) {
 					TypeBinding arg = argumentTypes[a];
 					for (int p = a == 0 ? 0 : a - 1; p < paramLength && p < a + 1; p++) { // look one slot before & after to see if the type matches
-						if (params[p] == arg) {
+						if (TypeBinding.equalsEquals(params[p], arg)) {
 							argMatches++;
 							continue next;
 						}
@@ -1808,7 +1808,7 @@
 						MethodBinding otherCandidate = candidates[j];
 						if (otherCandidate.hasSubstitutedParameters()) {
 							if (otherCandidate == candidate
-									|| (candidate.declaringClass == otherCandidate.declaringClass && candidate.areParametersEqual(otherCandidate))) {
+									|| (TypeBinding.equalsEquals(candidate.declaringClass, otherCandidate.declaringClass) && candidate.areParametersEqual(otherCandidate))) {
 								return new ProblemMethodBinding(candidates[i], candidates[i].selector, candidates[i].parameters, ProblemReasons.Ambiguous);
 							}
 						}
@@ -1921,7 +1921,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -2075,7 +2075,7 @@
 														ProblemReasons.NonStaticReferenceInStaticContext);
 											}
 										}
-										if (receiverType == fieldBinding.declaringClass || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+										if (TypeBinding.equalsEquals(receiverType, fieldBinding.declaringClass) || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
 											// found a valid field in the 'immediate' scope (i.e. not inherited)
 											// OR in 1.4 mode (inherited shadows enclosing)
 											if (foundField == null) {
@@ -2089,8 +2089,8 @@
 											if (foundField.isValidBinding())
 												// if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
 												// but only if "valid field" was inherited in the first place.
-												if (foundField.declaringClass != fieldBinding.declaringClass &&
-												    foundField.declaringClass != foundActualReceiverType) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316956
+												if (TypeBinding.notEquals(foundField.declaringClass, fieldBinding.declaringClass) &&
+												    TypeBinding.notEquals(foundField.declaringClass, foundActualReceiverType)) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316956
 													// i.e. have we found the same field - do not trust field identity yet
 													return new ProblemFieldBinding(
 														foundField, // closest match
@@ -2475,7 +2475,7 @@
 										tagAsAccessingEnclosingInstanceStateOf(receiverType, false /* type variable access */);
 									}
 									if (inheritedHasPrecedence
-											|| receiverType == methodBinding.declaringClass
+											|| TypeBinding.equalsEquals(receiverType, methodBinding.declaringClass)
 											|| (receiverType.getMethods(selector)) != Binding.NO_METHODS) {
 										// found a valid method in the 'immediate' scope (i.e. not inherited)
 										// OR in 1.4 mode (inherited visible shadows enclosing)
@@ -2523,8 +2523,8 @@
 								}
 							} else { // found a valid method so check to see if this is a hiding case
 								if (methodBinding.problemId() == ProblemReasons.Ambiguous
-									|| (foundMethod.declaringClass != methodBinding.declaringClass
-										&& (receiverType == methodBinding.declaringClass || receiverType.getMethods(selector) != Binding.NO_METHODS)))
+									|| (TypeBinding.notEquals(foundMethod.declaringClass, methodBinding.declaringClass)
+										&& (TypeBinding.equalsEquals(receiverType, methodBinding.declaringClass) || receiverType.getMethods(selector) != Binding.NO_METHODS)))
 									// ambiguous case -> must qualify the method (javac generates an ambiguous error instead)
 									// otherwise if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
 									// NOTE: Unlike fields, a non visible method hides a visible method
@@ -3136,7 +3136,7 @@
 					case BLOCK_SCOPE :
 						ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only
 						if (localType != null) {
-							if (foundType != null && foundType != localType)
+							if (foundType != null && TypeBinding.notEquals(foundType, localType))
 								return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
 							return localType;
 						}
@@ -3181,7 +3181,7 @@
 									return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
 								}
 								if (memberType.isValidBinding()) {
-									if (sourceType == memberType.enclosingType() || inheritedHasPrecedence) {
+									if (TypeBinding.equalsEquals(sourceType, memberType.enclosingType()) || inheritedHasPrecedence) {
 										if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType())
 											return new ProblemReferenceBinding(new char[][]{name}, memberType, ProblemReasons.NonStaticReferenceInStaticContext);
 										// found a valid type in the 'immediate' scope (i.e. not inherited)
@@ -3189,7 +3189,7 @@
 										if (foundType == null || (inheritedHasPrecedence && foundType.problemId() == ProblemReasons.NotVisible))
 											return memberType;
 										// if a valid type was found, complain when another is found in an 'immediate' enclosing type (i.e. not inherited)
-										if (foundType.isValidBinding() && foundType != memberType)
+										if (foundType.isValidBinding() && TypeBinding.notEquals(foundType, memberType))
 											return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
 									}
 								}
@@ -3207,7 +3207,7 @@
 						insideStaticContext |= sourceType.isStatic();
 						insideTypeAnnotation = false;
 						if (CharOperation.equals(sourceType.sourceName, name)) {
-							if (foundType != null && foundType != sourceType && foundType.problemId() != ProblemReasons.NotVisible)
+							if (foundType != null && TypeBinding.notEquals(foundType, sourceType) && foundType.problemId() != ProblemReasons.NotVisible)
 								return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
 							return sourceType;
 						}
@@ -3304,7 +3304,7 @@
 						} else {
 							temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport);
 						}
-						if (temp != type && temp != null) {
+						if (TypeBinding.notEquals(temp, type) && temp != null) {
 							if (temp.isValidBinding()) {
 								ImportReference importReference = someImport.reference;
 								if (importReference != null) {
@@ -3503,7 +3503,7 @@
 			next : for (int i = 0; i < oneParamsLength; i++) {
 				TypeBinding oneParam = applyErasure ? oneParams[i].erasure() : oneParams[i];
 				TypeBinding twoParam = applyErasure ? twoParams[i].erasure() : twoParams[i];
-				if (oneParam == twoParam || oneParam.isCompatibleWith(twoParam)) {
+				if (TypeBinding.equalsEquals(oneParam, twoParam) || oneParam.isCompatibleWith(twoParam)) {
 					if (two.declaringClass.isRawType()) continue next;
 
 					TypeBinding leafComponentType = two.original().parameters[i].leafComponentType();
@@ -3536,10 +3536,10 @@
 						TypeBinding oType = ((ArrayBinding) oneParam).elementsType();
 						TypeBinding eType = ((ArrayBinding) twoParam).elementsType();
 						if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && this.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
-							if (oneParam == eType || oneParam.isCompatibleWith(eType))
+							if (TypeBinding.equalsEquals(oneParam, eType) || oneParam.isCompatibleWith(eType))
 								return true; // special case to choose between 2 varargs methods when the last arg is Object[]
 						} else {
-							if (oType == eType || oType.isCompatibleWith(eType))
+							if (TypeBinding.equalsEquals(oType, eType) || oType.isCompatibleWith(eType))
 								return true; // special case to choose between 2 varargs methods when the last arg is Object[]
 						}
 					}
@@ -3558,7 +3558,7 @@
 			}
 			// check that each parameter before the vararg parameters are compatible (no autoboxing allowed here)
 			for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--)
-				if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i]))
+				if (TypeBinding.notEquals(oneParams[i], twoParams[i]) && !oneParams[i].isCompatibleWith(twoParams[i]))
 					return false;
 			if (parameterCompatibilityLevel(one, twoParams, true) == NOT_COMPATIBLE
 					&& parameterCompatibilityLevel(two, oneParams, true) == VARARGS_COMPATIBLE)
@@ -3574,7 +3574,7 @@
 
 		// check if autoboxed type is compatible
 		TypeBinding convertedType = environment.computeBoxingType(expressionType);
-		return convertedType == targetType || convertedType.isCompatibleWith(targetType);
+		return TypeBinding.equalsEquals(convertedType, targetType) || convertedType.isCompatibleWith(targetType);
 	}
 
 	/* Answer true if the scope is nested inside a given field declaration.
@@ -3626,7 +3626,7 @@
 		// test that the enclosingType is not part of the compilation unit
 		SourceTypeBinding[] topLevelTypes = ((CompilationUnitScope) unitScope).topLevelTypes;
 		for (int i = topLevelTypes.length; --i >= 0;)
-			if (topLevelTypes[i] == enclosingType.original())
+			if (TypeBinding.equalsEquals(topLevelTypes[i], enclosingType.original()))
 				return true;
 		return false;
 	}
@@ -3637,7 +3637,7 @@
 		Scope scope = this;
 		do {
 			if (scope instanceof ClassScope)
-				if (((ClassScope) scope).referenceContext.binding == type)
+				if (TypeBinding.equalsEquals(((ClassScope) scope).referenceContext.binding, type))
 					return true;
 			scope = scope.parent;
 		} while (scope != null);
@@ -3747,7 +3747,7 @@
 					nextInterface : for (int a = 0; a < itsLength; a++) {
 						ReferenceBinding next = itsInterfaces[a];
 						for (int b = 0; b < nextPosition; b++)
-							if (next == interfacesToVisit[b]) continue nextInterface;
+							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 						interfacesToVisit[nextPosition++] = next;
 					}
 				}
@@ -3766,7 +3766,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -3820,7 +3820,7 @@
 	// JLS 15.12.2
 	private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank, ArrayList lubStack) {
 		if (u == null) return v;
-		if (u == v) return u;
+		if (TypeBinding.equalsEquals(u, v)) return u;
 		if (v.isWildcard()) {
 			WildcardBinding wildV = (WildcardBinding) v;
 			if (u.isWildcard()) {
@@ -3834,11 +3834,11 @@
 								TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound,wildV.bound}, lubStack);
 								if (lub == null) return null;
 								// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
-								if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+								if (TypeBinding.equalsEquals(lub, TypeBinding.INT)) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 								return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
 							// ? extends U, ? SUPER V
 							case Wildcard.SUPER :
-								if (wildU.bound == wildV.bound) return wildU.bound;
+								if (TypeBinding.equalsEquals(wildU.bound, wildV.bound)) return wildU.bound;
 								return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 						}
 						break;
@@ -3858,7 +3858,7 @@
 						TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,wildV.bound}, lubStack);
 						if (lub == null) return null;
 						// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
-						if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+						if (TypeBinding.equalsEquals(lub, TypeBinding.INT)) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 						return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
 					// U, ? super V
 					case Wildcard.SUPER :
@@ -3876,7 +3876,7 @@
 					TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound, v}, lubStack);
 					if (lub == null) return null;
 					// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
-					if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+					if (TypeBinding.equalsEquals(lub, TypeBinding.INT)) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 					return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
 				// U, ? super V
 				case Wildcard.SUPER :
@@ -3889,7 +3889,7 @@
 		TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,v}, lubStack);
 		if (lub == null) return null;
 		// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
-		if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+		if (TypeBinding.equalsEquals(lub, TypeBinding.INT)) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 		return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
 	}
 
@@ -3927,7 +3927,7 @@
 				for (int k = 0; k < lubTypeLength; k++) {
 					TypeBinding lubType = lubTypes[k];
 					if (lubType == null) continue; // ignore
-					if (lubType == type || lubType.isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one
+					if (TypeBinding.equalsEquals(lubType, type) || lubType.isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one
 				}
 				continue nextLubCheck; // type not found in current lubTypes
 			}
@@ -4153,7 +4153,7 @@
 			if (otherType.isArrayType()) {
 				nextSuperType: for (int j = 0; j < superLength; j++) {
 					TypeBinding erasedSuperType = erasedSuperTypes[j];
-					if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType;
+					if (erasedSuperType == null || TypeBinding.equalsEquals(erasedSuperType, otherType)) continue nextSuperType;
 					TypeBinding match;
 					if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) {
 						erasedSuperTypes[j] = null;
@@ -4175,7 +4175,7 @@
 						checkExisting: {
 							int invocLength = someInvocations.length;
 							for (int k = 0; k < invocLength; k++) {
-								if (someInvocations[k] == match) break checkExisting;
+								if (TypeBinding.equalsEquals(someInvocations[k], match)) break checkExisting;
 							}
 							System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength+1], 0, invocLength);
 							allInvocations.put(erasedSuperType, someInvocations);
@@ -4189,7 +4189,7 @@
 				TypeBinding erasedSuperType = erasedSuperTypes[j];
 				if (erasedSuperType == null) continue nextSuperType;
 				TypeBinding match;
-				if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) {
+				if (TypeBinding.equalsEquals(erasedSuperType, otherType) || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) {
 					match = erasedSuperType;
 				} else {
 					if (erasedSuperType.isArrayType()) {
@@ -4218,7 +4218,7 @@
 					checkExisting: {
 						int invocLength = someInvocations.length;
 						for (int k = 0; k < invocLength; k++) {
-							if (someInvocations[k] == match) break checkExisting;
+							if (TypeBinding.equalsEquals(someInvocations[k], match)) break checkExisting;
 						}
 						System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength+1], 0, invocLength);
 						allInvocations.put(erasedSuperType, someInvocations);
@@ -4272,7 +4272,7 @@
 		MethodBinding previous = null;
 		nextVisible : for (int i = 0; i < visibleSize; i++) {
 			MethodBinding method = visible[i];
-			if (previous != null && method.declaringClass != previous.declaringClass)
+			if (previous != null && TypeBinding.notEquals(method.declaringClass, previous.declaringClass))
 				break; // cannot answer a method farther up the hierarchy than the first method found
 
 			if (!method.isStatic()) previous = method; // no ambiguity for static methods
@@ -4441,7 +4441,7 @@
 					MethodBinding next = moreSpecific[j];
 					if (next == null || i == j) continue;
 					MethodBinding original2 = next.original();
-					if (original.declaringClass == original2.declaringClass)
+					if (TypeBinding.equalsEquals(original.declaringClass, original2.declaringClass))
 						break nextSpecific; // duplicates thru substitution
 
 					if (!original.isAbstract()) {
@@ -4457,7 +4457,7 @@
 						}
 					} else if (receiverType != null) { // should not be null if original isAbstract, but be safe
 						TypeBinding superType = receiverType.findSuperTypeOriginatingFrom(original.declaringClass.erasure());
-						if (original.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
+						if (TypeBinding.equalsEquals(original.declaringClass, superType) || !(superType instanceof ReferenceBinding)) {
 							// keep original
 						} else {
 							// must find inherited method with the same substituted variables
@@ -4470,7 +4470,7 @@
 							}
 						}
 						superType = receiverType.findSuperTypeOriginatingFrom(original2.declaringClass.erasure());
-						if (original2.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
+						if (TypeBinding.equalsEquals(original2.declaringClass, superType) || !(superType instanceof ReferenceBinding)) {
 							// keep original2
 						} else {
 							// must find inherited method with the same substituted variables
@@ -4486,7 +4486,7 @@
 							original2 = original.computeSubstitutedMethod(original2, environment());
 						if (original2 == null || !original.areParameterErasuresEqual(original2))
 							continue nextSpecific; // current does not override next
-						if (original.returnType != original2.returnType) {
+						if (TypeBinding.notEquals(original.returnType, original2.returnType)) {
 							if (next.original().typeVariables != Binding.NO_TYPE_VARIABLES) {
 								if (original.returnType.erasure().findSuperTypeOriginatingFrom(original2.returnType.erasure()) == null)
 									continue nextSpecific;
@@ -4558,7 +4558,7 @@
 			ReferenceBinding currentException = allExceptions[i];
 			for (int j = 0; j < length; j++) {
 				if (i == j) continue;
-				if (currentException == allExceptions[j]) {
+				if (TypeBinding.equalsEquals(currentException, allExceptions[j])) {
 					// duplicate same exception
 					if (i < j) 
 						break; // take only the first occurrence
@@ -4621,7 +4621,7 @@
 				TypeBinding param = parameters[i];
 				TypeBinding arg = arguments[i];
 				//https://bugs.eclipse.org/bugs/show_bug.cgi?id=330445
-				if (arg != param && !arg.isCompatibleWith(param.erasure(), this))
+				if (TypeBinding.notEquals(arg, param) && !arg.isCompatibleWith(param.erasure(), this))
 					return NOT_COMPATIBLE;
 			}
 //{ObjectTeams: store successful parameters:
@@ -4642,7 +4642,7 @@
 			if (paramLength == argLength) { // accept X or X[] but not X[][]
 				TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
 				TypeBinding arg = arguments[lastIndex];
-				if (param != arg) {
+				if (TypeBinding.notEquals(param, arg)) {
 					level = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods);
 					if (level == NOT_COMPATIBLE) {
 						// expect X[], is it called with X
@@ -4660,7 +4660,7 @@
 					TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
 					for (int i = lastIndex; i < argLength; i++) {
 						TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i];
-						if (param != arg && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
+						if (TypeBinding.notEquals(param, arg) && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
 							return NOT_COMPATIBLE;
 					}
 				}  else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
@@ -4695,7 +4695,7 @@
 		
 		if (arg.isBaseType() != param.isBaseType()) {
 			TypeBinding convertedType = environment().computeBoxingType(arg);
-			if (convertedType == param || convertedType.isCompatibleWith(param))
+			if (TypeBinding.equalsEquals(convertedType, param) || convertedType.isCompatibleWith(param))
 				return AUTOBOX_COMPATIBLE;
 		}
 		return NOT_COMPATIBLE;
@@ -4716,7 +4716,7 @@
 		}
 		if (arg.isBaseType() != param.isBaseType()) {
 			TypeBinding convertedType = env.computeBoxingType(arg);
-			if (convertedType == param || convertedType.isCompatibleWith(param))
+			if (TypeBinding.equalsEquals(convertedType, param) || convertedType.isCompatibleWith(param))
 				return AUTOBOX_COMPATIBLE;
 		}
 		return NOT_COMPATIBLE;
@@ -4926,7 +4926,7 @@
 					ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
 					if (originalVariable.firstBound != null) {
 						TypeBinding firstBound;
-						firstBound = originalVariable.firstBound == originalVariable.superclass
+						firstBound = TypeBinding.equalsEquals(originalVariable.firstBound, originalVariable.superclass)
 								? substitutedSuperclass // could be array type or interface
 										: substitutedInterfaces[0];
 						substitutedVariable.setFirstBound(firstBound);
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 08f0cd9..a2d89ec 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
@@ -283,7 +283,7 @@
 						nextInterface : for (int a = 0; a < itsLength; a++) {
 							ReferenceBinding next = itsInterfaces[a];
 							for (int b = 0; b < nextPosition; b++)
-								if (next == interfacesToVisit[b]) continue nextInterface;
+								if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 							interfacesToVisit[nextPosition++] = next;
 						}
 					}
@@ -992,7 +992,7 @@
 			if (synthetic instanceof MethodBinding) {
 				MethodBinding method = (MethodBinding) synthetic;
 				if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector)
-					&& inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure()
+					&& TypeBinding.equalsEquals(inheritedMethodToBridge.returnType.erasure(), method.returnType.erasure())
 					&& inheritedMethodToBridge.areParameterErasuresEqual(method)) {
 						return null;
 				}
@@ -1039,7 +1039,7 @@
 			if (synthetic instanceof MethodBinding) {
 				MethodBinding method = (MethodBinding) synthetic;
 				if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector)
-					&& inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure()
+					&& TypeBinding.equalsEquals(inheritedMethodToBridge.returnType.erasure(), method.returnType.erasure())
 					&& inheritedMethodToBridge.areParameterErasuresEqual(method)) {
 						return null;
 				}
@@ -1341,7 +1341,7 @@
 					for (int iarg = 0; iarg < argCount; iarg++)
 //{ObjectTeams: weaker form of equality:
 	/* orig:
-						if (toMatch[iarg] != argumentTypes[iarg])
+						if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
 	  :giro*/
 						if (!AnchorMapping.areTypesEqual(toMatch[iarg], argumentTypes[iarg], method))
 // SH}
@@ -1369,7 +1369,7 @@
 				if (method.parameters.length == argCount) {
 					TypeBinding[] toMatch = method.parameters;
 					for (int iarg = 0; iarg < argCount; iarg++)
-						if (toMatch[iarg] != argumentTypes[iarg])
+						if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
 							continue nextMethod;
 					return method;
 				}
@@ -1400,7 +1400,7 @@
 					for (int iarg = 0; iarg < argCount; iarg++)
 //{ObjectTeams: weaker form of equality:
 /* orig:
-						if (toMatch[iarg] != argumentTypes[iarg])
+						if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
   :giro*/
 						if (!AnchorMapping.areTypesEqual(toMatch[iarg], argumentTypes[iarg], method))
 // SH}
@@ -1451,7 +1451,7 @@
 					for (int iarg = 0; iarg < argCount; iarg++)
 //{ObjectTeams: weaker form of equality:
 /* orig:
-						if (toMatch[iarg] != argumentTypes[iarg])
+						if (TypeBinding.notEquals(toMatch[iarg], argumentTypes[iarg]))
   :giro*/
 						if (!AnchorMapping.areTypesEqual(toMatch[iarg], argumentTypes[iarg], method))
 // SH}
@@ -1894,7 +1894,7 @@
 			if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0 && (!isMemberType() || !otherType.isMemberType()))
 				return false; // should have been identical
 			ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
-			if (this != otherParamType.genericType())
+			if (TypeBinding.notEquals(this, otherParamType.genericType()))
 				return false;
 			if (!isStatic()) { // static member types do not compare their enclosing
             	ReferenceBinding enclosing = enclosingType();
@@ -1902,7 +1902,7 @@
             		ReferenceBinding otherEnclosing = otherParamType.enclosingType();
             		if (otherEnclosing == null) return false;
             		if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
-						if (enclosing != otherEnclosing) return false;
+						if (TypeBinding.notEquals(enclosing, otherEnclosing)) return false;
             		} else {
             			if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
             		}
@@ -1919,7 +1919,7 @@
 			return true;
 
 		case Binding.RAW_TYPE :
-	        return otherType.erasure() == this;
+	        return TypeBinding.equalsEquals(otherType.erasure(), this);
 	}
 	return false;
 }
@@ -2052,7 +2052,7 @@
 						// Only in 1.6, we have to make sure even return types are different
 						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719
 						if (compliance16 && method.returnType != null && method2.returnType != null) {
-							if (method.returnType.erasure() != method2.returnType.erasure()) {
+							if (TypeBinding.notEquals(method.returnType.erasure(), method2.returnType.erasure())) {
 								// check to see if the erasure of either method is equal to the other
 								// if not, then change severity to WARNING
 								TypeBinding[] params1 = method.parameters;
@@ -2079,17 +2079,17 @@
 									int index = pLength;
 									// is erasure of signature of m2 same as signature of m1?
 									for (; --index >= 0;) {
-										if (params1[index] != params2[index].erasure()) {
+										if (TypeBinding.notEquals(params1[index], params2[index].erasure())) {
 											// If one of them is a raw type
 											if (params1[index] instanceof RawTypeBinding) {
-												if (params2[index].erasure() != ((RawTypeBinding)params1[index]).actualType()) {
+												if (TypeBinding.notEquals(params2[index].erasure(), ((RawTypeBinding)params1[index]).actualType())) {
 													break;
 												}
 											} else  {
 												break;
 											}
 										}
-										if (params1[index] == params2[index]) {
+										if (TypeBinding.equalsEquals(params1[index], params2[index])) {
 											TypeBinding type = params1[index].leafComponentType();
 											if (type instanceof SourceTypeBinding && type.typeVariables() != Binding.NO_TYPE_VARIABLES) {
 												index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
@@ -2100,10 +2100,10 @@
 									if (index >= 0 && index < pLength) {
 										// is erasure of signature of m1 same as signature of m2?
 										for (index = pLength; --index >= 0;)
-											if (params1[index].erasure() != params2[index]) {
+											if (TypeBinding.notEquals(params1[index].erasure(), params2[index])) {
 												// If one of them is a raw type
 												if (params2[index] instanceof RawTypeBinding) {
-													if (params1[index].erasure() != ((RawTypeBinding)params2[index]).actualType()) {
+													if (TypeBinding.notEquals(params1[index].erasure(), ((RawTypeBinding)params2[index]).actualType())) {
 														break;
 													}
 												} else  {
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 95ff2b5..029d5b6 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
@@ -189,7 +189,7 @@
 						if (method.parameters.length == paramCount) {
 							TypeBinding[] toMatch = method.parameters;
 							for (int i = 0; i < paramCount; i++) {
-								if (toMatch[i] != this.parameters[i]) {
+								if (TypeBinding.notEquals(toMatch[i], this.parameters[i])) {
 									continue nextMethod;
 								}
 							}
@@ -294,7 +294,7 @@
 						if (method.parameters.length == paramCount) {
 							TypeBinding[] toMatch = method.parameters;
 							for (int i = 0; i < paramCount; i++) {
-								if (toMatch[i] != this.parameters[i]) {
+								if (TypeBinding.notEquals(toMatch[i], this.parameters[i])) {
 									continue nextMethod;
 								}
 							}
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 248db97..74ae588 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
@@ -300,7 +300,7 @@
 				nextInterface : for (int a = 0; a < itsLength; a++) {
 					ReferenceBinding next = itsInterfaces[a];
 					for (int b = 0; b < nextPosition; b++)
-						if (next == interfacesToVisit[b]) continue nextInterface;
+						if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 					interfacesToVisit[nextPosition++] = next;
 				}
 			}
@@ -321,7 +321,7 @@
 			nextInterface : for (int a = 0; a < itsLength; a++) {
 				ReferenceBinding next = itsInterfaces[a];
 				for (int b = 0; b < nextPosition; b++)
-					if (next == interfacesToVisit[b]) continue nextInterface;
+					if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
 				interfacesToVisit[nextPosition++] = next;
 			}
 		}
@@ -437,7 +437,7 @@
  * Returns the type to use for generic cast, or null if none required
  */
 public TypeBinding genericCast(TypeBinding targetType) {
-	if (this == targetType) 
+	if (TypeBinding.equalsEquals(this, targetType)) 
 		return null;
 	TypeBinding targetErasure = targetType.erasure();
 	// type var get replaced by upper bound
@@ -707,7 +707,7 @@
 		return false;
 	TypeVariableBinding[] variables = erasure().typeVariables();
 	for (int i = 0, length = variables.length; i < length; i++) {
-		if (variables[i] != paramType.arguments[i])
+		if (TypeBinding.notEquals(variables[i], paramType.arguments[i]))
 			return false;
 	}
 	ReferenceBinding enclosing = paramType.enclosingType();
@@ -880,7 +880,7 @@
  * List<? extends String> & List<? extends Runnable> --> false
  */
 private boolean isProvablyDistinctTypeArgument(TypeBinding otherArgument, final ParameterizedTypeBinding paramType, final int rank) {
-	if (this == otherArgument)
+	if (TypeBinding.equalsEquals(this, otherArgument))
 		return false;
 
 	TypeBinding upperBound1 = null;
@@ -1176,19 +1176,19 @@
 						return false;
 					TypeBinding match = upperBound.findSuperTypeOriginatingFrom(otherBound);
 					if (match != null && (match = match.leafComponentType()).isRawType()) {
-						return match == otherBound.leafComponentType(); // forbide: Collection <=  ? extends Collection<?>
+						return TypeBinding.equalsEquals(match, otherBound.leafComponentType()); // forbide: Collection <=  ? extends Collection<?>
 																												// forbide: Collection[] <=  ? extends Collection<?>[]
 					}
 					return upperBound.isCompatibleWith(otherBound);
 
 				case Wildcard.SUPER:
-					if (otherBound == this)
+					if (TypeBinding.equalsEquals(otherBound, this))
 						return true; // ? super T  <=  ? super ? super T
 					if (lowerBound == null)
 						return false;
 					match = otherBound.findSuperTypeOriginatingFrom(lowerBound);
 					if (match != null && (match = match.leafComponentType()).isRawType()) {
-						return match == lowerBound.leafComponentType(); // forbide: Collection <=  ? super Collection<?>
+						return TypeBinding.equalsEquals(match, lowerBound.leafComponentType()); // forbide: Collection <=  ? super Collection<?>
 																												// forbide: Collection[] <=  ? super Collection<?>[]
 					}
 					return otherBound.isCompatibleWith(lowerBound);
@@ -1203,7 +1203,7 @@
 				return false;
 			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
 			ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
-			if (paramType.actualType() != otherParamType.actualType())
+			if (TypeBinding.notEquals(paramType.actualType(), otherParamType.actualType()))
 				return false;
 			if (!paramType.isStatic()) { // static member types do not compare their enclosing
 				ReferenceBinding enclosing = enclosingType();
@@ -1212,7 +1212,7 @@
 					if (otherEnclosing == null)
 						return false;
 					if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
-						if (enclosing != otherEnclosing)
+						if (TypeBinding.notEquals(enclosing, otherEnclosing))
 							return false;
 					} else {
 						if (!enclosing.isEquivalentTo(otherParamType.enclosingType()))
@@ -1228,7 +1228,7 @@
 			nextArgument: for (int i = 0; i < length; i++) {
 				TypeBinding argument = paramType.arguments[i];
 				TypeBinding otherArgument = otherArguments[i];
-				if (argument == otherArgument)
+				if (TypeBinding.equalsEquals(argument, otherArgument))
 					continue nextArgument;
 				int kind = argument.kind();
 				if (otherArgument.kind() != kind)
@@ -1246,7 +1246,7 @@
 						case Wildcard.EXTENDS:
 							// match "? extends <upperBound>" with "?"
 							if (otherWildcard.boundKind == Wildcard.UNBOUND
-									&& wildcard.bound == wildcard.typeVariable().upperBound())
+									&& TypeBinding.equalsEquals(wildcard.bound, wildcard.typeVariable().upperBound()))
 								continue nextArgument;
 							break;
 						case Wildcard.SUPER:
@@ -1254,7 +1254,7 @@
 						case Wildcard.UNBOUND:
 							// match "?" with "? extends <upperBound>"
 							if (otherWildcard.boundKind == Wildcard.EXTENDS
-									&& otherWildcard.bound == otherWildcard.typeVariable().upperBound())
+									&& TypeBinding.equalsEquals(otherWildcard.bound, otherWildcard.typeVariable().upperBound()))
 								continue nextArgument;
 							break;
 						}
@@ -1322,7 +1322,7 @@
  */
 public boolean needsUncheckedConversion(TypeBinding targetType) {
 
-	if (this == targetType)
+	if (TypeBinding.equalsEquals(this, targetType))
 		return false;
 	targetType = targetType.leafComponentType();
 	if (!(targetType instanceof ReferenceBinding))
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 19d334e..a9910b6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -271,7 +271,7 @@
 	public int boundsCount() {
 		if (this.firstBound == null) {
 			return 0;
-		} else if (this.firstBound == this.superclass) {
+		} else if (TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 			return this.superInterfaces.length + 1;
 		} else {
 			return this.superInterfaces.length;
@@ -421,15 +421,15 @@
 	public String annotatedDebugName() {
 		StringBuffer buffer = new StringBuffer(10);
 		buffer.append(super.annotatedDebugName());
-		if (this.superclass != null && this.firstBound == this.superclass) {
+		if (this.superclass != null && TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 		    buffer.append(" extends ").append(this.superclass.annotatedDebugName()); //$NON-NLS-1$
 		}
 		if (this.superInterfaces != null && this.superInterfaces != Binding.NO_SUPERINTERFACES) {
-		   if (this.firstBound != this.superclass) {
+		   if (TypeBinding.notEquals(this.firstBound, this.superclass)) {
 		        buffer.append(" extends "); //$NON-NLS-1$
 	        }
 		    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-		        if (i > 0 || this.firstBound == this.superclass) {
+		        if (i > 0 || TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 		            buffer.append(" & "); //$NON-NLS-1$
 		        }
 				buffer.append(this.superInterfaces[i].annotatedDebugName());
@@ -459,7 +459,7 @@
 	    StringBuffer sig = new StringBuffer(10);
 	    sig.append(this.sourceName).append(':');
 	   	int interfaceLength = this.superInterfaces == null ? 0 : this.superInterfaces.length;
-	    if (interfaceLength == 0 || this.firstBound == this.superclass) {
+	    if (interfaceLength == 0 || TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 	    	if (this.superclass != null)
 		        sig.append(this.superclass.genericTypeSignature());
 	    }
@@ -481,7 +481,7 @@
 	}
 
 	boolean hasOnlyRawBounds() {
-		if (this.superclass != null && this.firstBound == this.superclass)
+		if (this.superclass != null && TypeBinding.equalsEquals(this.firstBound, this.superclass))
 			if (!this.superclass.isRawType())
 				return false;
 
@@ -511,10 +511,10 @@
 	 * Returns true if the type variable is directly bound to a given type
 	 */
 	public boolean isErasureBoundTo(TypeBinding type) {
-		if (this.superclass.erasure() == type)
+		if (TypeBinding.equalsEquals(this.superclass.erasure(), type))
 			return true;
 		for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-			if (this.superInterfaces[i].erasure() == type)
+			if (TypeBinding.equalsEquals(this.superInterfaces[i].erasure(), type))
 				return true;
 		}
 		return false;
@@ -530,19 +530,19 @@
 	 * List<T1>> is interchangeable with <T2 extends List<T2>>.
 	 */
 	public boolean isInterchangeableWith(TypeVariableBinding otherVariable, Substitution substitute) {
-		if (this == otherVariable)
+		if (TypeBinding.equalsEquals(this, otherVariable))
 			return true;
 		int length = this.superInterfaces.length;
 		if (length != otherVariable.superInterfaces.length)
 			return false;
 
-		if (this.superclass != Scope.substitute(substitute, otherVariable.superclass))
+		if (TypeBinding.notEquals(this.superclass, Scope.substitute(substitute, otherVariable.superclass)))
 			return false;
 
 		next : for (int i = 0; i < length; i++) {
 			TypeBinding superType = Scope.substitute(substitute, otherVariable.superInterfaces[i]);
 			for (int j = 0; j < length; j++)
-				if (superType == this.superInterfaces[j])
+				if (TypeBinding.equalsEquals(superType, this.superInterfaces[j]))
 					continue next;
 			return false; // not a match
 		}
@@ -584,7 +584,7 @@
 	public TypeBinding[] otherUpperBounds() {
 		if (this.firstBound == null)
 			return Binding.NO_TYPES;
-		if (this.firstBound == this.superclass)
+		if (TypeBinding.equalsEquals(this.firstBound, this.superclass))
 			return this.superInterfaces;
 		int otherLength = this.superInterfaces.length - 1;
 		if (otherLength > 0) {
@@ -658,9 +658,9 @@
 		}
 		// refresh the firstBound in case it changed
 		if (this.firstBound != null) {
-			if (this.firstBound == oldSuperclass) {
+			if (TypeBinding.equalsEquals(this.firstBound, oldSuperclass)) {
 				this.setFirstBound(this.superclass);
-			} else if (this.firstBound == oldFirstInterface) {
+			} else if (TypeBinding.equalsEquals(this.firstBound, oldFirstInterface)) {
 				this.setFirstBound(interfaces[0]);
 			}
 		}
@@ -712,15 +712,15 @@
 			buffer.append(" base ").append(this.roletype.debugName()); //$NON-NLS-1$
 		} else
 // SH}
-		if (this.superclass != null && this.firstBound == this.superclass) {
+		if (this.superclass != null && TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 		    buffer.append(" extends ").append(this.superclass.debugName()); //$NON-NLS-1$
 		}
 		if (this.superInterfaces != null && this.superInterfaces != Binding.NO_SUPERINTERFACES) {
-		   if (this.firstBound != this.superclass) {
+		   if (TypeBinding.notEquals(this.firstBound, this.superclass)) {
 		        buffer.append(" extends "); //$NON-NLS-1$
 	        }
 		    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-		        if (i > 0 || this.firstBound == this.superclass) {
+		        if (i > 0 || TypeBinding.equalsEquals(this.firstBound, this.superclass)) {
 		            buffer.append(" & "); //$NON-NLS-1$
 		        }
 				buffer.append(this.superInterfaces[i].debugName());
@@ -784,12 +784,12 @@
 			this.tagBits |= nullTagBits | TagBits.HasNullTypeAnnotation;
 	}
 	private TypeReference findBound(TypeBinding bound, TypeParameter parameter) {
-		if (parameter.type != null && parameter.type.resolvedType == bound)
+		if (parameter.type != null && TypeBinding.equalsEquals(parameter.type.resolvedType, bound))
 			return parameter.type;
 		TypeReference[] bounds = parameter.bounds;
 		if (bounds != null) {
 			for (int i = 0; i < bounds.length; i++) {
-				if (bounds[i].resolvedType == bound)
+				if (TypeBinding.equalsEquals(bounds[i].resolvedType, bound))
 					return bounds[i];
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 1f5f9cb..b414b50 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -1091,7 +1091,7 @@
 		location.sourceEnd);
 }
 public void annotationCircularity(TypeBinding sourceType, TypeBinding otherType, TypeReference reference) {
-	if (sourceType == otherType)
+	if (TypeBinding.equalsEquals(sourceType, otherType))
 		this.handle(
 			IProblem.AnnotationCircularitySelfReference,
 			new String[] {new String(sourceType.readableName())},
@@ -2004,7 +2004,7 @@
 	if (inheritedMethod1.isCallin() != inheritedMethod2.isCallin())
 		return;
 // SH}
-	if (inheritedMethod1.declaringClass != inheritedMethod2.declaringClass) {
+	if (TypeBinding.notEquals(inheritedMethod1.declaringClass, inheritedMethod2.declaringClass)) {
 		int problemID = (inheritedMethod1.isDefaultMethod() && inheritedMethod2.isDefaultMethod())
 				? IProblem.DuplicateInheritedDefaultMethods
 				: IProblem.DuplicateInheritedMethods;
@@ -2366,7 +2366,7 @@
 			&& field.isStatic()
 			&& field.isPrivate()
 			&& field.isFinal()
-			&& TypeBinding.LONG == field.type) {
+			&& TypeBinding.equalsEquals(TypeBinding.LONG, field.type)) {
 		ReferenceBinding referenceBinding = field.declaringClass;
 		if (referenceBinding != null) {
 			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
@@ -2672,7 +2672,7 @@
 		end = reference.sourceEnd;
 	}
 
-	if (sourceType == superType)
+	if (TypeBinding.equalsEquals(sourceType, superType))
 		this.handle(
 			IProblem.HierarchyCircularitySelfReference,
 			new String[] {new String(sourceType.readableName()) },
@@ -2695,7 +2695,7 @@
 	start = reference.sourceStart;
 	end = reference.sourceEnd;
 
-	if (type == superType)
+	if (TypeBinding.equalsEquals(type, superType))
 		this.handle(
 			IProblem.HierarchyCircularitySelfReference,
 			new String[] {new String(type.readableName()) },
@@ -3342,7 +3342,7 @@
 	invalidType(importRef, (TypeBinding)expectedImport);
 }
 public void incompatibleExceptionInThrowsClause(SourceTypeBinding type, MethodBinding currentMethod, MethodBinding inheritedMethod, ReferenceBinding exceptionType) {
-	if (type == currentMethod.declaringClass) {
+	if (TypeBinding.equalsEquals(type, currentMethod.declaringClass)) {
 		int id;
 		if (currentMethod.declaringClass.isInterface()
 				&& !inheritedMethod.isPublic()){ // interface inheriting Object protected method
@@ -7264,13 +7264,13 @@
 }
 private String parameterBoundAsString(TypeVariableBinding typeVariable, boolean makeShort) {
     StringBuffer nameBuffer = new StringBuffer(10);
-    if (typeVariable.firstBound == typeVariable.superclass) {
+    if (TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) {
         nameBuffer.append(makeShort ? typeVariable.superclass.shortReadableName() : typeVariable.superclass.readableName());
     }
     int length;
     if ((length = typeVariable.superInterfaces.length) > 0) {
 	    for (int i = 0; i < length; i++) {
-	        if (i > 0 || typeVariable.firstBound == typeVariable.superclass) nameBuffer.append(" & "); //$NON-NLS-1$
+	        if (i > 0 || TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) nameBuffer.append(" & "); //$NON-NLS-1$
 	        nameBuffer.append(makeShort ? typeVariable.superInterfaces[i].shortReadableName() : typeVariable.superInterfaces[i].readableName());
 	    }
 	}
@@ -9004,7 +9004,7 @@
 	if (severity == ProblemSeverities.Ignore) return;
 	int start = type.sourceStart();
 	int end = type.sourceEnd();
-	if (currentMethod.declaringClass == type) {
+	if (TypeBinding.equalsEquals(currentMethod.declaringClass, type)) {
 		ASTNode location = ((MethodDeclaration) currentMethod.sourceMethod()).returnType;
 		start = location.sourceStart();
 		end = location.sourceEnd();
@@ -9194,7 +9194,7 @@
 	if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name)
 			&& field.isStatic()
 			&& field.isFinal()
-			&& TypeBinding.LONG == field.type) {
+			&& TypeBinding.equalsEquals(TypeBinding.LONG, field.type)) {
 		ReferenceBinding referenceBinding = field.declaringClass;
 		if (referenceBinding != null) {
 			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
@@ -9455,8 +9455,8 @@
 		        typesAsString(method2, true),
 		        new String(method2.declaringClass.shortReadableName())
 		},
-		method1.declaringClass == type ? method1.sourceStart() : type.sourceStart(),
-		method1.declaringClass == type ? method1.sourceEnd() : type.sourceEnd());
+		TypeBinding.equalsEquals(method1.declaringClass, type) ? method1.sourceStart() : type.sourceStart(),
+		TypeBinding.equalsEquals(method1.declaringClass, type) ? method1.sourceEnd() : type.sourceEnd());
 }
 public void safeVarargsOnFixedArityMethod(MethodBinding method) {
 	String [] arguments = new String[] { new String(method.isConstructor() ? method.declaringClass.shortReadableName() : method.selector)}; 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java
index d7670a9..28003dc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java
@@ -16,6 +16,7 @@
 
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 
 /**
@@ -76,7 +77,7 @@
 			// search superclass within input:
 			int j = 0;
 			for(j=0; j<input.length; j++)
-				if (input[j] == superclass)
+				if (TypeBinding.equalsEquals(input[j], superclass))
 					break;
 			if (j < input.length)
 				// depth first traversal:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/AnchorMapping.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/AnchorMapping.java
index 7b71c84..a30aef8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/AnchorMapping.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lookup/AnchorMapping.java
@@ -293,7 +293,7 @@
     * @param currentMethod  a candidate for the current method call
     */
    public static boolean areTypesEqual(TypeBinding t1, TypeBinding t2, MethodBinding currentMethod) {
-   		if (t1 == t2)
+   		if (TypeBinding.equalsEquals(t1, t2))
    			return true;
    		if (   t1 instanceof RoleTypeBinding
    			&& t2 instanceof RoleTypeBinding)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
index ed3a8aa..0e2aa36 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
@@ -203,7 +203,7 @@
 		return true;
 	}
 	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2, HashSet visitedTypes) {
-		if (typeBinding == typeBinding2)
+		if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(typeBinding, typeBinding2))
 			return true;
 		if (typeBinding == null || typeBinding2 == null)
 			return false;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 04831e3..e742de4 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -1056,7 +1056,7 @@
 			org.eclipse.jdt.internal.compiler.lookup.TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound;
 			int boundsLength = 0;
 			if (firstClassOrArrayBound != null) {
-				if (firstClassOrArrayBound == varSuperclass) {
+				if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(firstClassOrArrayBound, varSuperclass)) {
 					boundsLength++;
 				} else if (firstClassOrArrayBound.isArrayType()) { // capture of ? extends/super arrayType
 					boundsLength++;
@@ -1277,7 +1277,7 @@
 			return false;
 		}
 		org.eclipse.jdt.internal.compiler.lookup.TypeBinding otherBinding = ((TypeBinding) other).binding;
-		if (otherBinding.unannotated() == this.binding.unannotated()) {
+		if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(otherBinding.unannotated(), this.binding.unannotated())) {
 			return true;
 		}
 		// check return type
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
index 4cd8083..dc42749 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -199,7 +199,7 @@
 		// current stack is:
 		// field receiver value
 		if (valueRequired) {
-			if ((codegenBinding.type == TypeBinding.LONG) || (codegenBinding.type == TypeBinding.DOUBLE)) {
+			if ((TypeBinding.equalsEquals(codegenBinding.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(codegenBinding.type, TypeBinding.DOUBLE))) {
 				codeStream.dup2_x2();
 			} else {
 				codeStream.dup_x2();
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 4ea1ff8..8437289 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
@@ -186,7 +186,7 @@
 		    // extra cast needed if method return type was type variable
 		    if (codegenBinding.returnType.isTypeVariable()) {
 		        TypeVariableBinding variableReturnType = (TypeVariableBinding) codegenBinding.returnType;
-		        if (variableReturnType.firstBound != this.binding.returnType) { // no need for extra cast if same as first bound anyway
+		        if (TypeBinding.notEquals(variableReturnType.firstBound, this.binding.returnType)) { // no need for extra cast if same as first bound anyway
 				    this.valueCast = this.binding.returnType;
 		        }
 		    }
@@ -206,7 +206,7 @@
 	this.actualReceiverType = this.receiver.resolveType(scope);
 	if (receiverCast && this.actualReceiverType != null) {
 		 // due to change of declaring class with receiver type, only identity cast should be notified
-		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+		if (TypeBinding.equalsEquals(((CastExpression)this.receiver).expression.resolvedType, this.actualReceiverType)) {
 			scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
 		}
 	}
@@ -350,7 +350,7 @@
 			TypeBinding oldReceiverType = this.actualReceiverType;
 			this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(this.binding.declaringClass);
 			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
-			if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+			if (TypeBinding.notEquals(this.actualReceiverType, oldReceiverType) && TypeBinding.notEquals(this.receiver.postConversionType(scope), this.actualReceiverType)) { // record need for explicit cast at codegen since receiver could not handle it
 				this.bits |= NeedReceiverGenericCast;
 			}			
 		}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
index 12b420f..9a97adb 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
@@ -52,7 +52,7 @@
  */
 public CodeSnippetQualifiedNameReference(char[][] sources, long[] positions, int sourceStart, int sourceEnd, EvaluationContext evaluationContext) {
 	super(sources, positions, sourceStart, sourceEnd);
-	this.evaluationContext = evaluationContext;	
+	this.evaluationContext = evaluationContext;
 }
 
 /**
@@ -64,7 +64,7 @@
 	TypeBinding declaringClass = fieldBinding.original().declaringClass;
 	// check for forward references
 	if ((this.indexOfFirstFieldBinding == 1 || declaringClass.isEnum())
-			&& methodScope.enclosingSourceType() == declaringClass
+			&& TypeBinding.equalsEquals(methodScope.enclosingSourceType(), declaringClass)
 			&& methodScope.lastVisibleFieldID >= 0
 			&& fieldBinding.id >= methodScope.lastVisibleFieldID
 			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
@@ -80,7 +80,7 @@
 	if ((this.bits & Binding.VARIABLE) == 0) { // nothing to do if type ref
 		codeStream.recordPositionsFrom(pc, this.sourceStart);
 		return;
-		}
+	}
 	FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
 	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
 		super.generateCode(currentScope, codeStream, valueRequired);
@@ -89,18 +89,18 @@
 	lastFieldBinding = generateReadSequence(currentScope, codeStream);
 	if (lastFieldBinding != null) {
 		boolean isStatic = lastFieldBinding.isStatic();
-				Constant fieldConstant = lastFieldBinding.constant();
-				if (fieldConstant != Constant.NotAConstant) {
+		Constant fieldConstant = lastFieldBinding.constant();
+		if (fieldConstant != Constant.NotAConstant) {
 			if (!isStatic){
-						codeStream.invokeObjectGetClass();
-						codeStream.pop();
-					}
-			if (valueRequired) { // inline the last field constant
-					codeStream.generateConstant(fieldConstant, this.implicitConversion);
+				codeStream.invokeObjectGetClass();
+				codeStream.pop();
 			}
-				} else {	
+			if (valueRequired) { // inline the last field constant
+				codeStream.generateConstant(fieldConstant, this.implicitConversion);
+			}
+		} else {
 			boolean isFirst = lastFieldBinding == this.binding
-											&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+											&& (this.indexOfFirstFieldBinding == 1 || TypeBinding.equalsEquals(lastFieldBinding.declaringClass, currentScope.enclosingReceiverType()))
 											&& this.otherBindings == null; // could be dup: next.next.next
 			TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
 			if (valueRequired
@@ -112,15 +112,15 @@
 					codeStream.arraylength();
 					if (valueRequired) {
 						codeStream.generateImplicitConversion(this.implicitConversion);
-						} else {
+					} else {
 						// could occur if !valueRequired but compliance >= 1.4
 						codeStream.pop();
-						}
-					} else {
-						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+					}
+				} else {
+					codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
 					if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
 					if (valueRequired) {
-					codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateImplicitConversion(this.implicitConversion);
 					} else {
 						boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
 						// conversion only generated if unboxing
@@ -133,18 +133,18 @@
 							default :
 								codeStream.pop();
 						}
+					}
 				}
-			}
 
 				int fieldPosition = (int) (this.sourcePositions[this.sourcePositions.length - 1] >>> 32);
 				codeStream.recordPositionsFrom(lastFieldPc, fieldPosition);
-		} else {
+			} else {
 				if (!isStatic){
-				codeStream.invokeObjectGetClass(); // perform null check
-				codeStream.pop();
+					codeStream.invokeObjectGetClass(); // perform null check
+					codeStream.pop();
+				}
 			}
-		}		
-	}
+		}
 	}
 	codeStream.recordPositionsFrom(pc, this.sourceStart);
 }
@@ -156,7 +156,7 @@
 	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
 		super.generateAssignment(currentScope, codeStream, assignment, valueRequired);
 		return;
-		}
+	}
 	lastFieldBinding = generateReadSequence(currentScope, codeStream);
 	codeStream.generateEmulationForField(lastFieldBinding);
 	codeStream.swap();
@@ -170,8 +170,8 @@
 			default :
 				codeStream.dup_x2();
 			break;	
-				}
-		}
+		}		
+	}
 	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
 	if (valueRequired) {
 		codeStream.generateImplicitConversion(assignment.implicitConversion);
@@ -185,43 +185,43 @@
 		return;
 	}
 	lastFieldBinding = generateReadSequence(currentScope, codeStream);
-		if (lastFieldBinding.isStatic()){
-			codeStream.generateEmulationForField(lastFieldBinding);
-			codeStream.swap();
-			codeStream.aconst_null();
-			codeStream.swap();
-			codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
-		} else {
-			codeStream.generateEmulationForField(lastFieldBinding);
-			codeStream.swap();
-			codeStream.dup();
+	if (lastFieldBinding.isStatic()){
+		codeStream.generateEmulationForField(lastFieldBinding);
+		codeStream.swap();
+		codeStream.aconst_null();
+		codeStream.swap();
+		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	} else {
+		codeStream.generateEmulationForField(lastFieldBinding);
+		codeStream.swap();
+		codeStream.dup();
 
-			codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
-		}
-		// the last field access is a write access
-		// perform the actual compound operation
-		int operationTypeID;
-		if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
-			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	}
+	// the last field access is a write access
+	// perform the actual compound operation
+	int operationTypeID;
+	if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
+		codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+	} else {
+		// promote the array reference to the suitable operation type
+		codeStream.generateImplicitConversion(this.implicitConversion);
+		// generate the increment value (will by itself  be promoted to the operation value)
+		if (expression == IntLiteral.One){ // prefix operation
+			codeStream.generateConstant(expression.constant, this.implicitConversion);
 		} else {
-			// promote the array reference to the suitable operation type
-			codeStream.generateImplicitConversion(this.implicitConversion);
-			// generate the increment value (will by itself  be promoted to the operation value)
-			if (expression == IntLiteral.One){ // prefix operation
-				codeStream.generateConstant(expression.constant, this.implicitConversion);			
-			} else {
-				expression.generateCode(currentScope, codeStream, true);
-			}
-			// perform the operation
-			codeStream.sendOperator(operator, operationTypeID);
-			// cast the value back to the array reference type
-			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+			expression.generateCode(currentScope, codeStream, true);
 		}
-		// actual assignment
+		// perform the operation
+		codeStream.sendOperator(operator, operationTypeID);
+		// cast the value back to the array reference type
+		codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// actual assignment
 
-		// current stack is:
-		// field receiver value
-		if (valueRequired) {
+	// current stack is:
+	// field receiver value
+	if (valueRequired) {
 		switch (lastFieldBinding.type.id) {
 			case TypeIds.T_long :
 			case TypeIds.T_double :
@@ -230,21 +230,21 @@
 			default :
 				codeStream.dup_x2();
 			break;	
-			}
 		}
-		// current stack is:
-		// value field receiver value				
-		codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
 	}
+	// current stack is:
+	// value field receiver value
+	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+}
 public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
     FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
 	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
 		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
 		return;
-			}
+	}
 	lastFieldBinding = generateReadSequence(currentScope, codeStream);
-		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
-		if (valueRequired) {
+	codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	if (valueRequired) {
 		switch (lastFieldBinding.type.id) {
 			case TypeIds.T_long :
 			case TypeIds.T_double :
@@ -253,35 +253,35 @@
 			default :
 				codeStream.dup();
 			break;	
-			}
-		}
-		codeStream.generateEmulationForField(lastFieldBinding);
-		if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) {
-			codeStream.dup_x2();
-			codeStream.pop();
-			if (lastFieldBinding.isStatic()) {
-				codeStream.aconst_null();
-			} else {
-				generateReadSequence(currentScope, codeStream);
-			}
-			codeStream.dup_x2();
-			codeStream.pop();					
-		} else {
-			codeStream.dup_x1();
-			codeStream.pop();
-			if (lastFieldBinding.isStatic()) {
-				codeStream.aconst_null();
-			} else {
-				generateReadSequence(currentScope, codeStream);
-			}
-			codeStream.dup_x1();
-			codeStream.pop();					
-		}
-		codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
-		codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
-		codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
-		codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+		}		
 	}
+	codeStream.generateEmulationForField(lastFieldBinding);
+	if ((TypeBinding.equalsEquals(lastFieldBinding.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(lastFieldBinding.type, TypeBinding.DOUBLE))) {
+		codeStream.dup_x2();
+		codeStream.pop();
+		if (lastFieldBinding.isStatic()) {
+			codeStream.aconst_null();
+		} else {
+			generateReadSequence(currentScope, codeStream);
+		}
+		codeStream.dup_x2();
+		codeStream.pop();
+	} else {
+		codeStream.dup_x1();
+		codeStream.pop();
+		if (lastFieldBinding.isStatic()) {
+			codeStream.aconst_null();
+		} else {
+			generateReadSequence(currentScope, codeStream);
+		}
+		codeStream.dup_x1();
+		codeStream.pop();
+	}
+	codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
+	codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+}
 
 /*
  * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
@@ -328,7 +328,7 @@
 					} else {
 						codeStream.aconst_null();
 					}
-				}				
+				}
 			}
 			break;
 		case Binding.LOCAL : // reading the first local variable
@@ -368,14 +368,14 @@
 			TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
 			if (lastFieldBinding != null) {
 				needValue = !nextField.isStatic();
-						Constant fieldConstant = lastFieldBinding.constant();
-						if (fieldConstant != Constant.NotAConstant) {
+				Constant fieldConstant = lastFieldBinding.constant();
+				if (fieldConstant != Constant.NotAConstant) {
 					if (i > 0 && !lastFieldBinding.isStatic()) {
-								codeStream.invokeObjectGetClass(); // perform null check
-								codeStream.pop();
-							}
+						codeStream.invokeObjectGetClass(); // perform null check
+						codeStream.pop();
+					}
 					if (needValue) {
-							codeStream.generateConstant(fieldConstant, 0);
+						codeStream.generateConstant(fieldConstant, 0);
 					}
 				} else {
 					if (needValue || (i > 0 && complyTo14) || lastGenericCast != null) {
@@ -388,16 +388,16 @@
 								} else {
 									codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
 								}
-						} else {
+							} else {
 								codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+							}
+						} else {
+							codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
 						}
-					} else {
-						codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
-					}
 						if (lastGenericCast != null) {
 							codeStream.checkcast(lastGenericCast);
 							lastReceiverType = lastGenericCast;
-				} else {
+						} else {
 							lastReceiverType = lastFieldBinding.type;
 						}
 						if (!needValue) codeStream.pop();
@@ -405,7 +405,7 @@
 						if (lastFieldBinding == initialFieldBinding) {
 							if (lastFieldBinding.isStatic()){
 								// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
-								if (initialFieldBinding.declaringClass != this.actualReceiverType.erasure()) {
+								if (TypeBinding.notEquals(initialFieldBinding.declaringClass, this.actualReceiverType.erasure())) {
 									if (lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
 										MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
 										if (accessor == null) {
@@ -421,9 +421,9 @@
 								}
 							}
 						} else if (!lastFieldBinding.isStatic()){
-						codeStream.invokeObjectGetClass(); // perform null check
-						codeStream.pop();
-					}						
+							codeStream.invokeObjectGetClass(); // perform null check
+							codeStream.pop();
+						}
 						lastReceiverType = lastFieldBinding.type;
 					}
 					if ((positionsLength - otherBindingsCount + i - 1) >= 0) {
@@ -438,10 +438,10 @@
 				if (lastFieldBinding.isStatic()) {
 					codeStream.aconst_null();
 				}
-			}
-		}			
+			}			
+		}
 	}
-	return lastFieldBinding;
+	return lastFieldBinding;	
 }
 
 
@@ -463,7 +463,7 @@
 					scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
 					return null;
 				}
-			} else { //accessing to a field using a type as "receiver" is allowed only with static field	
+			} else { //accessing to a field using a type as "receiver" is allowed only with static field
 				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
 				return null;
 			}
@@ -484,11 +484,11 @@
 	// allocation of the fieldBindings array	and its respective constants
 	int otherBindingsLength = length - index;
 	this.otherBindings = new FieldBinding[otherBindingsLength];
-	
+
 	// fill the first constant (the one of the binding)
 	this.constant =((VariableBinding) this.binding).constant();
 
-	// iteration on each field	
+	// iteration on each field
 	while (index < length) {
 		char[] token = this.tokens[index];
 		if (type == null) return null; // could not resolve type prior to this point
@@ -534,12 +534,12 @@
 	return (this.otherBindings[otherBindingsLength - 1]).type;
 }
 
-	/**
-	 * index is <0 to denote write access emulation
-	 */		
+/**
+ * index is <0 to denote write access emulation
+ */
 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
 	// do nothing
-	}
+}
 
 /**
  * Normal field binding did not work, try to bind to a field of the delegate receiver.
@@ -565,7 +565,7 @@
 				CodeSnippetScope localScope = new CodeSnippetScope(scope);
 				this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.tokens[0], this);
 				if (this.binding.isValidBinding()) {
-					return checkFieldAccess(scope);						
+					return checkFieldAccess(scope);
 				} else {
 					return super.reportError(scope);
 				}
@@ -579,13 +579,13 @@
 
 	TypeBinding result;
 	if (this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotVisible) {
-	// field and/or local are done before type lookups
-	// the only available value for the restrictiveFlag BEFORE
-	// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField 
-	CodeSnippetScope localScope = new CodeSnippetScope(scope);
+		// field and/or local are done before type lookups
+		// the only available value for the restrictiveFlag BEFORE
+		// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField
+		CodeSnippetScope localScope = new CodeSnippetScope(scope);
 		if ((this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) {
-		this.bits &= ~RestrictiveFlagMASK; // clear bits
-		this.bits |= Binding.FIELD;
+			this.bits &= ~RestrictiveFlagMASK; // clear bits
+			this.bits |= Binding.FIELD;
 			result = getOtherFieldBindings(scope);
 		} else {
 			return super.reportError(scope);
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 6fff6ba..b07ddf3 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
@@ -71,14 +71,14 @@
 	if (fieldBinding.isPublic()) return true;
 
 	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
-	if (invocationType == fieldBinding.declaringClass) return true;
+	if (TypeBinding.equalsEquals(invocationType, fieldBinding.declaringClass)) return true;
 
 	if (fieldBinding.isProtected()) {
 		// answer true if the invocationType is the declaringClass or they are in the same package
 		// OR the invocationType is a subclass of the declaringClass
 		//    AND the receiverType is the invocationType or its subclass
 		//    OR the field is a static field accessed directly through a type
-		if (invocationType == fieldBinding.declaringClass) return true;
+		if (TypeBinding.equalsEquals(invocationType, fieldBinding.declaringClass)) return true;
 		if (invocationType.fPackage == fieldBinding.declaringClass.fPackage) return true;
 		if (fieldBinding.declaringClass.isSuperclassOf(invocationType)) {
 			if (invocationSite.isSuperAccess()) return true;
@@ -96,9 +96,9 @@
 	if (fieldBinding.isPrivate()) {
 		// answer true if the receiverType is the declaringClass
 		// AND the invocationType and the declaringClass have a common enclosingType
-		if (receiverType != fieldBinding.declaringClass) return false;
+		if (TypeBinding.notEquals(receiverType, fieldBinding.declaringClass)) return false;
 
-		if (invocationType != fieldBinding.declaringClass) {
+		if (TypeBinding.notEquals(invocationType, fieldBinding.declaringClass)) {
 			ReferenceBinding outerInvocationType = invocationType;
 			ReferenceBinding temp = outerInvocationType.enclosingType();
 			while (temp != null) {
@@ -112,7 +112,7 @@
 				outerDeclaringClass = temp;
 				temp = temp.enclosingType();
 			}
-			if (outerInvocationType != outerDeclaringClass) return false;
+			if (TypeBinding.notEquals(outerInvocationType, outerDeclaringClass)) return false;
 		}
 		return true;
 	}
@@ -128,9 +128,9 @@
 	TypeBinding originalDeclaringClass = fieldBinding.declaringClass .original();
 	do {
 		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
-			if (originalDeclaringClass == type.erasure().original()) return true;	
+			if (TypeBinding.equalsEquals(originalDeclaringClass, type.erasure().original())) return true;	
 		} else {
-			if (originalDeclaringClass == type.original()) return true;
+			if (TypeBinding.equalsEquals(originalDeclaringClass, type.original())) return true;
 		}
 		if (declaringPackage != type.fPackage) return false;
 	} while ((type = type.superclass()) != null);
@@ -146,14 +146,14 @@
 	if (methodBinding.isPublic()) return true;
 
 	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
-	if (invocationType == methodBinding.declaringClass) return true;
+	if (TypeBinding.equalsEquals(invocationType, methodBinding.declaringClass)) return true;
 
 	if (methodBinding.isProtected()) {
 		// answer true if the invocationType is the declaringClass or they are in the same package
 		// OR the invocationType is a subclass of the declaringClass
 		//    AND the receiverType is the invocationType or its subclass
 		//    OR the method is a static method accessed directly through a type
-		if (invocationType == methodBinding.declaringClass) return true;
+		if (TypeBinding.equalsEquals(invocationType, methodBinding.declaringClass)) return true;
 		if (invocationType.fPackage == methodBinding.declaringClass.fPackage) return true;
 		if (methodBinding.declaringClass.isSuperclassOf(invocationType)) {
 			if (invocationSite.isSuperAccess()) return true;
@@ -171,9 +171,9 @@
 	if (methodBinding.isPrivate()) {
 		// answer true if the receiverType is the declaringClass
 		// AND the invocationType and the declaringClass have a common enclosingType
-		if (receiverType != methodBinding.declaringClass) return false;
+		if (TypeBinding.notEquals(receiverType, methodBinding.declaringClass)) return false;
 
-		if (invocationType != methodBinding.declaringClass) {
+		if (TypeBinding.notEquals(invocationType, methodBinding.declaringClass)) {
 			ReferenceBinding outerInvocationType = invocationType;
 			ReferenceBinding temp = outerInvocationType.enclosingType();
 			while (temp != null) {
@@ -187,7 +187,7 @@
 				outerDeclaringClass = temp;
 				temp = temp.enclosingType();
 			}
-			if (outerInvocationType != outerDeclaringClass) return false;
+			if (TypeBinding.notEquals(outerInvocationType, outerDeclaringClass)) return false;
 		}
 		return true;
 	}
@@ -203,9 +203,9 @@
 	TypeBinding originalDeclaringClass = methodBinding.declaringClass .original();
 	do {
 		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
-			if (originalDeclaringClass == type.erasure().original()) return true;
+			if (TypeBinding.equalsEquals(originalDeclaringClass, type.erasure().original())) return true;
 		} else {
-			if (originalDeclaringClass == type.original()) return true;
+			if (TypeBinding.equalsEquals(originalDeclaringClass, type.original())) return true;
 		}
 		if (declaringPackage != type.fPackage) return false;
 	} while ((type = type.superclass()) != null);
@@ -221,7 +221,7 @@
 public final boolean canBeSeenByForCodeSnippet(ReferenceBinding referenceBinding, ReferenceBinding receiverType) {
 	if (referenceBinding.isPublic()) return true;
 
-	if (receiverType == referenceBinding) return true;
+	if (TypeBinding.equalsEquals(receiverType, referenceBinding)) return true;
 
 	if (referenceBinding.isProtected()) {
 		// answer true if the receiver (or its enclosing type) is the superclass 
@@ -247,7 +247,7 @@
 			outerDeclaringClass = temp;
 			temp = temp.enclosingType();
 		}
-		return outerInvocationType == outerDeclaringClass;
+		return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
 	}
 
 	// isDefault()
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
index 42034a7..112ec4f 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -174,7 +174,7 @@
 				}
 				assignment.expression.generateCode(currentScope, codeStream, true);
 				if (valueRequired) {
-					if ((codegenField.type == TypeBinding.LONG) || (codegenField.type == TypeBinding.DOUBLE)) {
+					if ((TypeBinding.equalsEquals(codegenField.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(codegenField.type, TypeBinding.DOUBLE))) {
 						codeStream.dup2_x2();
 					} else {
 						codeStream.dup_x2();
@@ -203,7 +203,7 @@
 					if (valueRequired) {
 						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
 					} else {
-						if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) {
+						if ((TypeBinding.equalsEquals(localBinding.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(localBinding.type, TypeBinding.DOUBLE))) {
 							codeStream.pop2();
 						} else {
 							codeStream.pop();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
index 5e9ad1d..e198234 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
@@ -232,7 +232,7 @@
 			}
 		}
 		for (int t = this.typeIndex; t >= 0; t--) {
-			if (this.typeBindings[t] == superBinding) {
+			if (TypeBinding.equalsEquals(this.typeBindings[t], superBinding)) {
 				return this.builder.getHandle(this.typeModels[t], superBinding);
 			}
 		}
@@ -338,7 +338,7 @@
 			if (CharOperation.equals(simpleName, interfaceBinding.sourceName)) {
 				bindingIndex++;
 				for (int t = this.typeIndex; t >= 0; t--) {
-					if (this.typeBindings[t] == interfaceBinding) {
+					if (TypeBinding.equalsEquals(this.typeBindings[t], interfaceBinding)) {
 						IType handle = this.builder.getHandle(this.typeModels[t], interfaceBinding);
 						if (handle != null) {
 							superinterfaces[index++] = handle;
@@ -1065,7 +1065,7 @@
 }
 private boolean subTypeOfType(ReferenceBinding subType, ReferenceBinding typeBinding) {
 	if (typeBinding == null || subType == null) return false;
-	if (subType == typeBinding) return true;
+	if (TypeBinding.equalsEquals(subType, typeBinding)) return true;
 	ReferenceBinding superclass = subType.superclass();
 	if (superclass != null) superclass = (ReferenceBinding) superclass.erasure();
 //	if (superclass != null && superclass.id == TypeIds.T_JavaLangObject && subType.isHierarchyInconsistent()) return false;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
index 6a10ced..d15bd7a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
@@ -149,7 +149,7 @@
 		TypeBinding[] parameters = method.parameters;
 		if (argumentTypes.length == parameters.length) {
 			for (int j=0,l=parameters.length; j<l; j++) {
-				if (parameters[j].erasure() != argumentTypes[j].erasure()) {
+				if (TypeBinding.notEquals(parameters[j].erasure(), argumentTypes[j].erasure())) {
 					continue methodsLoop;
 				}
 			}
@@ -1094,7 +1094,7 @@
 				if (argumentTypes.length == parameters.length) {
 					boolean found = true;
 					for (int k=0,l=parameters.length; k<l; k++) {
-						if (parameters[k].erasure() != argumentTypes[k].erasure()) {
+						if (TypeBinding.notEquals(parameters[k].erasure(), argumentTypes[k].erasure())) {
 							found = false;
 							break;
 						}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
index 01e07b7..14cb7ae 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
@@ -555,12 +555,12 @@
 			int length = argumentsBindings.length;
 			if (length == typeVariables.length) {
 				for (int i=0; i<length; i++) {
-				if (argumentsBindings[i] != typeVariables[i]) {
-					needUpdate = true;
-					break;
+					if (TypeBinding.notEquals(argumentsBindings[i], typeVariables[i])) {
+						needUpdate = true;
+						break;
+					}
 				}
 			}
-			}
 			if (needUpdate) {
 				char[][] patternArguments =  patternTypeArguments[depth];
 				updateMatch(argumentsBindings, locator, patternArguments, patternHasTypeParameters);	
@@ -686,7 +686,7 @@
 					if (argumentBinding.isWildcard()) { // argument is a wildcard
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
 						// It's ok if wildcards are identical
-						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+						if (wildcardBinding.boundKind == patternWildcardKind && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) {
 							continue;
 						}
 						// Look for wildcard compatibility
@@ -714,7 +714,7 @@
 					if (argumentBinding.isWildcard()) { // argument is a wildcard
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
 						// It's ok if wildcards are identical
-						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+						if (wildcardBinding.boundKind == patternWildcardKind && TypeBinding.equalsEquals(wildcardBinding.bound, patternBinding)) {
 							continue;
 						}
 						// Look for wildcard compatibility
@@ -760,7 +760,7 @@
 								matchRule &= ~SearchPattern.R_FULL_MATCH;
 								continue;
 						}
-					} else if (argumentBinding == patternBinding)
+					} else if (TypeBinding.equalsEquals(argumentBinding, patternBinding))
 						// valid only when arg is equals to pattern
 						continue;
 					break;