1.5 - raw types in binaries
diff --git a/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 32deb79..4a78241 100644
--- a/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -850,6 +850,8 @@
 	int InvalidClassInstantiationWithWildcards = Internal + 537;
 	/** @since 3.1 */
 	int FinalBoundForTypeVariable = TypeRelated + 538;
+	/** @since 3.1 */
+	int UndefinedTypeVariable = Internal + 539;
 	
 	/**
 	 * Foreach
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index c884f60..0375782 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -154,9 +154,10 @@
 	}
 	return CharOperation.concat(leafComponentType.sourceName(), brackets);
 }
-public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
-	if (this.leafComponentType == unresolvedType)
-		this.leafComponentType = resolvedType;
+public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment environment) {
+	if (this.leafComponentType == unresolvedType) {
+		this.leafComponentType = resolvedType.isGenericType() ? environment.createRawType(resolvedType) : resolvedType;
+	}
 }
 public String toString() {
 	return leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index e63c947..a7eab82 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -39,23 +39,20 @@
 private FieldBinding[] fields;
 private MethodBinding[] methods;
 private ReferenceBinding[] memberTypes;
-private TypeVariableBinding[] typeVariables;
+protected TypeVariableBinding[] typeVariables;
 
 // For the link with the principle structure
 private LookupEnvironment environment;
 
-public static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, ParameterizedTypeBinding parameterizedType, int rank) {
+public static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, boolean rawCheck, ParameterizedTypeBinding parameterizedType, int rank) {
 	if (type instanceof UnresolvedReferenceBinding)
-		return ((UnresolvedReferenceBinding) type).resolve(environment, parameterizedType, rank);
+		return ((UnresolvedReferenceBinding) type).resolve(environment, rawCheck, parameterizedType, rank);
 	if (type.isParameterizedType())
 		return ((ParameterizedTypeBinding) type).resolve();
 	if (type.isWildcard())
 		return ((WildcardBinding) type).resolve(parameterizedType, rank);
 	if (type.isArrayType())
-		resolveType(((ArrayBinding) type).leafComponentType, environment, parameterizedType, rank);
-	if (type.isTypeVariable()) {
-		return ((TypeVariableBinding) type).resolve(environment);
-	}
+		resolveType(((ArrayBinding) type).leafComponentType, environment, rawCheck, parameterizedType, rank);
 	return type;
 }
 
@@ -134,7 +131,7 @@
 	char[] enclosingTypeName = binaryType.getEnclosingTypeName();
 	if (enclosingTypeName != null) {
 		// attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
-		this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1);
+		this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true); // pretend parameterized to avoid raw
 		this.tagBits |= MemberTypeMask;   // must be a member type not a top-level or local type
 		this.tagBits |= 	HasUnresolvedEnclosingType;
 		if (this.enclosingType().isStrictfp())
@@ -149,7 +146,7 @@
 		char[] superclassName = binaryType.getSuperclassName();
 		if (superclassName != null) {
 			// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
-			this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1);
+			this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1, false);
 			this.tagBits |= 	HasUnresolvedSuperclass;
 		}
 
@@ -161,7 +158,7 @@
 				this.superInterfaces = new ReferenceBinding[size];
 				for (int i = 0; i < size; i++)
 					// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
-					this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1);
+					this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false);
 				this.tagBits |= 	HasUnresolvedSuperinterfaces;
 			}
 		}
@@ -207,7 +204,7 @@
 			this.memberTypes = new ReferenceBinding[size];
 			for (int i = 0; i < size; i++)
 				// attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
-				this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1);
+				this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false);
 			this.tagBits |= 	HasUnresolvedMemberTypes;
 		}
 	}
@@ -230,7 +227,7 @@
 				IBinaryField field = iFields[i];
 				char[] fieldSignature = checkGenericSignatures ? field.getGenericSignature() : null;
 				TypeBinding type = fieldSignature == null
-					? environment.getTypeFromSignature(field.getTypeName(), 0, -1)
+					? environment.getTypeFromSignature(field.getTypeName(), 0, -1, false)
 					: environment.getTypeFromTypeSignature(new SignatureWrapper(fieldSignature, 0), NoTypeVariables, this);
 				this.fields[i] =
 					new FieldBinding(
@@ -276,7 +273,7 @@
 					while ((nextChar = methodDescriptor[++end]) != ';');
 	
 				if (i >= startIndex)   // skip the synthetic arg if necessary
-					parameters[i - startIndex] = environment.getTypeFromSignature(methodDescriptor, index, end);
+					parameters[i - startIndex] = environment.getTypeFromSignature(methodDescriptor, index, end, false);
 				index = end + 1;
 			}
 		}
@@ -287,12 +284,12 @@
 			if (size > 0) {
 				exceptions = new ReferenceBinding[size];
 				for (int i = 0; i < size; i++)
-					exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1);
+					exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false);
 			}
 		}
 
 		if (!method.isConstructor())
-			returnType = environment.getTypeFromSignature(methodDescriptor, index + 1, -1);   // index is currently pointing at the ')'
+			returnType = environment.getTypeFromSignature(methodDescriptor, index + 1, -1, false);   // index is currently pointing at the ')'
 	} else {
 		// MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
 		SignatureWrapper wrapper = new SignatureWrapper(methodSignature, 0);
@@ -347,7 +344,7 @@
 				if (size > 0) {
 					exceptions = new ReferenceBinding[size];
 					for (int i = 0; i < size; i++)
-						exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1);
+						exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false);
 				}
 			}
 		}
@@ -436,7 +433,7 @@
 	if ((this.tagBits & HasUnresolvedEnclosingType) == 0)
 		return this.enclosingType;
 
-	this.enclosingType = (ReferenceBinding) resolveType(this.enclosingType, this.environment, null, 0);
+	this.enclosingType = (ReferenceBinding) resolveType(this.enclosingType, this.environment, false, null, 0);
 	this.tagBits ^= HasUnresolvedEnclosingType;
 	return this.enclosingType;
 }
@@ -559,7 +556,7 @@
 		return this.memberTypes;
 
 	for (int i = this.memberTypes.length; --i >= 0;)
-		this.memberTypes[i] = (ReferenceBinding) resolveType(this.memberTypes[i], this.environment, null, 0);
+		this.memberTypes[i] = (ReferenceBinding) resolveType(this.memberTypes[i], this.environment, false, null, 0);
 	this.tagBits ^= HasUnresolvedMemberTypes;
 	return this.memberTypes;
 }
@@ -578,7 +575,7 @@
 	if ((field.modifiers & AccUnresolved) == 0)
 		return field;
 
-	field.type = resolveType(field.type, this.environment, null, 0);
+	field.type = resolveType(field.type, this.environment, true, null, 0);
 	field.modifiers ^= AccUnresolved;
 	return field;
 }
@@ -587,11 +584,11 @@
 		return method;
 
 	if (!method.isConstructor())
-		method.returnType = resolveType(method.returnType, this.environment, null, 0);
+		method.returnType = resolveType(method.returnType, this.environment, true, null, 0);
 	for (int i = method.parameters.length; --i >= 0;)
-		method.parameters[i] = resolveType(method.parameters[i], this.environment, null, 0);
+		method.parameters[i] = resolveType(method.parameters[i], this.environment, true, null, 0);
 	for (int i = method.thrownExceptions.length; --i >= 0;)
-		method.thrownExceptions[i] = (ReferenceBinding)resolveType(method.thrownExceptions[i], this.environment, null, 0);
+		method.thrownExceptions[i] = (ReferenceBinding)resolveType(method.thrownExceptions[i], this.environment, true, null, 0);
 	method.modifiers ^= AccUnresolved;
 	return method;
 }
@@ -600,12 +597,12 @@
 		return variable;
 
 	if (variable.superclass != null)
-		variable.superclass = (ReferenceBinding)resolveType(variable.superclass, this.environment, null, 0);
+		variable.superclass = (ReferenceBinding)resolveType(variable.superclass, this.environment, true, null, 0);
 	if (variable.firstBound != null)
-		variable.firstBound = (ReferenceBinding) resolveType(variable.firstBound, this.environment, null, 0);
+		variable.firstBound = (ReferenceBinding) resolveType(variable.firstBound, this.environment, true, null, 0);
 	ReferenceBinding[] interfaces = variable.superInterfaces;
 	for (int i = interfaces.length; --i >= 0;)
-		interfaces[i] = (ReferenceBinding) resolveType(interfaces[i], this.environment, null, 0);
+		interfaces[i] = (ReferenceBinding) resolveType(interfaces[i], this.environment, true, null, 0);
 	variable.modifiers ^= AccUnresolved;
 	return variable;
 }
@@ -618,7 +615,7 @@
 	if ((this.tagBits & HasUnresolvedSuperclass) == 0)
 		return this.superclass;
 
-	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, null, 0);
+	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true, null, 0);
 	this.tagBits ^= HasUnresolvedSuperclass;
 	return this.superclass;
 }
@@ -629,7 +626,7 @@
 		return this.superInterfaces;
 
  	for (int i = this.superInterfaces.length; --i >= 0;)
-		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, null, 0);
+		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true, null, 0);
 	this.tagBits ^= HasUnresolvedSuperinterfaces;
 	return this.superInterfaces;
 }
@@ -637,7 +634,7 @@
  	if ((this.tagBits & HasUnresolvedTypeVariables) == 0)
 		return this.typeVariables;
  	for (int i = this.typeVariables.length; --i >= 0;)
-		resolveType(this.typeVariables[i], this.environment, null, 0);
+		resolveTypesFor(this.typeVariables[i]);
 	this.tagBits ^= HasUnresolvedTypeVariables;
 	return this.typeVariables;
 }
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index e2c88b5..a495d29 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -16,7 +16,6 @@
 import org.eclipse.jdt.internal.compiler.env.*;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
-import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
 import org.eclipse.jdt.internal.compiler.util.Util;
@@ -512,8 +511,9 @@
 
 	if (referenceBinding == null || referenceBinding == TheNotFoundType)
 		return null;
+	// TODO (kent) this will not handle names which would be part of parameterized type ref - maybe acceptable, but if so should be documented
 	if (referenceBinding instanceof UnresolvedReferenceBinding)
-		referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this, null, 0);
+		referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this, true, null, 0);
 
 	// compoundName refers to a nested type incorrectly (for example, package1.A$B)
 	if (referenceBinding.isNestedType())
@@ -530,7 +530,7 @@
 * NOTE: Aborts compilation if the class file cannot be found.
 */
 
-ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end) {
+ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end, boolean isParameterized) {
 	if (end == -1)
 		end = signature.length;
 
@@ -543,6 +543,9 @@
 	} else if (binding == TheNotFoundType) {
 		problemReporter.isClassPathCorrect(compoundName, null);
 		return null; // will not get here since the above error aborts the compilation
+	} else if (!isParameterized && binding.isGenericType()) {
+	    // check raw type, only for resolved types
+        binding = createRawType(binding);
 	}
 	return binding;
 }
@@ -555,7 +558,7 @@
 * NOTE: Aborts compilation if the class file cannot be found.
 */
 
-TypeBinding getTypeFromSignature(char[] signature, int start, int end) {
+TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean isParameterized) {
 	int dimension = 0;
 	while (signature[start] == '[') {
 		start++;
@@ -599,7 +602,7 @@
 				throw new Error(Util.bind("error.undefinedBaseType",String.valueOf(signature[start]))); //$NON-NLS-1$
 		}
 	} else {
-		binding = getTypeFromConstantPoolName(signature, start + 1, end);
+		binding = getTypeFromConstantPoolName(signature, start + 1, end, isParameterized);
 	}
 
 	if (dimension == 0)
@@ -625,22 +628,24 @@
 		for (int i = staticVariables.length; --i >= 0;)
 			if (CharOperation.equals(staticVariables[i].sourceName, wrapper.signature, varStart, varEnd))
 				return dimension == 0 ? (TypeBinding) staticVariables[i] : createArrayType(staticVariables[i], dimension);
