diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog
index f050fc9d36c..81200878806 100644
--- a/core/org.eclipse.cdt.core/ChangeLog
+++ b/core/org.eclipse.cdt.core/ChangeLog
@@ -1,3 +1,12 @@
+2004-08-25 Chris Wiebe
+
+	support for matching enclosed type names
+	* browser/org/eclipse/cdt/browser/AllTypesCache.java
+	* browser/org/eclipse/cdt/browser/IQualifiedTypeName.java
+	* browser/org/eclipse/cdt/browser/QualifiedTypeName.java
+	* browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
+	* browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
+
 2004-08-25 Chris Wiebe
 
 	add namespace validation to CConventions
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java
index 6e97b173ead..99d5e49b1a5 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java
@@ -182,19 +182,27 @@ public class AllTypesCache {
 	 * @param qualifiedName The qualified type name
 	 * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS,
 	 *              C_UNION, C_ENUMERATION, C_TYPEDEF
+	 * @param matchEnclosed <code>true</code> if enclosed types count as matches (foo::bar == bar)
 	 */
-	public static ITypeInfo[] getTypes(ITypeSearchScope scope, IQualifiedTypeName qualifiedName, int[] kinds) {
+	public static ITypeInfo[] getTypes(ITypeSearchScope scope, IQualifiedTypeName qualifiedName, int[] kinds, boolean matchEnclosed) {
 		final Collection fTypesFound = new ArrayList();
 		final ITypeSearchScope fScope = scope;
 		final int[] fKinds = kinds;
 		final IQualifiedTypeName fQualifiedName = qualifiedName;
+		final boolean fMatchEnclosed = matchEnclosed;
 		IProject[] projects = scope.getEnclosingProjects();
 		ITypeInfoVisitor visitor = new ITypeInfoVisitor() {
 			public boolean visit(ITypeInfo info) {
 				if (ArrayUtil.contains(fKinds, info.getCElementType())
-						&& fQualifiedName.equals(info.getQualifiedTypeName())
 						&& (fScope != null && info.isEnclosed(fScope))) {
-					fTypesFound.add(info);
+					IQualifiedTypeName currName = info.getQualifiedTypeName();
+					if (fMatchEnclosed && currName.segmentCount() > fQualifiedName.segmentCount()
+					        && currName.lastSegment().equals(fQualifiedName.lastSegment())) {
+						currName = currName.removeFirstSegments(currName.segmentCount() - fQualifiedName.segmentCount());
+					}
+					if (currName.equals(fQualifiedName)) {
+						fTypesFound.add(info);
+					}
 				}
 				return true;
 			}
@@ -333,12 +341,13 @@ public class AllTypesCache {
 	 * 
 	 * @param project the enclosing project
 	 * @param qualifiedName The qualified type name
+	 * @param matchEnclosed <code>true</code> if enclosed types count as matches (foo::bar == bar)
 	 * @param ignoreCase <code>true</code> if case-insensitive
 	 * @return Array of types
 	 */
-	public static ITypeInfo[] getTypes(IProject project, IQualifiedTypeName qualifiedName, boolean ignoreCase) {
+	public static ITypeInfo[] getTypes(IProject project, IQualifiedTypeName qualifiedName, boolean matchEnclosed, boolean ignoreCase) {
 		ITypeCache cache = TypeCacheManager.getInstance().getCache(project);
-		return cache.getTypes(qualifiedName, ignoreCase);
+		return cache.getTypes(qualifiedName, matchEnclosed, ignoreCase);
 	}
 
 	/**
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java
index 673b5d73be3..4b1e53703a8 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IQualifiedTypeName.java
@@ -16,12 +16,11 @@ public interface IQualifiedTypeName extends Comparable {
 
 	public String getName();
 
+	public String getFullyQualifiedName();
+	public IQualifiedTypeName getEnclosingTypeName();
 	public String[] getEnclosingNames();
 
-	public String getFullyQualifiedName();
-
-	public IQualifiedTypeName getEnclosingTypeName();
-
+	public boolean isQualified();
 	public boolean isEmpty();
 	public boolean isGlobal();
 	
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java
index bd2bee4da2b..136bdd778b0 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java
@@ -97,10 +97,14 @@ public class QualifiedTypeName implements IQualifiedTypeName {
 		return null;
 	}
 
+	public boolean isQualified() {
+		return (fSegments.length > 1);
+	}
+
 	public boolean isEmpty() {
 		return fSegments.length == 0;
 	}
-
+	
 	public boolean isGlobal() {
 		if (fSegments.length <= 1) {
 			return true;
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
index 57927ec3072..d43d0f82e0c 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java
@@ -103,9 +103,11 @@ public interface ITypeCache extends ISchedulingRule {
 	 *  name.  If no types are found, an empty array is returned.
 	 *
 	 * @param qualifiedName the qualified type name to match
+	 * @param matchEnclosed <code>true</code> if enclosed types count as matches (foo::bar == bar)
+	 * @param ignoreCase <code>true</code> if case-insensitive
 	 * @return Array of types
 	 */
-	public ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean ignoreCase);
+	public ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean matchEnclosed, boolean ignoreCase);
 
 	/** Returns first type in the cache which matches the given
 	 *  type and name.  If no type is found, <code>null</code>
diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
index debc0d6e35c..6caa2f9d75a 100644
--- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
+++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
@@ -149,6 +149,10 @@ public class TypeCache implements ITypeCache {
 		public boolean isGlobal() {
 			return true;
 		}
+
+		public boolean isQualified() {
+		    return false;
+		}
 		
 		public int segmentCount() {
 			return 1;
@@ -481,9 +485,9 @@ public class TypeCache implements ITypeCache {
 		return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]);
 	}
 	
-	public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean ignoreCase) {
+	public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName, boolean matchEnclosed, boolean ignoreCase) {
 		Collection results = new ArrayList();
-		if (!ignoreCase) {
+		if (!ignoreCase && !matchEnclosed) {
 			for (int i = 0; i < ITypeInfo.KNOWN_TYPES.length; ++i) {
 				ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, ITypeInfo.KNOWN_TYPES[i]));
 				if (info != null) {
@@ -499,8 +503,24 @@ public class TypeCache implements ITypeCache {
 		    for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) {
 				Map.Entry entry = (Map.Entry) mapIter.next();
 				ITypeInfo info = (ITypeInfo) entry.getValue();
-				if (info.getQualifiedTypeName().compareToIgnoreCase(qualifiedName) == 0) {
-				    results.add(info);
+				IQualifiedTypeName currName = info.getQualifiedTypeName();
+				
+				if (ignoreCase) {
+					if (matchEnclosed && currName.segmentCount() > qualifiedName.segmentCount()
+					        && currName.lastSegment().equalsIgnoreCase(qualifiedName.lastSegment())) {
+						currName = currName.removeFirstSegments(currName.segmentCount() - qualifiedName.segmentCount());
+					}
+					if (currName.equalsIgnoreCase(qualifiedName)) {
+						results.add(info);
+					}
+				} else {
+					if (matchEnclosed && currName.segmentCount() > qualifiedName.segmentCount()
+					        && currName.lastSegment().equals(qualifiedName.lastSegment())) {
+						currName = currName.removeFirstSegments(currName.segmentCount() - qualifiedName.segmentCount());
+					}
+					if (currName.equals(qualifiedName)) {
+						results.add(info);
+					}
 				}
 			}
 		}