+	    ReferenceBinding initialType = enclosingType;
 		do {
-			TypeVariableBinding[] enclosingVariables = enclosingType.typeVariables();
-			for (int i = enclosingVariables.length; --i >= 0;)
-				if (CharOperation.equals(enclosingVariables[i].sourceName, wrapper.signature, varStart, varEnd))
-					return dimension == 0 ? (TypeBinding) enclosingVariables[i] : createArrayType(enclosingVariables[i], dimension);
+		    if (enclosingType instanceof BinaryTypeBinding) { // per construction can only be binary type binding
+				TypeVariableBinding[] enclosingVariables = ((BinaryTypeBinding)enclosingType).typeVariables; // do not trigger resolution of variables
+				for (int i = enclosingVariables.length; --i >= 0;)
+					if (CharOperation.equals(enclosingVariables[i].sourceName, wrapper.signature, varStart, varEnd))
+						return dimension == 0 ? (TypeBinding) enclosingVariables[i] : createArrayType(enclosingVariables[i], dimension);
+		    }
 		} while ((enclosingType = enclosingType.enclosingType()) != null);
-		throw new AbortCompilation(
-			this.unitBeingCompleted.compilationResult,
-			new IllegalAccessError(Util.bind("error.undefinedTypeVariable", new String(CharOperation.subarray(wrapper.signature, varStart, varEnd))))); //$NON-NLS-1$
+		problemReporter.undefinedTypeVariableSignature(CharOperation.subarray(wrapper.signature, varStart, varEnd), initialType);
+		return null; // cannot reach this, since previous problem will abort compilation
 	}
 
-	TypeBinding type = getTypeFromSignature(wrapper.signature, wrapper.start, wrapper.computeEnd());
+	TypeBinding type = getTypeFromSignature(wrapper.signature, wrapper.start, wrapper.computeEnd(), true);
 	if (wrapper.end != wrapper.bracket)
 		return dimension == 0 ? type : createArrayType(type, dimension);
 	// type must be a ReferenceBinding at this point, cannot be a BaseTypeBinding or ArrayTypeBinding
-	ReferenceBinding actualType = (ReferenceBinding) type;
+	ReferenceBinding actualType = (ReferenceBinding) type; // TODO (kent) what if it is actually due to bogus binaries ?
 
 	java.util.ArrayList args = new java.util.ArrayList(2);
 	int rank = 0;
@@ -729,37 +734,17 @@
 		Object[] keys = uniqueParameterizedTypeBindings.keyTable;
 		for (int i = 0, l = keys.length; i < l; i++) {
 			if (keys[i] == unresolvedType) {
-				keys[i] = resolvedType; // hashCode is based on compoundName so this works
+				keys[i] = resolvedType; // hashCode is based on compoundName so this works - cannot be raw since type of parameterized type
 				break;
 			}
 		}
 	}
 
-// TODO (kent) we should be recreating unresolved raw bindings from binaries (in case no generic signature and referencing a generic type)
-// TODO (philippe) what????
-//	if (uniqueRawTypeBindings.get(unresolvedType) != null) { // update the key
-//		Object[] keys = uniqueRawTypeBindings.keyTable;
-//		for (int i = 0, l = keys.length; i < l; i++) {
-//			if (keys[i] == unresolvedType) {
-//				keys[i] = resolvedType; // hashCode is based on compoundName so this works
-//				break;
-//			}
-//		}
-//	}
-//	values = uniqueRawTypeBindings.valueTable;
-//	for (int i = 0, l = values.length; i < l; i++) {
-//		if (values[i] != null) {
-//			RawTypeBinding cachedType = (RawTypeBinding) values[i];
-//			if (cachedType.type == unresolvedType)
-//				cachedType.type = resolvedType;
-//		}
-//	}
-
 	if (uniqueWildcardBindings.get(unresolvedType) != null) { // update the key
 		Object[] keys = uniqueWildcardBindings.keyTable;
 		for (int i = 0, l = keys.length; i < l; i++) {
 			if (keys[i] == unresolvedType) {
-				keys[i] = resolvedType; // hashCode is based on compoundName so this works
+				keys[i] = resolvedType.isGenericType() ? createRawType(resolvedType) : resolvedType; // hashCode is based on compoundName so this works
 				break;
 			}
 		}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 021040b..304b5c8 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -479,8 +479,8 @@
 		return TypeConstants.NoExceptions; // safety check
 
 	for (int i = exceptions.length; --i >= 0;)
-		if (exceptions[i] instanceof UnresolvedReferenceBinding)
-			exceptions[i] = (ReferenceBinding) BinaryTypeBinding.resolveType(exceptions[i], this.environment, null, 0);
+		if (exceptions[i] instanceof UnresolvedReferenceBinding) // TODO (kent) should use more general #resolveType mechanism to address all cases
+			exceptions[i] = (ReferenceBinding) BinaryTypeBinding.resolveType(exceptions[i], this.environment, true, null, 0);
 	return exceptions;
 }
 private ReferenceBinding runtimeException() {
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
index fd5ce4e..7b71ed8 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
@@ -124,7 +124,7 @@
 	if (binding == LookupEnvironment.TheNotFoundType)
 		return null;
 	if (binding instanceof UnresolvedReferenceBinding)
-		binding = ((UnresolvedReferenceBinding) binding).resolve(environment, null, 0);
+		binding = ((UnresolvedReferenceBinding) binding).resolve(environment, true, null, 0);
 	if (binding.isNestedType())
 		return new ProblemReferenceBinding(name, InternalNameProvided);
 	return binding;
@@ -160,7 +160,7 @@
 	ReferenceBinding typeBinding = getType0(name);
 	if (typeBinding != null && typeBinding != LookupEnvironment.TheNotFoundType) {
 		if (typeBinding instanceof UnresolvedReferenceBinding)
-			typeBinding = ((UnresolvedReferenceBinding) typeBinding).resolve(environment, null, 0);
+			typeBinding = ((UnresolvedReferenceBinding) typeBinding).resolve(environment, false, null, 0); // no raw check
 		if (typeBinding.isNestedType())
 			return new ProblemReferenceBinding(name, InternalNameProvided);
 		return typeBinding;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index b861b9c..468e691 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -395,10 +395,10 @@
 	}
 
 	ReferenceBinding resolve() {
-		ReferenceBinding resolvedType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.type, this.environment, null, 0);
+		ReferenceBinding resolvedType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.type, this.environment, false, null, 0); // still part of parameterized type ref
 		int argLength = this.arguments.length;
 		for (int i = 0; i < argLength; i++)
-			BinaryTypeBinding.resolveType(this.arguments[i], this.environment, this, i);
+			BinaryTypeBinding.resolveType(this.arguments[i], this.environment, true, this, i);
 		// arity check
 		TypeVariableBinding[] refTypeVariables = resolvedType.typeVariables();
 		if (refTypeVariables == NoTypeVariables) { // check generic
@@ -543,16 +543,16 @@
 		return this.superInterfaces;
 	}
 
-	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
+	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
 		boolean update = false;
 		if (this.type == unresolvedType) {
-			this.type = resolvedType;
+			this.type = resolvedType; // cannot be raw since being parameterized below
 			update = true;
 		}
 		if (this.arguments != null) {
 			for (int i = 0, l = this.arguments.length; i < l; i++) {
 				if (this.arguments[i] == unresolvedType) {
-					this.arguments[i] = resolvedType;
+					this.arguments[i] = resolvedType.isGenericType() ? env.createRawType(resolvedType) : resolvedType;
 					update = true;
 				}
 			}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 05f3d20..553d09d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -174,7 +174,7 @@
 
 public abstract char[] sourceName();
 
-public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
+public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment environment) {
 	// subclasses must override if they wrap another type binding
 }
 /**
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index b05f94d..f8918d8 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -97,14 +97,6 @@
 	public boolean isTypeVariable() {
 	    return true;
 	}
-	public TypeBinding resolve(LookupEnvironment environment) {
-		// resolve all bounds
-		this.superclass = (ReferenceBinding)BinaryTypeBinding.resolveType(this.superclass, environment, null, 0);
-		for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-			this.superInterfaces[i] = (ReferenceBinding)BinaryTypeBinding.resolveType(this.superInterfaces[i], environment, null, 0);
-		}
-		return this;
-	}
 	public ReferenceBinding superclass() {
 		return superclass;
 	}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
index 08a2311..5f83aa4 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
@@ -35,25 +35,29 @@
 public String debugName() {
 	return toString();
 }
-ReferenceBinding resolve(LookupEnvironment environment, ParameterizedTypeBinding parameterizedType, int rank) {
-	if (this.resolvedType != null) return this.resolvedType;
-
-	ReferenceBinding environmentType = this.fPackage.getType0(this.compoundName[this.compoundName.length - 1]);
-	if (environmentType == this)
-		environmentType = environment.askForType(this.compoundName);
-	if (environmentType != null && environmentType != this) { // could not resolve any better, error was already reported against it
-		this.resolvedType = environmentType;
-		// must ensure to update any other type bindings that can contain the resolved type
-		// otherwise we could create 2 : 1 for this unresolved type & 1 for the resolved type
-		if (this.wrappers != null)
-			for (int i = 0, l = this.wrappers.length; i < l; i++)
-				this.wrappers[i].swapUnresolved(this, environmentType);
-		environment.updateCaches(this, environmentType);
-		return environmentType; // when found, it replaces the unresolved type in the cache
+ReferenceBinding resolve(LookupEnvironment environment, boolean rawCheck, ParameterizedTypeBinding parameterizedType, int rank) {
+    ReferenceBinding targetType;
+	if ((targetType = this.resolvedType) == null) {
+		targetType = this.fPackage.getType0(this.compoundName[this.compoundName.length - 1]);
+		if (targetType == this)
+			targetType = environment.askForType(this.compoundName);
+		if (targetType != null && targetType != this) { // could not resolve any better, error was already reported against it
+			this.resolvedType = targetType;
+			// must ensure to update any other type bindings that can contain the resolved type
+			// otherwise we could create 2 : 1 for this unresolved type & 1 for the resolved type
+			if (this.wrappers != null)
+				for (int i = 0, l = this.wrappers.length; i < l; i++)
+					this.wrappers[i].swapUnresolved(this, targetType, environment);
+			environment.updateCaches(this, targetType);
+		} else {
+			environment.problemReporter.isClassPathCorrect(this.compoundName, null);
+			return null; // will not get here since the above error aborts the compilation
+		}
 	}
-
-	environment.problemReporter.isClassPathCorrect(this.compoundName, null);
-	return null; // will not get here since the above error aborts the compilation
+	if (rawCheck && parameterizedType == null && targetType.isGenericType()) { // raw reference to generic ?
+	    return environment.createRawType(targetType);
+	}
+	return targetType;
 }
 public String toString() {
 	return "Unresolved type " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index 996e196..1680fd6 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -140,7 +140,7 @@
 	    switch(this.kind) {
 	        case Wildcard.EXTENDS :
 	        case Wildcard.SUPER :
-				BinaryTypeBinding.resolveType(this.bound, this.environment, null, 0);
+				BinaryTypeBinding.resolveType(this.bound, this.environment, true, null, 0);
 				break;
 			case Wildcard.UNBOUND :
 				if (this.bound == null) {
@@ -223,9 +223,9 @@
         return this.superInterfaces;
     }
 
-	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
+	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
 		if (this.bound == unresolvedType) {
-			this.bound = resolvedType;
+			this.bound = resolvedType.isGenericType() ? env.createRawType(resolvedType) : resolvedType;
 			initialize(this.bound);
 		}
 	}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index eab743a..36f4da8 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -3295,6 +3295,16 @@
 		statement.sourceStart,
 		statement.sourceEnd);
 }
+// can only occur inside binaries
+public void undefinedTypeVariableSignature(char[] variableName, ReferenceBinding binaryType) {
+	this.handle(
+		IProblem.UndefinedTypeVariable,
+		new String[] {new String(variableName), new String(binaryType.readableName()) },	
+		new String[] {new String(variableName), new String(binaryType.shortReadableName())},
+		AbortCompilation | Error,
+		0,
+		1);
+}
 public void undocumentedEmptyBlock(int blockStart, int blockEnd) {
 	this.handle(
 		IProblem.UndocumentedEmptyBlock,
diff --git a/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 37a08a3..7787be8 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -400,6 +400,7 @@
 536 = Unsafe type operation: Should not assign expression of type {0} to the field {1} of raw type {2}. References to generic type {3} should be parameterized
 537 = Cannot instantiate the generic type {0} using wildcard arguments ({1})
 538 = The type parameter {0} for the type {1} should not be bounded by the final type {2}. Final types cannot be further extended
+539 = Inconsistent classfile encountered: The undefined type parameter {0} is referenced from within {1}
 
 ### FOREACH
 550 = Type mismatch: cannot convert from element type {0} to {1}