]> source.dussan.org Git - aspectj.git/commitdiff
Fix part 1 for pr110307
authoraclement <aclement>
Mon, 17 Oct 2005 13:20:52 +0000 (13:20 +0000)
committeraclement <aclement>
Mon, 17 Oct 2005 13:20:52 +0000 (13:20 +0000)
weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java
weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java
weaver/src/org/aspectj/weaver/ResolvedType.java
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java

index e51e40a149d1006071151e3c8f8aea41a3adfbd7..75faa51940cdb1a1c65bc0863a6c36c49c9eee3b 100644 (file)
@@ -81,5 +81,29 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
 //             ConcreteTypeMunger o = (ConcreteTypeMunger) other;
                return 0;
        }
+       
+       /**
+        * ITDs can be made on generic types and 'share' type variables with
+        * the generic type.  In this case we may need to 'tailor' the munger
+        * for addition to a particulra type.  For eaxmple:
+        *   interface I<T> {}
+        *   
+        *   aspect X implements I<String> {
+        *     List<T> I<T>.foo { return null; }
+        *   }
+        *   
+        * In this case the munger matches X but it matches with the form
+        *   List<String> foo() { return null; }
+        */
+       public boolean isTargetTypeParameterized() {
+               if (munger==null) return false; 
+               return munger.sharesTypeVariablesWithGenericType();
+       }
 
+    /**
+     * For an ITD made on a generic type that shares type variables with
+     * that target type, this method will tailor the ITD for a particular usage
+     * of the generic type - either in its raw or parameterized form.
+     */
+       public abstract ConcreteTypeMunger parameterizedFor(ResolvedType targetType);
 }
index 1e6a286aa3c1bf1e1833ebfecf9b6d1414cc7690..33e43a605964be70f5eda2ae9fbece1e9b92b759 100644 (file)
@@ -64,4 +64,15 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger {
                if (ResolvedType.matches(ret, member)) return getSignature();
                return super.getMatchingSyntheticMember(member, aspectType);
        }
+       
+       /**
+     * ResolvedTypeMunger.parameterizedFor(ResolvedType)
+     */
+       public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
+               ResolvedType genericType = target;
+               if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType();
+               ResolvedMember parameterizedSignature = getSignature().parameterizedWith(target.getTypeParameters(),genericType,target.isParameterizedType());
+               return new NewMethodTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
+       }
+
 }
index 3eacaabe8e8d9aa87facc7a77be510fcf8d6bbd8..ae18931b2f8611a00082cee6c0c9280f1556bfe7 100644 (file)
@@ -7,22 +7,13 @@
  * http://www.eclipse.org/legal/cpl-v10.html 
  *  
  * Contributors: 
- *     PARC     initial implementation
+ *     PARC     initial implementation 
  *     Alexandre Vasseur    @AspectJ ITDs
  * ******************************************************************/
 
 
 package org.aspectj.weaver;
 
-import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.Message;
-import org.aspectj.bridge.MessageUtil;
-import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.bcel.BcelTypeMunger;
-import org.aspectj.weaver.patterns.Declare;
-import org.aspectj.weaver.patterns.PerClause;
-
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -35,22 +26,30 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
-
-    private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
-    public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.patterns.Declare;
+import org.aspectj.weaver.patterns.PerClause;
 
-    private ResolvedType[] resolvedTypeParams;
+public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
 
+       private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY  = new ResolvedType[0];
+       public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
+       
+       private ResolvedType[] resolvedTypeParams;
+       
     protected World world;
-
+           
     protected ResolvedType(String signature, World world) {
         super(signature);
         this.world = world;
     }
-
+        
     protected ResolvedType(String signature, String signatureErasure, World world) {
-        super(signature, signatureErasure);
+        super(signature,signatureErasure);
         this.world = world;
     }
 
@@ -72,29 +71,25 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     }
 
     public abstract ResolvedMember[] getDeclaredFields();
-
     public abstract ResolvedMember[] getDeclaredMethods();
-
     public abstract ResolvedType[] getDeclaredInterfaces();
-
     public abstract ResolvedMember[] getDeclaredPointcuts();
-
     /**
      * Returns a ResolvedType object representing the superclass of this type, or null.
      * If this represents a java.lang.Object, a primitive type, or void, this
-     * method returns null.
+     * method returns null.  
      */
     public abstract ResolvedType getSuperclass();
 
     /**
-     * Returns the modifiers for this type.
+     * Returns the modifiers for this type.  
      * <p/>
      * See {@link Class#getModifiers()} for a description
      * of the weirdness of this methods on primitives and arrays.
      *
      * @param world the {@link World} in which the lookup is made.
      * @return an int representing the modifiers for this type
-     * @see java.lang.reflect.Modifier
+     * @see     java.lang.reflect.Modifier
      */
     public abstract int getModifiers();
 
@@ -102,49 +97,50 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     public boolean isMissing() {
         return false;
     }
-
+    
     public ResolvedType[] getAnnotationTypes() {
-        return EMPTY_RESOLVED_TYPE_ARRAY;
+       return EMPTY_RESOLVED_TYPE_ARRAY;
     }
-
+    
     public final UnresolvedType getSuperclass(World world) {
         return getSuperclass();
     }
 
-
+    
     // This set contains pairs of types whose signatures are concatenated
     // together, this means with a fast lookup we can tell if two types
     // are equivalent.
     static Set validBoxing = new HashSet();
-
+    
     static {
-        validBoxing.add("Ljava/lang/Byte;B");
-        validBoxing.add("Ljava/lang/Character;C");
-        validBoxing.add("Ljava/lang/Double;D");
-        validBoxing.add("Ljava/lang/Float;F");
-        validBoxing.add("Ljava/lang/Integer;I");
-        validBoxing.add("Ljava/lang/Long;J");
-        validBoxing.add("Ljava/lang/Short;S");
-        validBoxing.add("Ljava/lang/Boolean;Z");
-        validBoxing.add("BLjava/lang/Byte;");
-        validBoxing.add("CLjava/lang/Character;");
-        validBoxing.add("DLjava/lang/Double;");
-        validBoxing.add("FLjava/lang/Float;");
-        validBoxing.add("ILjava/lang/Integer;");
-        validBoxing.add("JLjava/lang/Long;");
-        validBoxing.add("SLjava/lang/Short;");
-        validBoxing.add("ZLjava/lang/Boolean;");
-    }
-
-
-    // utilities
+      validBoxing.add("Ljava/lang/Byte;B");
+      validBoxing.add("Ljava/lang/Character;C");
+      validBoxing.add("Ljava/lang/Double;D");
+      validBoxing.add("Ljava/lang/Float;F");
+      validBoxing.add("Ljava/lang/Integer;I");
+      validBoxing.add("Ljava/lang/Long;J");
+      validBoxing.add("Ljava/lang/Short;S");
+      validBoxing.add("Ljava/lang/Boolean;Z");
+      validBoxing.add("BLjava/lang/Byte;");
+      validBoxing.add("CLjava/lang/Character;");
+      validBoxing.add("DLjava/lang/Double;");
+      validBoxing.add("FLjava/lang/Float;");
+      validBoxing.add("ILjava/lang/Integer;");
+      validBoxing.add("JLjava/lang/Long;");
+      validBoxing.add("SLjava/lang/Short;");
+      validBoxing.add("ZLjava/lang/Boolean;");
+    }
+    
+
+
+    // utilities                
     public ResolvedType getResolvedComponentType() {
-        return null;
+       return null;
     }
 
-    public World getWorld() {
-        return world;
-    }
+       public World getWorld() {
+               return world;
+       }
 
     // ---- things from object
 
@@ -155,16 +151,16 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
             return super.equals(other);
         }
     }
-
     // ---- difficult things
-
+    
     /**
      * returns an iterator through all of the fields of this type, in order
      * for checking from JVM spec 2ed 5.4.3.2.  This means that the order is
      * <p/>
      * <ul><li> fields from current class </li>
-     * <li> recur into direct superinterfaces </li>
-     * <li> recur into superclass </li>
+     *     <li> recur into direct superinterfaces </li>
+     *     <li> recur into superclass </li>
      * </ul>
      * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
@@ -174,20 +170,20 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return
-                        dupFilter.filter(
-                                ((ResolvedType) o).getDirectSupertypes());
+                return 
+                    dupFilter.filter(
+                        ((ResolvedType)o).getDirectSupertypes());
             }
         };
         Iterators.Getter fieldGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return Iterators.array(((ResolvedType) o).getDeclaredFields());
+                return Iterators.array(((ResolvedType)o).getDeclaredFields());
             }
         };
-        return
-                Iterators.mapOver(
-                        Iterators.recur(this, typeGetter),
-                        fieldGetter);
+        return 
+            Iterators.mapOver(
+                Iterators.recur(this, typeGetter),
+                fieldGetter);
     }
 
     /**
@@ -195,8 +191,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      * for checking from JVM spec 2ed 5.4.3.3.  This means that the order is
      * <p/>
      * <ul><li> methods from current class </li>
-     * <li> recur into superclass, all the way up, not touching interfaces </li>
-     * <li> recur into all superinterfaces, in some unspecified order </li>
+     *     <li> recur into superclass, all the way up, not touching interfaces </li>
+     *     <li> recur into all superinterfaces, in some unspecified order </li>
      * </ul>
      * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
@@ -208,41 +204,38 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter ifaceGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return
-                        dupFilter.filter(
-                                Iterators.array(((ResolvedType) o).getDeclaredInterfaces())
-                        );
+                return 
+                    dupFilter.filter(
+                        Iterators.array(((ResolvedType)o).getDeclaredInterfaces())
+                        );                       
             }
         };
         Iterators.Getter methodGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return Iterators.array(((ResolvedType) o).getDeclaredMethods());
+                return Iterators.array(((ResolvedType)o).getDeclaredMethods());
             }
         };
-        return
-                Iterators.mapOver(
-                        Iterators.append(
-                                new Iterator() {
-                                    ResolvedType curr = ResolvedType.this;
-
-                                    public boolean hasNext() {
-                                        return curr != null;
-                                    }
-
-                                    public Object next() {
-                                        ResolvedType ret = curr;
-                                        curr = curr.getSuperclass();
-                                        return ret;
-                                    }
-
-                                    public void remove() {
-                                        throw new UnsupportedOperationException();
-                                    }
-                                },
-                                Iterators.recur(this, ifaceGetter)),
-                        methodGetter);
+        return 
+            Iterators.mapOver(
+                Iterators.append(
+                    new Iterator() {
+                        ResolvedType curr = ResolvedType.this;
+                        public boolean hasNext() {
+                            return curr != null;
+                        }
+                        public Object next() {
+                            ResolvedType ret = curr;
+                            curr = curr.getSuperclass();
+                            return ret;
+                        }
+                        public void remove() {
+                            throw new UnsupportedOperationException();
+                        }
+                    },
+                    Iterators.recur(this, ifaceGetter)),
+                methodGetter);
     }
-
+    
     /**
      * Return a list of methods, first those declared on this class, then those declared on the superclass (recurse) and then those declared
      * on the superinterfaces.  The getMethods() call above doesn't quite work the same as it will (through the iterator) return methods
@@ -251,31 +244,31 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing) {
         List methods = new ArrayList();
         Set knowninterfaces = new HashSet();
-        addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing);
+        addAndRecurse(knowninterfaces,methods,this,includeITDs,allowMissing);
         return methods;
     }
-
-    private void addAndRecurse(Set knowninterfaces, List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) {
-        collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type
-        // now add all the inter-typed members too
-        if (includeITDs && rtx.interTypeMungers != null) {
-            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
-                ResolvedMember rm = tm.getSignature();
-                if (rm != null) {  // new parent type munger can have null signature...
-                    collector.add(tm.getSignature());
-                }
-            }
-        }
-        if (!rtx.equals(ResolvedType.OBJECT)) {
-            ResolvedType superType = rtx.getSuperclass();
-            if (superType != null && !superType.isMissing()) {
-                addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing); // Recurse if we aren't at the top
-            }
-        }
-        ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down
-        for (int i = 0; i < interfaces.length; i++) {
-            ResolvedType iface = interfaces[i];
+    
+    private void addAndRecurse(Set knowninterfaces,List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) {
+      collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type
+      // now add all the inter-typed members too
+      if (includeITDs && rtx.interTypeMungers != null) {
+         for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();  
+                               ResolvedMember rm = tm.getSignature();
+                               if (rm != null) {  // new parent type munger can have null signature...
+                                       collector.add(tm.getSignature());
+                               } 
+                       }
+      }
+      if (!rtx.equals(ResolvedType.OBJECT)) {
+         ResolvedType superType = rtx.getSuperclass();
+         if (superType != null && !superType.isMissing()) {
+                 addAndRecurse(knowninterfaces,collector,superType,includeITDs,allowMissing); // Recurse if we aren't at the top
+         }
+      }
+      ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down
+      for (int i = 0; i < interfaces.length; i++) {
+               ResolvedType iface = interfaces[i];
 
             // we need to know if it is an interface from Parent kind munger
             // as those are used for @AJ ITD and we precisely want to skip those
@@ -289,26 +282,26 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
             }
 
             if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do interfaces more than once
-                knowninterfaces.add(iface);
-                if (allowMissing && iface.isMissing()) {
-                    if (iface instanceof MissingResolvedTypeWithKnownSignature) {
-                        ((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
-                    }
-                } else {
-                    addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing);
-                }
-            }
+          knowninterfaces.add(iface); 
+          if (allowMissing && iface.isMissing()) {
+               if (iface instanceof MissingResolvedTypeWithKnownSignature) {
+                       ((MissingResolvedTypeWithKnownSignature)iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
+               }
+          } else {
+                 addAndRecurse(knowninterfaces,collector,iface,includeITDs,allowMissing);
+          }
         }
+         }
     }
 
     public ResolvedType[] getResolvedTypeParameters() {
-        if (resolvedTypeParams == null) {
-            resolvedTypeParams = world.resolve(typeParameters);
-        }
-        return resolvedTypeParams;
+       if (resolvedTypeParams == null) {
+               resolvedTypeParams = world.resolve(typeParameters);
+       }
+       return resolvedTypeParams;
     }
-
-    /**
+    
+    /** 
      * described in JVM spec 2ed 5.4.3.2
      */
     public ResolvedMember lookupField(Member m) {
@@ -322,19 +315,19 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     public ResolvedMember lookupMethod(Member m) {
         return lookupMember(m, getMethods());
     }
-
+    
     public ResolvedMember lookupMethodInITDs(Member m) {
-        if (interTypeMungers != null) {
-            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
-                if (matches(tm.getSignature(), m)) {
-                    return tm.getSignature();
-                }
-            }
-        }
-        return null;
-    }
-
+       if (interTypeMungers != null) {
+                       for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
+                               if (matches(tm.getSignature(), m)) {
+                                       return tm.getSignature();
+                               }
+                       }
+               }
+       return null;
+    }
+    
     /**
      * return null if not found
      */
@@ -345,55 +338,55 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         }
         return null; //ResolvedMember.Missing;
         //throw new BCException("can't find " + m);
-    }
-
+    }  
+    
     /**
      * return null if not found
      */
     private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
-        for (int i = 0; i < a.length; i++) {
-            ResolvedMember f = a[i];
-            if (matches(f, m)) return f;
-        }
-        return null;
-    }
-
-
+               for (int i = 0; i < a.length; i++) {
+                       ResolvedMember f = a[i];
+            if (matches(f, m)) return f;       
+               }
+               return null;
+    }      
+    
+    
     /**
      * Looks for the first member in the hierarchy matching aMember. This method
      * differs from lookupMember(Member) in that it takes into account parameters
      * which are type variables - which clearly an unresolved Member cannot do since
-     * it does not know anything about type variables.
+     * it does not know anything about type variables. 
      */
-    public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing) {
-        Iterator toSearch = null;
-        ResolvedMember found = null;
-        if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
-            toSearch = getMethodsWithoutIterator(true, allowMissing).iterator();
-        } else {
-            if (aMember.getKind() != Member.FIELD)
-                throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind());
-            toSearch = getFields();
-        }
-        while (toSearch.hasNext()) {
-            ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();
-            if (candidate.matches(aMember)) {
-                found = candidate;
-                break;
-            }
-        }
-
-        return found;
-    }
-
+     public ResolvedMember lookupResolvedMember(ResolvedMember aMember,boolean allowMissing) {
+       Iterator toSearch = null;
+       ResolvedMember found = null;
+       if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
+               toSearch = getMethodsWithoutIterator(true,allowMissing).iterator();
+       } else {
+               if (aMember.getKind() != Member.FIELD) 
+                       throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind());
+               toSearch = getFields();
+       }
+       while(toSearch.hasNext()) {
+                       ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();                    
+                       if (candidate.matches(aMember)) {
+                               found = candidate;
+                               break;
+                       } 
+               }
+       
+       return found;
+    }
+    
     public static boolean matches(Member m1, Member m2) {
         if (m1 == null) return m2 == null;
         if (m2 == null) return false;
-
+        
         // Check the names
         boolean equalNames = m1.getName().equals(m2.getName());
         if (!equalNames) return false;
-
+        
         // Check the signatures
         boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
         if (equalSignatures) return true;
@@ -402,45 +395,45 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         // the subsig might be ()LFastCar; - where FastCar is a subclass of Car
         boolean equalCovariantSignatures = m1.getParameterSignature().equals(m2.getParameterSignature());
         if (equalCovariantSignatures) return true;
-
+        
         return false;
     }
-
+    
     public static boolean conflictingSignature(Member m1, Member m2) {
-        if (m1 == null || m2 == null) return false;
-
+       if (m1 == null || m2 == null) return false;
+       
         if (!m1.getName().equals(m2.getName())) {
             return false;
         }
         if (m1.getKind() != m2.getKind()) {
             return false;
         }
-
-        if (m1.getKind() == Member.FIELD) {
-            return m1.getDeclaringType().equals(m2.getDeclaringType());
-        } else if (m1.getKind() == Member.POINTCUT) {
-            return true;
-        }
-
-        UnresolvedType[] p1 = m1.getParameterTypes();
-        UnresolvedType[] p2 = m2.getParameterTypes();
-        int n = p1.length;
-        if (n != p2.length) return false;
-
-        for (int i = 0; i < n; i++) {
-            if (!p1[i].equals(p2[i])) return false;
-        }
-        return true;
-    }
-
-
+       
+       if (m1.getKind() == Member.FIELD) {
+               return m1.getDeclaringType().equals(m2.getDeclaringType());
+       } else if (m1.getKind() == Member.POINTCUT) {
+               return true;
+       }
+       
+       UnresolvedType[] p1 = m1.getParameterTypes();
+       UnresolvedType[] p2 = m2.getParameterTypes();
+       int n = p1.length;
+       if (n != p2.length) return false;
+       
+       for (int i=0; i < n; i++) {
+               if (!p1[i].equals(p2[i])) return false;
+       }
+       return true;
+    }
+    
+    
     /**
      * returns an iterator through all of the pointcuts of this type, in order
      * for checking from JVM spec 2ed 5.4.3.2 (as for fields).  This means that the order is
      * <p/>
      * <ul><li> pointcuts from current class </li>
-     * <li> recur into direct superinterfaces </li>
-     * <li> recur into superclass </li>
+     *     <li> recur into direct superinterfaces </li>
+     *     <li> recur into superclass </li>
      * </ul>
      * <p/>
      * We keep a hashSet of interfaces that we've visited so we don't spiral
@@ -451,26 +444,26 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         // same order as fields
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return
-                        dupFilter.filter(
-                                ((ResolvedType) o).getDirectSupertypes());
+                return 
+                    dupFilter.filter(
+                        ((ResolvedType)o).getDirectSupertypes());
             }
         };
         Iterators.Getter pointcutGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
                 //System.err.println("getting for " + o);
-                return Iterators.array(((ResolvedType) o).getDeclaredPointcuts());
+                return Iterators.array(((ResolvedType)o).getDeclaredPointcuts());
             }
         };
-        return
-                Iterators.mapOver(
-                        Iterators.recur(this, typeGetter),
-                        pointcutGetter);
+        return 
+            Iterators.mapOver(
+                Iterators.recur(this, typeGetter),
+                pointcutGetter);
     }
-
+    
     public ResolvedPointcutDefinition findPointcut(String name) {
         //System.err.println("looking for pointcuts " + this);
-        for (Iterator i = getPointcuts(); i.hasNext();) {
+        for (Iterator i = getPointcuts(); i.hasNext(); ) {
             ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next();
             //System.err.println(f);
             if (name.equals(f.getName())) {
@@ -479,320 +472,316 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         }
         return null; // should we throw an exception here?
     }
-
+    
+    
     // all about collecting CrosscuttingMembers
 
-    //??? collecting data-structure, shouldn't really be a field
+       //??? collecting data-structure, shouldn't really be a field
     public CrosscuttingMembers crosscuttingMembers;
 
-    public CrosscuttingMembers collectCrosscuttingMembers() {
-        crosscuttingMembers = new CrosscuttingMembers(this);
-        crosscuttingMembers.setPerClause(getPerClause());
-        crosscuttingMembers.addShadowMungers(collectShadowMungers());
-        crosscuttingMembers.addTypeMungers(getTypeMungers());
+       public CrosscuttingMembers collectCrosscuttingMembers() {
+               crosscuttingMembers = new CrosscuttingMembers(this);
+               crosscuttingMembers.setPerClause(getPerClause());
+               crosscuttingMembers.addShadowMungers(collectShadowMungers());
+               crosscuttingMembers.addTypeMungers(getTypeMungers());
         //FIXME AV - skip but needed ?? or  ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
-        crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
-        crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
-
-        //System.err.println("collected cc members: " + this + ", " + collectDeclares());
-        return crosscuttingMembers;
-    }
-
-    public final Collection collectDeclares(boolean includeAdviceLike) {
-        if (! this.isAspect()) return Collections.EMPTY_LIST;
-
-        ArrayList ret = new ArrayList();
-        //if (this.isAbstract()) {
+               crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
+               crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
+               
+               //System.err.println("collected cc members: " + this + ", " + collectDeclares());
+               return crosscuttingMembers;
+       }
+       
+       public final Collection collectDeclares(boolean includeAdviceLike) {
+               if (! this.isAspect() ) return Collections.EMPTY_LIST;
+               
+               ArrayList ret = new ArrayList();
+               //if (this.isAbstract()) {
 //             for (Iterator i = getDeclares().iterator(); i.hasNext();) {
 //                     Declare dec = (Declare) i.next();
 //                     if (!dec.isAdviceLike()) ret.add(dec);
 //             }
 //        
 //        if (!includeAdviceLike) return ret;
-
-        if (!this.isAbstract()) {
-            //ret.addAll(getDeclares());
-            final Iterators.Filter dupFilter = Iterators.dupFilter();
-            Iterators.Getter typeGetter = new Iterators.Getter() {
-                public Iterator get(Object o) {
-                    return
-                            dupFilter.filter(
-                                    ((ResolvedType) o).getDirectSupertypes());
-                }
-            };
-            Iterator typeIterator = Iterators.recur(this, typeGetter);
-
-            while (typeIterator.hasNext()) {
-                ResolvedType ty = (ResolvedType) typeIterator.next();
-                //System.out.println("super: " + ty + ", " + );
-                for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
-                    Declare dec = (Declare) i.next();
-                    if (dec.isAdviceLike()) {
-                        if (includeAdviceLike) ret.add(dec);
-                    } else {
-                        ret.add(dec);
-                    }
-                }
-            }
-        }
-
-        return ret;
-    }
-
-
+        
+               if (!this.isAbstract()) {
+                       //ret.addAll(getDeclares());
+                       final Iterators.Filter dupFilter = Iterators.dupFilter();
+               Iterators.Getter typeGetter = new Iterators.Getter() {
+                   public Iterator get(Object o) {
+                       return 
+                           dupFilter.filter(
+                               ((ResolvedType)o).getDirectSupertypes());
+                   }
+               };
+               Iterator typeIterator = Iterators.recur(this, typeGetter);
+       
+               while (typeIterator.hasNext()) {
+                       ResolvedType ty = (ResolvedType) typeIterator.next();
+                       //System.out.println("super: " + ty + ", " + );
+                       for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
+                                       Declare dec = (Declare) i.next();
+                                       if (dec.isAdviceLike()) {
+                                               if (includeAdviceLike) ret.add(dec);
+                                       } else {
+                                               ret.add(dec);
+                                       }
+                               }
+               }
+               }
+               
+               return ret;
+    }
+    
+       
+       
+       
     private final Collection collectShadowMungers() {
         if (! this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST;
 
-        ArrayList acc = new ArrayList();
+               ArrayList acc = new ArrayList();
         final Iterators.Filter dupFilter = Iterators.dupFilter();
         Iterators.Getter typeGetter = new Iterators.Getter() {
             public Iterator get(Object o) {
-                return
-                        dupFilter.filter(
-                                ((ResolvedType) o).getDirectSupertypes());
+                return 
+                    dupFilter.filter(
+                        ((ResolvedType)o).getDirectSupertypes());
             }
         };
         Iterator typeIterator = Iterators.recur(this, typeGetter);
 
         while (typeIterator.hasNext()) {
             ResolvedType ty = (ResolvedType) typeIterator.next();
-            acc.addAll(ty.getDeclaredShadowMungers());
+            acc.addAll(ty.getDeclaredShadowMungers());     
         }
-
+        
         return acc;
     }
-
-    protected boolean doesNotExposeShadowMungers() {
-        return false;
-    }
+    
+       protected boolean doesNotExposeShadowMungers() {
+               return false;
+       }
 
     public PerClause getPerClause() {
         return null;
     }
 
-    protected Collection getDeclares() {
-        return Collections.EMPTY_LIST;
-    }
-
+       protected Collection getDeclares() {
+               return Collections.EMPTY_LIST; 
+       }
+       
     protected Collection getTypeMungers() {
         return Collections.EMPTY_LIST;
     }
-
+       
     protected Collection getPrivilegedAccesses() {
         return Collections.EMPTY_LIST;
     }
+       
 
     // ---- useful things
-
-    public final boolean isInterface() {
+    
+    public final boolean isInterface() {       
         return Modifier.isInterface(getModifiers());
     }
-
-    public final boolean isAbstract() {
+    
+    public final boolean isAbstract() {       
         return Modifier.isAbstract(getModifiers());
     }
-
+    
     public boolean isClass() {
-        return false;
+       return false;
     }
-
+    
     public boolean isAspect() {
-        return false;
+       return false;
     }
 
     public boolean isAnnotationStyleAspect() {
-        return false;
+       return false;
     }
 
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isEnum() {
-        return false;
+       return false;
     }
-
+    
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isAnnotation() {
-        return false;
+       return false;
     }
-
-    /**
-     * Note: Only overridden by Name subtype
-     */
-    public void addAnnotation(AnnotationX annotationX) {
-        throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
-    }
-
+    
     /**
      * Note: Only overridden by Name subtype
      */
-    public AnnotationX[] getAnnotations() {
-        throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
-    }
-
-
+       public void addAnnotation(AnnotationX annotationX) {
+               throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
+       }
+       
+       /**
+        * Note: Only overridden by Name subtype
+        */
+       public AnnotationX[] getAnnotations() {
+               throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
+       }
+
+    
     /**
      * Note: Only overridden by Name subtype.
      */
     public boolean isAnnotationWithRuntimeRetention() {
         return false;
     }
-
+    
     public boolean isSynthetic() {
-        return signature.indexOf("$ajc") != -1;
+       return signature.indexOf("$ajc") != -1;
     }
-
+    
     public final boolean isFinal() {
         return Modifier.isFinal(getModifiers());
     }
 
-    protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
-        if (!isParameterizedType()) return Collections.EMPTY_MAP;
-        TypeVariable[] tvs = getGenericType().getTypeVariables();
-        Map parameterizationMap = new HashMap();
-        for (int i = 0; i < tvs.length; i++) {
-            parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
-        }
-        return parameterizationMap;
-    }
+       protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
+               if (!isParameterizedType()) return Collections.EMPTY_MAP;
+               TypeVariable[] tvs = getGenericType().getTypeVariables();
+               Map parameterizationMap = new HashMap();
+               for (int i = 0; i < tvs.length; i++) {
+                       parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
+               }
+               return parameterizationMap;
+       }
+
+       
+       public Collection getDeclaredAdvice() {
+               List l = new ArrayList();
+               ResolvedMember[] methods = getDeclaredMethods();
+               if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
+               Map typeVariableMap = getMemberParameterizationMap();
+               for (int i=0, len = methods.length; i < len; i++) {
+                       ShadowMunger munger = methods[i].getAssociatedShadowMunger();
+                       if (munger != null) {
+                               if (this.isParameterizedType()) {
+                                       //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
+                                       munger = munger.parameterizeWith(typeVariableMap);
+                                       if (munger instanceof Advice) {
+                                               Advice advice = (Advice) munger;
+                                               // update to use the parameterized signature...
+                                               UnresolvedType[] ptypes = methods[i].getGenericParameterTypes() ;
+                                               UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
+                                               for (int j = 0; j < ptypes.length; j++) {
+                                                       if (ptypes[j] instanceof TypeVariableReferenceType) {
+                                                               TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
+                                                               if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
+                                                                       newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName());
+                                                               } else {
+                                                                       newPTypes[j] = ptypes[j];
+                                                               }
+                                                       } else {
+                                                               newPTypes[j] = ptypes[j];
+                                                       }
+                                               }
+                                               advice.setBindingParameterTypes(newPTypes);
+                                       }
+                               }
+                               munger.setDeclaringType(this);
+                               l.add(munger);
+                       }
+               }
+               return l;
+       }
+       
+       public Collection getDeclaredShadowMungers() {
+               Collection c = getDeclaredAdvice();
+               return c;
+       }
+       
+       // ---- only for testing!
+
+
+       public ResolvedMember[] getDeclaredJavaFields() {
+               return filterInJavaVisible(getDeclaredFields());
+       }
+       public ResolvedMember[] getDeclaredJavaMethods() {
+               return filterInJavaVisible(getDeclaredMethods());
+       }
+       public ShadowMunger[] getDeclaredShadowMungersArray() {
+               List l = (List) getDeclaredShadowMungers();
+               return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
+       }
+       private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
+               List l = new ArrayList();
+               for (int i=0, len = ms.length; i < len; i++) {
+                       if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
+                               l.add(ms[i]);
+                       }
+               }
+               return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
+       }
+       
+       public abstract ISourceContext getSourceContext();
 
 
-    public Collection getDeclaredAdvice() {
-        List l = new ArrayList();
-        ResolvedMember[] methods = getDeclaredMethods();
-        if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
-        Map typeVariableMap = getMemberParameterizationMap();
-        for (int i = 0, len = methods.length; i < len; i++) {
-            ShadowMunger munger = methods[i].getAssociatedShadowMunger();
-            if (munger != null) {
-                if (this.isParameterizedType()) {
-                    //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
-                    munger = munger.parameterizeWith(typeVariableMap);
-                    if (munger instanceof Advice) {
-                        Advice advice = (Advice) munger;
-                        // update to use the parameterized signature...
-                        UnresolvedType[] ptypes = methods[i].getGenericParameterTypes();
-                        UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
-                        for (int j = 0; j < ptypes.length; j++) {
-                            if (ptypes[j] instanceof TypeVariableReferenceType) {
-                                TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
-                                if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
-                                    newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName());
-                                } else {
-                                    newPTypes[j] = ptypes[j];
-                                }
-                            } else {
-                                newPTypes[j] = ptypes[j];
-                            }
-                        }
-                        advice.setBindingParameterTypes(newPTypes);
-                    }
-                }
-                munger.setDeclaringType(this);
-                l.add(munger);
-            }
-        }
-        return l;
-    }
-
-    public Collection getDeclaredShadowMungers() {
-        Collection c = getDeclaredAdvice();
-        return c;
-    }
-
-    // ---- only for testing!
-
-
-    public ResolvedMember[] getDeclaredJavaFields() {
-        return filterInJavaVisible(getDeclaredFields());
-    }
-
-    public ResolvedMember[] getDeclaredJavaMethods() {
-        return filterInJavaVisible(getDeclaredMethods());
-    }
-
-    public ShadowMunger[] getDeclaredShadowMungersArray() {
-        List l = (List) getDeclaredShadowMungers();
-        return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
-    }
-
-    private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
-        List l = new ArrayList();
-        for (int i = 0, len = ms.length; i < len; i++) {
-            if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
-                l.add(ms[i]);
-            }
-        }
-        return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
-    }
-
-    public abstract ISourceContext getSourceContext();
-
     // ---- fields
-
+    
     public static final ResolvedType[] NONE = new ResolvedType[0];
 
-    public static final Primitive BYTE = new Primitive("B", 1, 0);
-    public static final Primitive CHAR = new Primitive("C", 1, 1);
-    public static final Primitive DOUBLE = new Primitive("D", 2, 2);
-    public static final Primitive FLOAT = new Primitive("F", 1, 3);
-    public static final Primitive INT = new Primitive("I", 1, 4);
-    public static final Primitive LONG = new Primitive("J", 2, 5);
-    public static final Primitive SHORT = new Primitive("S", 1, 6);
-    public static final Primitive VOID = new Primitive("V", 0, 8);
+    public static final Primitive BYTE    = new Primitive("B", 1, 0);
+    public static final Primitive CHAR    = new Primitive("C", 1, 1);
+    public static final Primitive DOUBLE  = new Primitive("D", 2, 2);
+    public static final Primitive FLOAT   = new Primitive("F", 1, 3);
+    public static final Primitive INT     = new Primitive("I", 1, 4);
+    public static final Primitive LONG    = new Primitive("J", 2, 5);
+    public static final Primitive SHORT   = new Primitive("S", 1, 6);
+    public static final Primitive VOID    = new Primitive("V", 0, 8);
     public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
-    public static final Missing MISSING = new Missing();
-
+    public static final Missing   MISSING = new Missing();
+    
     // ---- types
     public static ResolvedType makeArray(ResolvedType type, int dim) {
-        if (dim == 0) return type;
-        ResolvedType array = new Array("[" + type.getSignature(), type.getWorld(), type);
-        return makeArray(array, dim - 1);
+       if (dim == 0) return type;
+       ResolvedType array = new Array("[" + type.getSignature(),type.getWorld(),type);
+       return makeArray(array,dim-1);
     }
-
+    
     static class Array extends ResolvedType {
         ResolvedType componentType;
-
         Array(String s, World world, ResolvedType componentType) {
             super(s, world);
             this.componentType = componentType;
         }
-
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedMember[] getDeclaredMethods() {
             // ??? should this return clone?  Probably not...
             // If it ever does, here is the code:
             //  ResolvedMember cloneMethod =
             //    new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,UnresolvedType.OBJECT,"clone",new UnresolvedType[]{});
             //  return new ResolvedMember[]{cloneMethod};
-            return ResolvedMember.NONE;
+               return ResolvedMember.NONE;
         }
-
         public final ResolvedType[] getDeclaredInterfaces() {
             return
-                    new ResolvedType[]{
-                            world.getCoreType(CLONEABLE),
-                            world.getCoreType(SERIALIZABLE)
-                    };
+                new ResolvedType[] {
+                    world.getCoreType(CLONEABLE), 
+                    world.getCoreType(SERIALIZABLE)
+                };
         }
-
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
-
+        
         public boolean hasAnnotation(UnresolvedType ofType) {
-            return false;
+               return false;
         }
-
+        
         public final ResolvedType getSuperclass() {
             return world.getCoreType(OBJECT);
         }
-
         public final boolean isAssignableFrom(ResolvedType o) {
             if (! o.isArray()) return false;
             if (o.getComponentType().isPrimitiveType()) {
@@ -801,13 +790,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                 return getComponentType().resolve(world).isAssignableFrom(o.getComponentType().resolve(world));
             }
         }
-
+        
         public boolean isAssignableFrom(ResolvedType o, boolean allowMissing) {
-            return isAssignableFrom(o);
+               return isAssignableFrom(o);
         }
-
+        
         public final boolean isCoerceableFrom(ResolvedType o) {
-            if (o.equals(UnresolvedType.OBJECT) ||
+            if (o.equals(UnresolvedType.OBJECT) || 
                     o.equals(UnresolvedType.SERIALIZABLE) ||
                     o.equals(UnresolvedType.CLONEABLE)) {
                 return true;
@@ -819,119 +808,101 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                 return getComponentType().resolve(world).isCoerceableFrom(o.getComponentType().resolve(world));
             }
         }
-
         public final int getModifiers() {
             int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
             return (componentType.getModifiers() & mask) | Modifier.FINAL;
         }
-
         public UnresolvedType getComponentType() {
             return componentType;
         }
-
         public ResolvedType getResolvedComponentType() {
             return componentType;
         }
-
         public ISourceContext getSourceContext() {
-            return getResolvedComponentType().getSourceContext();
+               return getResolvedComponentType().getSourceContext();
         }
     }
-
+    
     static class Primitive extends ResolvedType {
         private int size;
         private int index;
-
         Primitive(String signature, int size, int index) {
             super(signature, null);
             this.size = size;
             this.index = index;
         }
-
         public final int getSize() {
             return size;
         }
-
         public final int getModifiers() {
             return Modifier.PUBLIC | Modifier.FINAL;
         }
-
         public final boolean isPrimitiveType() {
             return true;
         }
-
         public boolean hasAnnotation(UnresolvedType ofType) {
-            return false;
+               return false;
         }
-
         public final boolean isAssignableFrom(ResolvedType other) {
             if (!other.isPrimitiveType()) {
-                if (!world.isInJava5Mode()) return false;
-                return validBoxing.contains(this.getSignature() + other.getSignature());
+               if (!world.isInJava5Mode()) return false;
+               return validBoxing.contains(this.getSignature()+other.getSignature());
             }
-            return assignTable[((Primitive) other).index][index];
+            return assignTable[((Primitive)other).index][index];
         }
-
         public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
-            return isAssignableFrom(other);
-        }
-
+               return isAssignableFrom(other);
+        }        
         public final boolean isCoerceableFrom(ResolvedType other) {
             if (this == other) return true;
             if (! other.isPrimitiveType()) return false;
-            if (index > 6 || ((Primitive) other).index > 6) return false;
+            if (index > 6 || ((Primitive)other).index > 6) return false;
             return true;
         }
-
         public ResolvedType resolve(World world) {
             this.world = world;
             return super.resolve(world);
         }
-
         public final boolean needsNoConversionFrom(ResolvedType other) {
             if (! other.isPrimitiveType()) return false;
-            return noConvertTable[((Primitive) other).index][index];
-        }
-
-        private static final boolean[][] assignTable =
-                {// to: B     C      D       F      I       J       S      V       Z        from
-                        {true, true, true, true, true, true, true, false, false}, // B
-                        {false, true, true, true, true, true, false, false, false}, // C
-                        {false, false, true, false, false, false, false, false, false}, // D
-                        {false, false, true, true, false, false, false, false, false}, // F
-                        {false, false, true, true, true, true, false, false, false}, // I
-                        {false, false, true, true, false, true, false, false, false}, // J
-                        {false, false, true, true, true, true, true, false, false}, // S
-                        {false, false, false, false, false, false, false, true, false}, // V
-                        {false, false, false, false, false, false, false, false, true}, // Z
-                };
-        private static final boolean[][] noConvertTable =
-                {// to: B     C      D       F      I       J       S      V       Z        from
-                        {true, true, false, false, true, false, true, false, false}, // B
-                        {false, true, false, false, true, false, false, false, false}, // C
-                        {false, false, true, false, false, false, false, false, false}, // D
-                        {false, false, false, true, false, false, false, false, false}, // F
-                        {false, false, false, false, true, false, false, false, false}, // I
-                        {false, false, false, false, false, true, false, false, false}, // J
-                        {false, false, false, false, true, false, true, false, false}, // S
-                        {false, false, false, false, false, false, false, true, false}, // V
-                        {false, false, false, false, false, false, false, false, true}, // Z
-                };
-
+            return noConvertTable[((Primitive)other).index][index];
+        }           
+        private static final boolean[][] assignTable = 
+            {// to: B     C      D       F      I       J       S      V       Z        from
+                { true , true , true , true , true , true , true , false, false }, // B
+                { false, true , true , true , true , true , false, false, false }, // C
+                { false, false, true , false, false, false, false, false, false }, // D
+                { false, false, true , true , false, false, false, false, false }, // F
+                { false, false, true , true , true , true , false, false, false }, // I
+                { false, false, true , true , false, true , false, false, false }, // J
+                { false, false, true , true , true , true , true , false, false }, // S
+                { false, false, false, false, false, false, false, true , false }, // V
+                { false, false, false, false, false, false, false, false, true  }, // Z
+            };             
+        private static final boolean[][] noConvertTable = 
+            {// to: B     C      D       F      I       J       S      V       Z        from
+                { true , true , false, false, true , false, true , false, false }, // B
+                { false, true , false, false, true , false, false, false, false }, // C
+                { false, false, true , false, false, false, false, false, false }, // D
+                { false, false, false, true , false, false, false, false, false }, // F
+                { false, false, false, false, true , false, false, false, false }, // I
+                { false, false, false, false, false, true , false, false, false }, // J
+                { false, false, false, false, true , false, true , false, false }, // S
+                { false, false, false, false, false, false, false, true , false }, // V
+                { false, false, false, false, false, false, false, false, true  }, // Z
+            };             
+                
         // ----
-
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedMember[] getDeclaredMethods() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedType[] getDeclaredInterfaces() {
             return ResolvedType.NONE;
         }
-
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
@@ -939,41 +910,37 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         public final ResolvedType getSuperclass() {
             return null;
         }
-
+        
         public ISourceContext getSourceContext() {
-            return null;
+               return null;
         }
-
+   
     }
 
     static class Missing extends ResolvedType {
         Missing() {
             super(MISSING_NAME, null);
-        }
+        }       
 //        public final String toString() {
 //            return "<missing>";
 //        }      
-
         public final String getName() {
-            return MISSING_NAME;
+               return MISSING_NAME;
         }
-
+        
         public final boolean isMissing() {
             return true;
         }
-
+        
         public boolean hasAnnotation(UnresolvedType ofType) {
-            return false;
+               return false;
         }
-
         public final ResolvedMember[] getDeclaredFields() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedMember[] getDeclaredMethods() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedType[] getDeclaredInterfaces() {
             return ResolvedType.NONE;
         }
@@ -981,148 +948,141 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         public final ResolvedMember[] getDeclaredPointcuts() {
             return ResolvedMember.NONE;
         }
-
         public final ResolvedType getSuperclass() {
             return null;
         }
-
         public final int getModifiers() {
             return 0;
         }
-
         public final boolean isAssignableFrom(ResolvedType other) {
             return false;
-        }
-
+        }   
         public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
             return false;
-        }
-
+        }   
         public final boolean isCoerceableFrom(ResolvedType other) {
             return false;
-        }
-
+        }        
         public boolean needsNoConversionFrom(ResolvedType other) {
             return false;
         }
-
         public ISourceContext getSourceContext() {
-            return null;
+               return null;
         }
 
     }
 
-    /**
+    /** 
      * Look up a member, takes into account any ITDs on this type.
      * return null if not found
      */
-    public ResolvedMember lookupMemberNoSupers(Member member) {
-        ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
-        if (ret == null && interTypeMungers != null) {
-            for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-                ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
-                if (matches(tm.getSignature(), member)) {
-                    return tm.getSignature();
-                }
-            }
-        }
-        return ret;
-    }
-
-    public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
-        ResolvedMember ret = lookupMemberNoSupers(member);
-        if (ret != null) return ret;
-
-        ResolvedType supert = getSuperclass();
-        if (supert != null) {
-            ret = supert.lookupMemberNoSupers(member);
-        }
-
-        return ret;
-    }
-
-    /**
-     * as lookupMemberNoSupers, but does not include ITDs
+       public ResolvedMember lookupMemberNoSupers(Member member) {
+               ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
+               if (ret == null && interTypeMungers != null) {
+                       for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+                               ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
+                               if (matches(tm.getSignature(), member)) {
+                                       return tm.getSignature();
+                               }
+                       }
+               }
+               return ret;
+       }
+       
+       public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
+               ResolvedMember ret = lookupMemberNoSupers(member);
+               if (ret != null) return ret;
+               
+               ResolvedType supert = getSuperclass();
+               if (supert != null) {
+                       ret = supert.lookupMemberNoSupers(member);
+               }
+               
+               return ret;
+       }
+       
+       /**
+        * as lookupMemberNoSupers, but does not include ITDs
      *
-     * @param member
-     * @return
-     */
-    public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
-        ResolvedMember ret;
-        if (member.getKind() == Member.FIELD) {
-            ret = lookupMember(member, getDeclaredFields());
-        } else {
-            // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
-            ret = lookupMember(member, getDeclaredMethods());
-        }
-        return ret;
-    }
-
-    /**
-     * This lookup has specialized behaviour - a null result tells the
-     * EclipseTypeMunger that it should make a default implementation of a
-     * method on this type.
+        * @param member
+        * @return
+        */
+       public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
+               ResolvedMember ret;
+               if (member.getKind() == Member.FIELD) {
+                       ret = lookupMember(member, getDeclaredFields());
+               } else {
+                       // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
+                       ret = lookupMember(member, getDeclaredMethods());
+               }
+               return ret;
+       }
+       
+       /**
+        * This lookup has specialized behaviour - a null result tells the
+        * EclipseTypeMunger that it should make a default implementation of a
+        * method on this type.
      *
-     * @param member
-     * @return
-     */
-    public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
-        return lookupMemberIncludingITDsOnInterfaces(member, this);
-    }
-
-    private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
-        ResolvedMember ret = onType.lookupMemberNoSupers(member);
-        if (ret != null) {
-            return ret;
-        } else {
-            ResolvedType superType = onType.getSuperclass();
-            if (superType != null) {
-                ret = lookupMemberIncludingITDsOnInterfaces(member, superType);
-            }
-            if (ret == null) {
-                // try interfaces then, but only ITDs now...
-                ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
-                for (int i = 0; i < superInterfaces.length; i++) {
-                    ret = superInterfaces[i].lookupMethodInITDs(member);
-                    if (ret != null) return ret;
-                }
-            }
-        }
-        return ret;
-    }
-
-    protected List interTypeMungers = new ArrayList(0);
-
-    public List getInterTypeMungers() {
-        return interTypeMungers;
-    }
-
+        * @param member
+        * @return
+        */
+       public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
+               return lookupMemberIncludingITDsOnInterfaces(member, this);
+       }
+       
+       private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
+               ResolvedMember ret = onType.lookupMemberNoSupers(member);
+               if (ret != null) {
+                       return ret;
+               } else {
+                       ResolvedType superType = onType.getSuperclass();
+                       if (superType != null) {
+                               ret = lookupMemberIncludingITDsOnInterfaces(member,superType);
+                       }
+                       if (ret == null) {
+                               // try interfaces then, but only ITDs now...
+                               ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
+                               for (int i = 0; i < superInterfaces.length; i++) {
+                                       ret = superInterfaces[i].lookupMethodInITDs(member);
+                                       if (ret != null) return ret;
+                               }
+                       }
+               }
+               return ret;
+       }
+       
+       protected List interTypeMungers = new ArrayList(0);
+       
+       public List getInterTypeMungers() {
+               return interTypeMungers;
+       }
+    
     public List getInterTypeParentMungers() {
-        List l = new ArrayList();
-        for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
-            ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
-            if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
-        }
-        return l;
-    }
-
-    /**
-     * ??? This method is O(N*M) where N = number of methods and M is number of
-     * inter-type declarations in my super
-     */
-    public List getInterTypeMungersIncludingSupers() {
+      List l = new ArrayList();
+      for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
+               ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
+               if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
+       }
+      return l;
+    }
+    
+       /**
+        * ??? This method is O(N*M) where N = number of methods and M is number of
+        * inter-type declarations in my super
+        */
+     public List getInterTypeMungersIncludingSupers() {
         ArrayList ret = new ArrayList();
         collectInterTypeMungers(ret);
         return ret;
     }
 
-
+     
     public List getInterTypeParentMungersIncludingSupers() {
-        ArrayList ret = new ArrayList();
-        collectInterTypeParentMungers(ret);
-        return ret;
+      ArrayList ret = new ArrayList();
+      collectInterTypeParentMungers(ret);
+      return ret;
     }
-
+    
     private void collectInterTypeParentMungers(List collector) {
         for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
             ResolvedType superType = (ResolvedType) iter.next();
@@ -1130,44 +1090,45 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         }
         collector.addAll(getInterTypeParentMungers());
     }
-
-
+        
+        
     protected void collectInterTypeMungers(List collector) {
         for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
-            ResolvedType superType = (ResolvedType) iter.next();
+                       ResolvedType superType = (ResolvedType) iter.next();
             superType.collectInterTypeMungers(collector);
-        }
-
+               }
+        
         outer:
         for (Iterator iter1 = collector.iterator(); iter1.hasNext();) {
             ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
-            if (superMunger.getSignature() == null) continue;
-
-            if (!superMunger.getSignature().isAbstract()) continue;
-
+            if ( superMunger.getSignature() == null) continue;
+            
+            if ( !superMunger.getSignature().isAbstract()) continue;
+            
             for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
-                ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
+                ConcreteTypeMunger  myMunger = (ConcreteTypeMunger) iter.next();
                 if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
                     iter1.remove();
                     continue outer;
                 }
             }
-
+            
             if (!superMunger.getSignature().isPublic()) continue;
-
-            for (Iterator iter = getMethods(); iter.hasNext();) {
-                ResolvedMember method = (ResolvedMember) iter.next();
+            
+            for (Iterator iter = getMethods(); iter.hasNext(); ) {
+                ResolvedMember method = (ResolvedMember)iter.next();
                 if (conflictingSignature(method, superMunger.getSignature())) {
                     iter1.remove();
                     continue outer;
                 }
             }
         }
-
+        
         collector.addAll(getInterTypeMungers());
     }
-
-
+    
+    
     /**
      * Check:
      * 1) That we don't have any abstract type mungers unless this type is abstract.
@@ -1175,56 +1136,56 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      */
     public void checkInterTypeMungers() {
         if (isAbstract()) return;
-
+        
         boolean itdProblem = false;
-
+        
         for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
-            ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
-            itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
+                       ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
+                       itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
 
         }
-
+        
         if (itdProblem) return; // If the rules above are broken, return right now
-
-        for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
-            ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
+        
+               for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
+                       ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
             if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1
                 if (munger.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) {
                     ;//ignore for @AJ ITD as munger.getSingature() is the interface method hence abstract
                 } else {
-                    world.getMessageHandler().handleMessage(
-                            new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
-                                    "", IMessage.ERROR, getSourceLocation(), null,
-                                    new ISourceLocation[]{getMungerLocation(munger)}));
-                }
+                world.getMessageHandler().handleMessage(
+                    new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
+                        "", IMessage.ERROR, getSourceLocation(), null, 
+                        new ISourceLocation[] { getMungerLocation(munger) }));
             }
-        }
+               }
     }
-
+    }
+    
     /**
      * See PR70794.  This method checks that if an abstract inter-type method declaration is made on
      * an interface then it must also be public.
      * This is a compiler limitation that could be made to work in the future (if someone
      * provides a worthwhile usecase)
-     *
+     * 
      * @return indicates if the munger failed the check
      */
     private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) {
-        if (munger.getMunger() != null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
-            ResolvedMember itdMember = munger.getSignature();
-            ResolvedType onType = itdMember.getDeclaringType().resolve(world);
-            if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
-                world.getMessageHandler().handleMessage(
-                        new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE, munger.getSignature(), onType), "",
-                                Message.ERROR, getSourceLocation(), null,
-                                new ISourceLocation[]{getMungerLocation(munger)})
-                );
-                return true;
-            }
-        }
-        return false;
-    }
-
+               if (munger.getMunger()!=null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
+                       ResolvedMember itdMember = munger.getSignature();
+                       ResolvedType onType = itdMember.getDeclaringType().resolve(world);
+                       if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
+                                       world.getMessageHandler().handleMessage(
+                                                       new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,munger.getSignature(),onType),"",
+                                                                       Message.ERROR,getSourceLocation(),null,
+                                                                       new ISourceLocation[]{getMungerLocation(munger)})       
+                                               );
+                                       return true;
+                               }                       
+               }
+               return false;
+    }
+    
     /**
      * Get a source location for the munger.
      * Until intertype mungers remember where they came from, the source location
@@ -1232,13 +1193,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      * source location for the aspect containing the ITD.
      */
     private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) {
-        ISourceLocation sloc = munger.getSourceLocation();
-        if (sloc == null) {
-            sloc = munger.getAspectType().getSourceLocation();
-        }
-        return sloc;
+       ISourceLocation sloc = munger.getSourceLocation();
+       if (sloc == null) {
+               sloc = munger.getAspectType().getSourceLocation();
+       }
+       return sloc;
     }
-
+       
     /**
      * Returns a ResolvedType object representing the declaring type of this type, or
      * null if this type does not represent a non-package-level-type.
@@ -1251,424 +1212,524 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
      * @return the declaring UnresolvedType object, or null.
      */
     public ResolvedType getDeclaringType() {
-        if (isArray()) return null;
-        String name = getName();
-        int lastDollar = name.lastIndexOf('$');
-        while (lastDollar != -1) {
-            ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
-            if (ret != ResolvedType.MISSING) return ret;
-            lastDollar = name.lastIndexOf('$', lastDollar - 1);
-        }
-        return null;
-    }
-
-
-    public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
-        //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
-
-        if (Modifier.isPublic(modifiers)) {
-            return true;
-        } else if (Modifier.isPrivate(modifiers)) {
-            return targetType.getOutermostType().equals(fromType.getOutermostType());
-        } else if (Modifier.isProtected(modifiers)) {
-            return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
-        } else { // package-visible
-            return samePackage(targetType, fromType);
-        }
-    }
-
-    public static boolean hasBridgeModifier(int modifiers) {
-        return (modifiers & Constants.ACC_BRIDGE) != 0;
-    }
-
-    private static boolean samePackage(
-            ResolvedType targetType,
+       if (isArray()) return null;
+               String name = getName();
+               int lastDollar = name.lastIndexOf('$');
+               while (lastDollar != -1) {
+                       ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
+                       if (ret != ResolvedType.MISSING) return ret;
+                       lastDollar = name.lastIndexOf('$', lastDollar-1);
+               }
+               return null;
+    }
+       
+       
+       public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
+               //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
+               
+               if (Modifier.isPublic(modifiers)) {
+                       return true;
+               } else if (Modifier.isPrivate(modifiers)) {
+                       return targetType.getOutermostType().equals(fromType.getOutermostType());
+               } else if (Modifier.isProtected(modifiers)) {
+                       return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
+               } else { // package-visible
+                       return samePackage(targetType, fromType);
+               }       
+       }
+       
+       public static boolean hasBridgeModifier(int modifiers) {
+               return (modifiers & Constants.ACC_BRIDGE)!=0;
+       }
+
+       private static boolean samePackage(
+               ResolvedType targetType,
             ResolvedType fromType) {
-        String p1 = targetType.getPackageName();
-        String p2 = fromType.getPackageName();
-        if (p1 == null) return p2 == null;
-        if (p2 == null) return false;
-        return p1.equals(p2);
+               String p1 = targetType.getPackageName();
+               String p2 = fromType.getPackageName();
+               if (p1 == null) return p2 == null;
+               if (p2 == null) return false;
+               return p1.equals(p2);
+       }
+
+       /**
+        * Checks if the generic type for 'this' and the generic type for 'other' are the same -
+        * it can be passed raw or parameterized versions and will just compare the underlying
+        * generic type.
+        */
+    private boolean genericTypeEquals(ResolvedType other) {
+        ResolvedType rt = other;
+        if (rt.isParameterizedType() || rt.isRawType()) rt.getGenericType();
+        if (( (isParameterizedType() || isRawType()) && getGenericType().equals(rt)) ||
+                (this.equals(other))) return true;
+        return false;
     }
+       
+        /**
+     * Look up the actual occurence of a particular type in the hierarchy for
+     * 'this' type.  The input is going to be a generic type, and the caller
+     * wants to know if it was used in its RAW or a PARAMETERIZED form in this
+     * hierarchy.
+     *
+     * returns null if it can't be found.
+     */
+    public ResolvedType discoverActualOccurenceOfTypeInHierarchy(ResolvedType lookingFor) {
+            if (!lookingFor.isGenericType())
+                    throw new BCException("assertion failed: method should only be called with generic type, but "+lookingFor+" is "+lookingFor.typeKind);
 
-    public void addInterTypeMunger(ConcreteTypeMunger munger) {
-        ResolvedMember sig = munger.getSignature();
-        if (sig == null || munger.getMunger() == null ||
-                munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
-            interTypeMungers.add(munger);
-            return;
-        }
+            if (this.equals(ResolvedType.OBJECT)) return null;
 
-        //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
-        if (sig.getKind() == Member.METHOD) {
-            if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false, true) /*getMethods()*/)) return;
-            if (this.isInterface()) {
-                if (!compareToExistingMembers(munger,
-                        Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
-            }
-        } else if (sig.getKind() == Member.FIELD) {
-            if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
-        } else {
-            if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
-        }
+            if (genericTypeEquals(lookingFor)) return this;
 
-        // now compare to existingMungers
-        for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-            ConcreteTypeMunger existingMunger = (ConcreteTypeMunger) i.next();
-            if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
-                //System.err.println("match " + munger + " with " + existingMunger);
-                if (isVisible(munger.getSignature().getModifiers(),
-                        munger.getAspectType(), existingMunger.getAspectType())) {
-                    //System.err.println("    is visible");
-                    int c = compareMemberPrecedence(sig, existingMunger.getSignature());
-                    if (c == 0) {
-                        c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
-                    }
-                    //System.err.println("       compare: " + c);
-                    if (c < 0) {
-                        // the existing munger dominates the new munger
-                        checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
-                        return;
-                    } else if (c > 0) {
-                        // the new munger dominates the existing one
-                        checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
-                        i.remove();
-                        break;
-                    } else {
-                        interTypeConflictError(munger, existingMunger);
-                        interTypeConflictError(existingMunger, munger);
-                        return;
-                    }
-                }
-            }
-        }
-        //System.err.println("adding: " + munger + " to " + this);
-        interTypeMungers.add(munger);
-    }
+            ResolvedType superT = getSuperclass();
+            if (superT.genericTypeEquals(lookingFor)) return superT;
 
-    private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
-        return compareToExistingMembers(munger, existingMembersList.iterator());
-    }
-
-    //??? returning too soon
-    private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
-        ResolvedMember sig = munger.getSignature();
-        while (existingMembers.hasNext()) {
-            ResolvedMember existingMember = (ResolvedMember) existingMembers.next();
-            //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
-            if (conflictingSignature(existingMember, munger.getSignature())) {
-                //System.err.println("conflict: existingMember=" + existingMember + "   typeMunger=" + munger);
-                //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
-
-                if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
-                    int c = compareMemberPrecedence(sig, existingMember);
-                    //System.err.println("   c: " + c);
-                    if (c < 0) {
-                        // existingMember dominates munger
-                        checkLegalOverride(munger.getSignature(), existingMember);
-                        return false;
-                    } else if (c > 0) {
-                        // munger dominates existingMember
-                        checkLegalOverride(existingMember, munger.getSignature());
-                        //interTypeMungers.add(munger);
-                        //??? might need list of these overridden abstracts
-                        continue;
-                    } else {
-                        // bridge methods can differ solely in return type.
-                        // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
-                        // could do with a rewrite !
-                        boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
-                        if (sameReturnTypes)
-                            getWorld().getMessageHandler().handleMessage(
-                                    MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType().getName(),
-                                            existingMember),
-                                            munger.getSourceLocation())
-                            );
-                    }
-                } else if (isDuplicateMemberWithinTargetType(existingMember, this, sig)) {
-                    getWorld().getMessageHandler().handleMessage(
-                            MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType().getName(),
-                                    existingMember),
-                                    munger.getSourceLocation())
-                    );
-                    ;
-                }
-                //return;
+            ResolvedType[] superIs = getDeclaredInterfaces();
+            for (int i = 0; i < superIs.length; i++) {
+                    ResolvedType superI = superIs[i];
+                    if (superI.genericTypeEquals(lookingFor)) return superI;
+                    ResolvedType checkTheSuperI = discoverActualOccurenceOfTypeInHierarchy(lookingFor);
+                    if (checkTheSuperI!=null) return checkTheSuperI;
             }
-        }
-        return true;
-    }
-
-    // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
-    // this may still be disallowed if it would result in two members within the same declaring type with the same
-    // signature AND more than one of them is concrete AND they are both visible within the target type.
-    private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType, ResolvedMember itdMember) {
-        if ((existingMember.isAbstract() || itdMember.isAbstract())) return false;
-        UnresolvedType declaringType = existingMember.getDeclaringType();
-        if (!targetType.equals(declaringType)) return false;
-        // now have to test that itdMember is visible from targetType
-        if (itdMember.isPrivate()) return false;
-        if (itdMember.isPublic()) return true;
-        // must be in same package to be visible then...
-        if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
-
-        // trying to put two members with the same signature into the exact same type..., and both visible in that type.
-        return true;
+            return discoverActualOccurenceOfTypeInHierarchy(superT);
     }
 
     /**
-     * @return true if the override is legal
-     *         note: calling showMessage with two locations issues TWO messages, not ONE message
-     *         with an additional source location.
+     * Called for all type mungers but only does something if they share type variables
+     * with a generic type which they target.  When this happens this routine will check
+     * for the target type in the target hierarchy and 'bind' any type parameters as
+     * appropriate.  For example, for the ITD "List<T> I<T>.x" against a type like this:
+     * "class A implements I<String>" this routine will return a parameterized form of
+     * the ITD "List<String> I.x"
      */
-    public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
-        //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
-        if (Modifier.isFinal(parent.getModifiers())) {
-            world.showMessage(Message.ERROR,
-                    WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent),
-                    child.getSourceLocation(), null);
-            return false;
-        }
-
-        boolean incompatibleReturnTypes = false;
-
-        // In 1.5 mode, allow for covariance on return type
-        if (world.isInJava5Mode() && parent.getKind() == Member.METHOD) {
-            ResolvedType rtParentReturnType = parent.getReturnType().resolve(world);
-            ResolvedType rtChildReturnType = child.getReturnType().resolve(world);
-            incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
-        } else {
-            incompatibleReturnTypes = !parent.getReturnType().equals(child.getReturnType());
-        }
-
-        if (incompatibleReturnTypes) {
-            world.showMessage(IMessage.ERROR,
-                    WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH, parent, child),
-                    child.getSourceLocation(), parent.getSourceLocation());
-            return false;
-        }
-        if (parent.getKind() == Member.POINTCUT) {
-            UnresolvedType[] pTypes = parent.getParameterTypes();
-            UnresolvedType[] cTypes = child.getParameterTypes();
-            if (!Arrays.equals(pTypes, cTypes)) {
-                world.showMessage(IMessage.ERROR,
-                        WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH, parent, child),
-                        child.getSourceLocation(), parent.getSourceLocation());
-                return false;
-            }
-        }
-        //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
-        if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
-            world.showMessage(IMessage.ERROR,
-                    WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION, parent, child),
-                    child.getSourceLocation(), parent.getSourceLocation());
-            return false;
-        }
-
-        // check declared exceptions
-        ResolvedType[] childExceptions = world.resolve(child.getExceptions());
-        ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
-        ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
-        ResolvedType error = world.resolve("java.lang.Error");
-
+    public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) {
+       boolean debug = false;
+               ResolvedMember member = munger.getSignature();
+               if (munger.isTargetTypeParameterized()) {
+                       if (debug) System.err.println("Processing attempted parameterization of "+munger+" targetting type "+this);
+                       if (debug) System.err.println("  This type is "+this+"  ("+typeKind+")");
+               // need to tailor this munger instance for the particular target...
+               if (debug) System.err.println("  Signature that needs parameterizing: "+member);
+               // Retrieve the generic type
+               ResolvedType onType = world.resolve(member.getDeclaringType()).getGenericType();
+               member.resolve(world); // Ensure all parts of the member are resolved
+               if (debug) System.err.println("  Actual target ontype: "+onType+"  ("+onType.typeKind+")");
+               // quickly find the targettype in the type hierarchy for this type (it will be either RAW or PARAMETERIZED)
+               ResolvedType actualTarget = discoverActualOccurenceOfTypeInHierarchy(onType);
+               if (actualTarget==null)
+                       throw new BCException("assertion failed: asked "+this+" for occurrence of "+onType+" in its hierarchy??");
+       
+               // only bind the tvars if its a parameterized type or the raw type (in which case they collapse to bounds) - don't do it for generic types ;)
+               if (!actualTarget.isGenericType()) {
+                   if (debug) System.err.println("Occurence in "+this+" is actually "+actualTarget+"  ("+actualTarget.typeKind+")");
+                   // parameterize the signature
+                   ResolvedMember newOne = member.parameterizedWith(actualTarget.getTypeParameters(),onType,actualTarget.isParameterizedType());
+                   munger = munger.parameterizedFor(actualTarget);
+                   if (debug) System.err.println("New sig: "+newOne);
+                   
+               }
+               if (debug) System.err.println("=====================================");
+               }
+               return munger;
+    }
+
+    
+    
+       public void addInterTypeMunger(ConcreteTypeMunger munger) {
+               ResolvedMember sig = munger.getSignature();
+               if (sig == null || munger.getMunger() == null || 
+                               munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess)
+               {
+                       interTypeMungers.add(munger);
+                       return;
+               }
+               
+               ConcreteTypeMunger originalMunger = munger;
+               // we will use the 'parameterized' ITD for all the comparisons but we say the original
+        // one passed in actually matched as it will be added to the intertype member finder
+               // for the target type.  It is possible we only want to do this if a generic type 
+               // is discovered and the tvar is collapsed to a bound?
+               munger = fillInAnyTypeParameters(munger);
+               sig = munger.getSignature(); // possibly changed when type parms filled in
+
+               
+               //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
+               if (sig.getKind() == Member.METHOD) {
+                       if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false,true) /*getMethods()*/)) return;
+                       if (this.isInterface()) {
+                               if (!compareToExistingMembers(munger, 
+                                               Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
+                       }
+               } else if (sig.getKind() == Member.FIELD) {
+                       if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
+               } else {
+                       if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
+               }
+
+               
+               // now compare to existingMungers
+               for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
+                       ConcreteTypeMunger existingMunger = (ConcreteTypeMunger)i.next();
+                       if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
+                               //System.err.println("match " + munger + " with " + existingMunger);
+                               if (isVisible(munger.getSignature().getModifiers(),
+                                                       munger.getAspectType(), existingMunger.getAspectType()))
+                               {
+                                       //System.err.println("    is visible");
+                                       int c = compareMemberPrecedence(sig, existingMunger.getSignature());
+                                       if (c == 0) {
+                                               c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
+                                       }
+                                       //System.err.println("       compare: " + c);
+                                       if (c < 0) {
+                                               // the existing munger dominates the new munger
+                                               checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
+                                               return;
+                                       } else if (c > 0) {
+                                               // the new munger dominates the existing one
+                                               checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
+                                               i.remove();
+                                               break;
+                                       } else {
+                                               interTypeConflictError(munger, existingMunger);
+                                               interTypeConflictError(existingMunger, munger);
+                                               return;
+                                       }                                       
+                               }
+                       }
+               }
+               //System.err.println("adding: " + munger + " to " + this);
+               // we used the 'parameterized' ITD for all the comparisons but we say the original
+        // one passed in actually matched as it will be added to the intertype member finder
+               // for the target type.
+               interTypeMungers.add(originalMunger);
+       }
+       
+       private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
+               return compareToExistingMembers(munger,existingMembersList.iterator());
+       }
+       
+       //??? returning too soon
+       private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
+               ResolvedMember sig = munger.getSignature();
+               while (existingMembers.hasNext()) {
+                       ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
+                       //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
+                       if (conflictingSignature(existingMember, munger.getSignature())) {
+                               //System.err.println("conflict: existingMember=" + existingMember + "   typeMunger=" + munger);
+                               //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
+                               
+                               if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
+                                       int c = compareMemberPrecedence(sig, existingMember);
+                                       //System.err.println("   c: " + c);
+                                       if (c < 0) {
+                                               // existingMember dominates munger
+                                               checkLegalOverride(munger.getSignature(), existingMember);
+                                               return false;
+                                       } else if (c > 0) {
+                                               // munger dominates existingMember
+                                               checkLegalOverride(existingMember, munger.getSignature());
+                                               //interTypeMungers.add(munger);  
+                                               //??? might need list of these overridden abstracts
+                                               continue;
+                                       } else {
+                                         // bridge methods can differ solely in return type.
+                                         // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
+                                         // could do with a rewrite !
+                                         boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
+                                         if (sameReturnTypes)
+                                                 getWorld().getMessageHandler().handleMessage(
+                                                       MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
+                                                                       existingMember),
+                                                       munger.getSourceLocation())
+                                                 );
+                                       }
+                               } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
+                                       getWorld().getMessageHandler().handleMessage(
+                                                       MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
+                                                                       existingMember),
+                                                       munger.getSourceLocation())
+                    );
+                    ;
+                               }
+                               //return;
+                       }
+               }
+               return true;
+       }
+       
+       // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
+       // this may still be disallowed if it would result in two members within the same declaring type with the same
+       // signature AND more than one of them is concrete AND they are both visible within the target type.
+       private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType,ResolvedMember itdMember) {
+           if ( (existingMember.isAbstract() || itdMember.isAbstract())) return false;
+           UnresolvedType declaringType = existingMember.getDeclaringType();
+           if (!targetType.equals(declaringType)) return false;
+           // now have to test that itdMember is visible from targetType
+           if (itdMember.isPrivate()) return false;
+           if (itdMember.isPublic()) return true;
+           // must be in same package to be visible then...
+           if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
+           
+           // trying to put two members with the same signature into the exact same type..., and both visible in that type.
+           return true;
+       }
+       
+       /**
+        * @return true if the override is legal
+        * note: calling showMessage with two locations issues TWO messages, not ONE message
+        * with an additional source location.
+        */
+       public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
+               //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
+               if (Modifier.isFinal(parent.getModifiers())) {
+                       world.showMessage(Message.ERROR,
+                                       WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER,parent),
+                                       child.getSourceLocation(),null);
+                       return false;
+               }
+               
+               boolean incompatibleReturnTypes = false;
+               
+               // In 1.5 mode, allow for covariance on return type
+               if (world.isInJava5Mode() && parent.getKind()==Member.METHOD) {
+                       
+                 // Look at the generic types when doing this comparison
+             ResolvedType rtParentReturnType = parent.getGenericReturnType().resolve(world);
+                 ResolvedType rtChildReturnType  = child.getGenericReturnType().resolve(world);
+                 incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
+               } else {
+                 incompatibleReturnTypes =!parent.getReturnType().equals(child.getReturnType());
+               }
+               
+               if (incompatibleReturnTypes) {
+                       world.showMessage(IMessage.ERROR,
+                                       WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH,parent,child),
+                                       child.getSourceLocation(), parent.getSourceLocation());
+                       return false;
+               }               
+               if (parent.getKind() == Member.POINTCUT) {
+                       UnresolvedType[] pTypes = parent.getParameterTypes();
+                       UnresolvedType[] cTypes = child.getParameterTypes();
+                       if (!Arrays.equals(pTypes, cTypes)) {
+                               world.showMessage(IMessage.ERROR,
+                                               WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH,parent,child),
+                                               child.getSourceLocation(), parent.getSourceLocation());
+                               return false;
+                       }
+               }               
+               //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
+               if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
+                       world.showMessage(IMessage.ERROR,
+                                       WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION,parent,child),
+                                       child.getSourceLocation(), parent.getSourceLocation());
+                       return false;
+               }
+               
+               // check declared exceptions
+               ResolvedType[] childExceptions = world.resolve(child.getExceptions());
+               ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
+               ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
+               ResolvedType error = world.resolve("java.lang.Error");
+               
         outer:
         for (int i = 0, leni = childExceptions.length; i < leni; i++) {
-            //System.err.println("checking: " + childExceptions[i]);
-            if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
-            if (error.isAssignableFrom(childExceptions[i])) continue;
-
-            for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
-                if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
-            }
-
-            // this message is now better handled my MethodVerifier in JDT core.
+                       //System.err.println("checking: " + childExceptions[i]);
+                       if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
+                       if (error.isAssignableFrom(childExceptions[i])) continue;
+                       
+                       for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
+                               if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
+                       }
+                       
+                       // this message is now better handled my MethodVerifier in JDT core.
 //                     world.showMessage(IMessage.ERROR,
 //                                     WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()),
 //                                     child.getSourceLocation(), null);
-
-            return false;
-        }
-        if (parent.isStatic() && !child.isStatic()) {
-            world.showMessage(IMessage.ERROR,
-                    WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC, child, parent),
-                    child.getSourceLocation(), null);
-            return false;
-        } else if (child.isStatic() && !parent.isStatic()) {
-            world.showMessage(IMessage.ERROR,
-                    WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC, child, parent),
-                    child.getSourceLocation(), null);
-            return false;
-        }
-        return true;
-
-    }
-
-    private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
-        //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
-
-        // need to allow for the special case of 'clone' - which is like abstract but is
-        // not marked abstract.  The code below this next line seems to make assumptions
-        // about what will have gotten through the compiler based on the normal
-        // java rules.  clone goes against these...
-        if (m2.isProtected() && m2.isNative() && m2.getName().equals("clone")) return +1;
-
-        if (Modifier.isAbstract(m1.getModifiers())) return -1;
-        if (Modifier.isAbstract(m2.getModifiers())) return +1;
-
-        if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
-
-        ResolvedType t1 = m1.getDeclaringType().resolve(world);
-        ResolvedType t2 = m2.getDeclaringType().resolve(world);
-        if (t1.isAssignableFrom(t2)) {
-            return -1;
-        }
-        if (t2.isAssignableFrom(t1)) {
-            return +1;
-        }
-        return 0;
-    }
-
-
-    public static boolean isMoreVisible(int m1, int m2) {
-        if (Modifier.isPrivate(m1)) return false;
-        if (isPackage(m1)) return Modifier.isPrivate(m2);
-        if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
-        if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
-        throw new RuntimeException("bad modifier: " + m1);
-    }
-
-    private static boolean isPackage(int i) {
-        return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
-    }
-
-    private void interTypeConflictError(
-            ConcreteTypeMunger m1,
+                                               
+                       return false;
+               }
+               if (parent.isStatic() && !child.isStatic()) {
+                       world.showMessage(IMessage.ERROR,
+                                       WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC,child,parent),
+                                       child.getSourceLocation(),null);
+                       return false;
+               } else if (child.isStatic() && !parent.isStatic()) {
+                       world.showMessage(IMessage.ERROR,
+                                       WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC,child,parent),
+                                       child.getSourceLocation(),null);
+                       return false;
+               }
+               return true;
+               
+       }
+       
+       private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
+               //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
+               
+               // need to allow for the special case of 'clone' - which is like abstract but is
+               // not marked abstract.  The code below this next line seems to make assumptions
+               // about what will have gotten through the compiler based on the normal
+               // java rules.  clone goes against these...
+               if (m2.isProtected() && m2.isNative() && m2.getName().equals("clone")) return +1;
+               
+               if (Modifier.isAbstract(m1.getModifiers())) return -1;
+               if (Modifier.isAbstract(m2.getModifiers())) return +1;
+       
+               if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
+               
+               ResolvedType t1 = m1.getDeclaringType().resolve(world);
+               ResolvedType t2 = m2.getDeclaringType().resolve(world);
+               if (t1.isAssignableFrom(t2)) {
+                       return -1;
+               }
+               if (t2.isAssignableFrom(t1)) {
+                       return +1;
+               }
+               return 0;
+       }
+       
+
+       public static boolean isMoreVisible(int m1, int m2) {
+               if (Modifier.isPrivate(m1)) return false;
+               if (isPackage(m1)) return Modifier.isPrivate(m2);
+               if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
+               if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
+               throw new RuntimeException("bad modifier: " + m1);
+       }
+
+       private static boolean isPackage(int i) {
+               return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
+       }
+
+       private void interTypeConflictError(
+               ConcreteTypeMunger m1,
             ConcreteTypeMunger m2) {
-        //XXX this works only if we ignore separate compilation issues
-        //XXX dual errors possible if (this instanceof BcelObjectType) return;
-
-        //System.err.println("conflict at " + m2.getSourceLocation());
-        getWorld().showMessage(IMessage.ERROR,
-                WeaverMessages.format(WeaverMessages.ITD_CONFLICT, m1.getAspectType().getName(),
-                        m2.getSignature(), m2.getAspectType().getName()),
-                m2.getSourceLocation(), getSourceLocation());
-    }
-
-
-    public ResolvedMember lookupSyntheticMember(Member member) {
-        //??? horribly inefficient
-        //for (Iterator i =
-        //System.err.println("lookup " + member + " in " + interTypeMungers);
-        for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
-            ConcreteTypeMunger m = (ConcreteTypeMunger) i.next();
-            ResolvedMember ret = m.getMatchingSyntheticMember(member);
-            if (ret != null) {
-                //System.err.println("   found: " + ret);
-                return ret;
-            }
-        }
-
+               //XXX this works only if we ignore separate compilation issues
+               //XXX dual errors possible if (this instanceof BcelObjectType) return;
+               
+               //System.err.println("conflict at " + m2.getSourceLocation());
+               getWorld().showMessage(IMessage.ERROR,
+                               WeaverMessages.format(WeaverMessages.ITD_CONFLICT,m1.getAspectType().getName(),
+                                                                       m2.getSignature(),m2.getAspectType().getName()),
+                                               m2.getSourceLocation(), getSourceLocation());
+       }
+       
+       
+       public ResolvedMember lookupSyntheticMember(Member member) {
+               //??? horribly inefficient
+               //for (Iterator i = 
+               //System.err.println("lookup " + member + " in " + interTypeMungers);
+               for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
+                       ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+                       ResolvedMember ret = m.getMatchingSyntheticMember(member);
+                       if (ret != null) {
+                               //System.err.println("   found: " + ret);
+                               return ret;
+                       }
+               }
+               
 //             if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) {
 //                     return getSuperclass().lookupSyntheticMember(member);
 //             }
-
-        return null;
-    }
-
-    public void clearInterTypeMungers() {
-        if (isRawType()) getGenericType().clearInterTypeMungers();
-        interTypeMungers = new ArrayList();
-    }
-
-
-    public boolean isTopmostImplementor(ResolvedType interfaceType) {
-        if (isInterface()) return false;
-        if (!interfaceType.isAssignableFrom(this, true)) return false;
-        // check that I'm truly the topmost implementor
-        if (this.getSuperclass().isMissing()) return true; // we don't know anything about supertype, and it can't be exposed to weaver
-        if (interfaceType.isAssignableFrom(this.getSuperclass(), true)) {
-            return false;
-        }
-        return true;
-    }
-
-    public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
-        if (isInterface()) return null;
-        if (!interfaceType.isAssignableFrom(this)) return null;
-        // Check if my super class is an implementor?
-        ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
-        if (higherType != null) return higherType;
-        return this;
-    }
-
-    private ResolvedType findHigher(ResolvedType other) {
-        if (this == other) return this;
-        for (Iterator i = other.getDirectSupertypes(); i.hasNext();) {
-            ResolvedType rtx = (ResolvedType) i.next();
-            boolean b = this.isAssignableFrom(rtx);
-            if (b) return rtx;
-        }
-        return null;
-    }
-
-    public List getExposedPointcuts() {
-        List ret = new ArrayList();
-        if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
-
-        for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext();) {
-            ResolvedType t = (ResolvedType) i.next();
-            addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
-        }
-        addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
-        for (Iterator i = ret.iterator(); i.hasNext();) {
-            ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) i.next();
+               
+               return null;
+       }
+
+       public void clearInterTypeMungers() {
+               if (isRawType()) getGenericType().clearInterTypeMungers();
+               interTypeMungers = new ArrayList();
+       }
+
+
+       public boolean isTopmostImplementor(ResolvedType interfaceType) {
+               if (isInterface()) return false;
+               if (!interfaceType.isAssignableFrom(this,true)) return false;
+               // check that I'm truly the topmost implementor
+               if (this.getSuperclass().isMissing()) return true; // we don't know anything about supertype, and it can't be exposed to weaver
+               if (interfaceType.isAssignableFrom(this.getSuperclass(),true)) {
+                       return false;
+               }
+               return true;
+       }
+       
+       public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
+               if (isInterface()) return null;
+               if (!interfaceType.isAssignableFrom(this)) return null;
+               // Check if my super class is an implementor?
+               ResolvedType higherType  = this.getSuperclass().getTopmostImplementor(interfaceType);
+               if (higherType!=null) return higherType;
+               return this;
+       }
+       
+       private ResolvedType findHigher(ResolvedType other) {
+        if (this == other) return this;
+     for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
+       ResolvedType rtx = (ResolvedType)i.next();
+       boolean b = this.isAssignableFrom(rtx);
+       if (b) return rtx;
+     }       
+     return null;
+       }
+       
+       public List getExposedPointcuts() {
+               List ret = new ArrayList();
+               if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
+               
+               for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext(); ) {
+                       ResolvedType t = (ResolvedType)i.next();
+                       addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
+               }
+               addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
+               for (Iterator i = ret.iterator(); i.hasNext(); ) {
+                       ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition)i.next();
 //                     System.err.println("looking at: " + inherited + " in " + this);
 //                     System.err.println("            " + inherited.isAbstract() + " in " + this.isAbstract());
-            if (inherited.isAbstract()) {
-                if (!this.isAbstract()) {
-                    getWorld().showMessage(IMessage.ERROR,
-                            WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE, inherited, this.getName()),
-                            inherited.getSourceLocation(), this.getSourceLocation());
-                }
-            }
-        }
-
-
-        return ret;
-    }
-
-    private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
-        for (Iterator i = added.iterator(); i.hasNext();) {
-            ResolvedPointcutDefinition toAdd =
-                    (ResolvedPointcutDefinition) i.next();
-            //System.err.println("adding: " + toAdd);
-            for (Iterator j = acc.iterator(); j.hasNext();) {
-                ResolvedPointcutDefinition existing =
-                        (ResolvedPointcutDefinition) j.next();
-                if (existing == toAdd) continue;
-                if (!isVisible(existing.getModifiers(),
-                        existing.getDeclaringType().resolve(getWorld()),
-                        this)) {
-                    continue;
-                }
-                if (conflictingSignature(existing, toAdd)) {
-                    if (isOverriding) {
-                        checkLegalOverride(existing, toAdd);
-                        j.remove();
-                    } else {
-                        getWorld().showMessage(
-                                IMessage.ERROR,
-                                WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS, this.getName() + toAdd.getSignature()),
-                                existing.getSourceLocation(),
-                                toAdd.getSourceLocation());
-                        j.remove();
-                    }
-                }
-            }
-            acc.add(toAdd);
-        }
-    }
-
+                       if (inherited.isAbstract()) {
+                               if (!this.isAbstract()) {
+                                       getWorld().showMessage(IMessage.ERROR,
+                                                       WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE,inherited,this.getName()),
+                                                       inherited.getSourceLocation(), this.getSourceLocation());
+                               }
+                       }
+               }               
+               
+               
+               return ret;
+       }
+       
+       private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
+               for (Iterator i = added.iterator(); i.hasNext();) {
+                       ResolvedPointcutDefinition toAdd =
+                               (ResolvedPointcutDefinition) i.next();
+                               //System.err.println("adding: " + toAdd);
+                       for (Iterator j = acc.iterator(); j.hasNext();) {
+                               ResolvedPointcutDefinition existing =
+                                       (ResolvedPointcutDefinition) j.next();
+                               if (existing == toAdd) continue;
+                               if (!isVisible(existing.getModifiers(),
+                                       existing.getDeclaringType().resolve(getWorld()),
+                                       this)) {
+                                       continue;
+                               }
+                               if (conflictingSignature(existing, toAdd)) {
+                                       if (isOverriding) {
+                                               checkLegalOverride(existing, toAdd);
+                                               j.remove();
+                                       } else {
+                                               getWorld().showMessage(
+                                                       IMessage.ERROR,
+                                                       WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,this.getName() + toAdd.getSignature()),
+                                                       existing.getSourceLocation(),
+                                                       toAdd.getSourceLocation());
+                                               j.remove();
+                                       }
+                               }
+                       }
+                       acc.add(toAdd);
+               }
+       }
+       
     public ISourceLocation getSourceLocation() {
         return null;
     }
@@ -1677,240 +1738,239 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
         return false;
     }
 
-    public WeaverStateInfo getWeaverState() {
-        return null;
-    }
-
-    /**
-     * Overridden by ReferenceType to return a sensible answer for parameterized and raw types.
+       public WeaverStateInfo getWeaverState() {
+               return null;
+       }
+       
+       /**
+        * Overridden by ReferenceType to return a sensible answer for parameterized and raw types.
      *
-     * @return
-     */
-    public ResolvedType getGenericType() {
-        if (!(isParameterizedType() || isRawType()))
-            throw new BCException("The type " + getBaseName() + " is not parameterized or raw - it has no generic type");
-        return null;
-    }
-
-    public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
-        if (!(isGenericType() || isParameterizedType())) return this;
-        return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
-    }
-
-    /**
-     * Iff I am a parameterized type, and any of my parameters are type variable
-     * references, return a version with those type parameters replaced in accordance
-     * with the passed bindings.
-     */
-    public UnresolvedType parameterize(Map typeBindings) {
-        if (!isParameterizedType()) throw new IllegalStateException("Can't parameterize a type that is not a parameterized type");
-        boolean workToDo = false;
-        for (int i = 0; i < typeParameters.length; i++) {
-            if (typeParameters[i].isTypeVariableReference()) {
-                workToDo = true;
-            }
-        }
-        if (!workToDo) {
-            return this;
-        } else {
-            UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
-            for (int i = 0; i < newTypeParams.length; i++) {
-                newTypeParams[i] = typeParameters[i];
-                if (newTypeParams[i].isTypeVariableReference()) {
-                    TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
-                    UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
-                    if (binding != null) newTypeParams[i] = binding;
-                }
-            }
-            return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
-        }
-    }
-
-    public boolean hasParameterizedSuperType() {
-        getParameterizedSuperTypes();
-        return parameterizedSuperTypes.length > 0;
-    }
-
-    public boolean hasGenericSuperType() {
-        ResolvedType[] superTypes = getDeclaredInterfaces();
-        for (int i = 0; i < superTypes.length; i++) {
-            if (superTypes[i].isGenericType()) return true;
-        }
-        return false;
-    }
-
-    private ResolvedType[] parameterizedSuperTypes = null;
-
-    /**
-     * Similar to the above method, but accumulates the super types
-     *
-     * @return
-     */
-    public ResolvedType[] getParameterizedSuperTypes() {
-        if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
-        List accumulatedTypes = new ArrayList();
-        accumulateParameterizedSuperTypes(this, accumulatedTypes);
-        ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
-        parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
-        return parameterizedSuperTypes;
-    }
-
-    private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
-        if (forType.isParameterizedType()) {
-            parameterizedTypeList.add(forType);
-        }
-        if (forType.getSuperclass() != null) {
-            accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList);
-        }
-        ResolvedType[] interfaces = forType.getDeclaredInterfaces();
-        for (int i = 0; i < interfaces.length; i++) {
-            accumulateParameterizedSuperTypes(interfaces[i], parameterizedTypeList);
-        }
-    }
-
-    /**
-     * Types may have pointcuts just as they have methods and fields.
-     */
-    public ResolvedPointcutDefinition findPointcut(String name, World world) {
-        throw new UnsupportedOperationException("Not yet implemenented");
-    }
-
-    /**
-     * Determines if variables of this type could be assigned values of another
-     * with lots of help.
-     * java.lang.Object is convertable from all types.
-     * A primitive type is convertable from X iff it's assignable from X.
-     * A reference type is convertable from X iff it's coerceable from X.
-     * In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y
-     * could be assignable to a variable of type X without loss of precision.
+        * @return
+        */
+       public ResolvedType getGenericType() {
+               if (!(isParameterizedType() || isRawType()))
+                       throw new BCException("The type "+getBaseName()+" is not parameterized or raw - it has no generic type");
+               return null;
+       }
+       
+       public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
+               if (!(isGenericType() || isParameterizedType())) return this;
+               return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
+       }
+       
+       /**
+        * Iff I am a parameterized type, and any of my parameters are type variable
+        * references, return a version with those type parameters replaced in accordance
+        * with the passed bindings.
+        */
+       public UnresolvedType parameterize(Map typeBindings) {
+               if (!isParameterizedType()) throw new IllegalStateException("Can't parameterize a type that is not a parameterized type");
+       boolean workToDo = false;
+       for (int i = 0; i < typeParameters.length; i++) {
+                       if (typeParameters[i].isTypeVariableReference()) {
+                               workToDo = true;
+                       }
+               }
+       if (!workToDo) {
+               return this;
+       } else {
+               UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
+               for (int i = 0; i < newTypeParams.length; i++) {
+                               newTypeParams[i] = typeParameters[i];
+                               if (newTypeParams[i].isTypeVariableReference()) {
+                                       TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
+                                       UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
+                                       if (binding != null) newTypeParams[i] = binding;
+                               }
+                       }
+               return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
+       }
+    }
+       
+       public boolean hasParameterizedSuperType() {
+               getParameterizedSuperTypes();
+               return parameterizedSuperTypes.length > 0;
+       }
+       
+       public boolean hasGenericSuperType() {
+               ResolvedType[] superTypes = getDeclaredInterfaces();
+               for (int i = 0; i < superTypes.length; i++) {
+                       if (superTypes[i].isGenericType()) return true;
+               }
+               return false;
+       }
+       
+       private ResolvedType[] parameterizedSuperTypes = null;
+       /**
+        * Similar to the above method, but accumulates the super types
      *
-     * @param other the other type
-     * @param world the {@link World} in which the possible assignment should be checked.
-     * @return true iff variables of this type could be assigned values of other with possible conversion
-     */
-    public final boolean isConvertableFrom(ResolvedType other) {
+        * @return
+        */
+       public ResolvedType[] getParameterizedSuperTypes() {
+               if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
+               List accumulatedTypes = new ArrayList();
+               accumulateParameterizedSuperTypes(this,accumulatedTypes);
+               ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
+               parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
+               return parameterizedSuperTypes;
+       }
+       
+       private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
+               if (forType.isParameterizedType()) {
+                       parameterizedTypeList.add(forType);
+               }
+               if (forType.getSuperclass() != null) {
+                       accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList);
+               }
+               ResolvedType[] interfaces = forType.getDeclaredInterfaces();
+               for (int i = 0; i < interfaces.length; i++) {
+                       accumulateParameterizedSuperTypes(interfaces[i], parameterizedTypeList);
+               }
+       }
+
+       /**
+        * Types may have pointcuts just as they have methods and fields.
+        */
+       public ResolvedPointcutDefinition findPointcut(String name, World world) {
+           throw new UnsupportedOperationException("Not yet implemenented");
+       }
+
+       /**
+        * Determines if variables of this type could be assigned values of another
+        * with lots of help.  
+        * java.lang.Object is convertable from all types.
+        * A primitive type is convertable from X iff it's assignable from X.
+        * A reference type is convertable from X iff it's coerceable from X.
+        * In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y
+        * could be assignable to a variable of type X without loss of precision. 
+        * 
+        * @param other the other type
+        * @param world the {@link World} in which the possible assignment should be checked.
+        * @return true iff variables of this type could be assigned values of other with possible conversion
+        */
+     public final boolean isConvertableFrom(ResolvedType other) {
 
 //      // version from TypeX
 //      if (this.equals(OBJECT)) return true;
 //      if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
 //      return this.isCoerceableFrom(other);
 //      
-
-        // version from ResolvedTypeX
-        if (this.equals(OBJECT)) return true;
-        if (world.isInJava5Mode()) {
-            if (this.isPrimitiveType() ^ other.isPrimitiveType()) { // If one is primitive and the other isnt
-                if (validBoxing.contains(this.getSignature() + other.getSignature())) return true;
-            }
-        }
-        if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
-        return this.isCoerceableFrom(other);
-    }
-
-    /**
-     * Determines if the variables of this type could be assigned values
-     * of another type without casting.  This still allows for assignment conversion
-     * as per JLS 2ed 5.2.  For object types, this means supertypeOrEqual(THIS, OTHER).
-     *
-     * @param other the other type
-     * @param world the {@link World} in which the possible assignment should be checked.
-     * @return true iff variables of this type could be assigned values of other without casting
+        
+        // version from ResolvedTypeX
+        if (this.equals(OBJECT)) return true;
+        if (world.isInJava5Mode()) {
+               if (this.isPrimitiveType()^other.isPrimitiveType()) { // If one is primitive and the other isnt
+                       if (validBoxing.contains(this.getSignature()+other.getSignature())) return true;
+               }
+        }
+        if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
+        return this.isCoerceableFrom(other);
+        }
+
+       /**
+        * Determines if the variables of this type could be assigned values
+        * of another type without casting.  This still allows for assignment conversion
+        * as per JLS 2ed 5.2.  For object types, this means supertypeOrEqual(THIS, OTHER).
+        * 
+        * @param other the other type
+        * @param world the {@link World} in which the possible assignment should be checked.
+        * @return true iff variables of this type could be assigned values of other without casting
      * @throws NullPointerException if other is null
-     */
-    public abstract boolean isAssignableFrom(ResolvedType other);
-
-    public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
-
-    /**
-     * Determines if values of another type could possibly be cast to
-     * this type.  The rules followed are from JLS 2ed 5.5, "Casting Conversion".
+        */
+       public abstract boolean isAssignableFrom(ResolvedType other);
+       
+       public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
+
+       /**
+        * Determines if values of another type could possibly be cast to
+        * this type.  The rules followed are from JLS 2ed 5.5, "Casting Conversion".
      * <p/>
-     * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
+        * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
      * <p/>
-     * <blockquote><pre>
-     *    a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
-     * </pre></blockquote>
-     *
-     * @param other the other type
-     * @param world the {@link World} in which the possible coersion should be checked.
-     * @return true iff values of other could possibly be cast to this type.
+        * <blockquote><pre>
+        *    a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
+        * </pre></blockquote>
+        *
+        * @param other the other type
+        * @param world the {@link World} in which the possible coersion should be checked.
+        * @return true iff values of other could possibly be cast to this type. 
      * @throws NullPointerException if other is null.
-     */
-    public abstract boolean isCoerceableFrom(ResolvedType other);
-
-    public boolean needsNoConversionFrom(ResolvedType o) {
-        return isAssignableFrom(o);
-    }
-
-    /**
+        */
+       public abstract boolean isCoerceableFrom(ResolvedType other);
+       
+       public boolean needsNoConversionFrom(ResolvedType o) {
+           return isAssignableFrom(o);
+       }
+       
+       /** 
      * Implemented by ReferenceTypes
      */
-    public String getSignatureForAttribute() {
-        throw new RuntimeException("Cannot ask this type " + this + " for a generic sig attribute");
-    }
-
-    private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE;
-
-    /**
-     * return true if the parameterization of this type includes a member type variable.  Member
-     * type variables occur in generic methods/ctors.
-     */
-    public boolean isParameterizedWithAMemberTypeVariable() {
-        // MAYBE means we haven't worked it out yet...
-        if (parameterizedWithAMemberTypeVariable == FuzzyBoolean.MAYBE) {
-
-            // if there are no type parameters then we cant be...
-            if (typeParameters == null || typeParameters.length == 0) {
-                parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
-                return false;
-            }
-
-            for (int i = 0; i < typeParameters.length; i++) {
-                UnresolvedType aType = (ResolvedType) typeParameters[i];
-                if (aType.isTypeVariableReference() && ((TypeVariableReference) aType).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
-                    parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                    return true;
-                }
-                if (aType.isParameterizedType()) {
-                    boolean b = aType.isParameterizedWithAMemberTypeVariable();
-                    if (b) {
-                        parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                        return true;
-                    }
-                }
-                if (aType.isGenericWildcard()) {
-                    if (aType.isExtends()) {
-                        boolean b = false;
-                        UnresolvedType upperBound = aType.getUpperBound();
-                        if (upperBound.isParameterizedType()) {
-                            b = upperBound.isParameterizedWithAMemberTypeVariable();
-                        } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference) upperBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
-                            b = true;
-                        }
-                        if (b) {
-                            parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                            return true;
-                        }
-                        // FIXME asc need to check additional interface bounds
-                    }
-                    if (aType.isSuper()) {
-                        boolean b = false;
-                        UnresolvedType lowerBound = aType.getLowerBound();
-                        if (lowerBound.isParameterizedType()) {
-                            b = lowerBound.isParameterizedWithAMemberTypeVariable();
-                        } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference) lowerBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
-                            b = true;
-                        }
-                        if (b) {
-                            parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
-                            return true;
-                        }
-                    }
-                }
-            }
-            parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
-        }
-        return parameterizedWithAMemberTypeVariable.alwaysTrue();
-    }
-
+       public String getSignatureForAttribute() {
+               throw new RuntimeException("Cannot ask this type "+this+" for a generic sig attribute");
+       }
+       
+       private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE;
+       
+       /**
+        * return true if the parameterization of this type includes a member type variable.  Member
+        * type variables occur in generic methods/ctors.
+        */
+       public boolean isParameterizedWithAMemberTypeVariable() {
+               // MAYBE means we haven't worked it out yet...
+               if (parameterizedWithAMemberTypeVariable==FuzzyBoolean.MAYBE) {
+                       
+                       // if there are no type parameters then we cant be...
+                       if (typeParameters==null || typeParameters.length==0) {
+                               parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
+                               return false;
+                       }
+                       
+                       for (int i = 0; i < typeParameters.length; i++) {
+                               UnresolvedType aType = (ResolvedType)typeParameters[i];
+                               if (aType.isTypeVariableReference()  && ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
+                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                                       return true;
+                               }
+                               if (aType.isParameterizedType()) {
+                                       boolean b = aType.isParameterizedWithAMemberTypeVariable();
+                                       if (b) {
+                                               parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                                               return true;
+                                       }
+                               }
+                               if (aType.isGenericWildcard()) {
+                                       if (aType.isExtends()) {
+                                               boolean b = false;
+                                               UnresolvedType upperBound = aType.getUpperBound();
+                                               if (upperBound.isParameterizedType()) {
+                                                       b = upperBound.isParameterizedWithAMemberTypeVariable();
+                                               } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference)upperBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
+                                                       b = true;
+                                               }
+                                               if (b) {
+                                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                                                       return true;
+                                               }
+                                               // FIXME asc need to check additional interface bounds
+                                       }
+                                       if (aType.isSuper()) {
+                                               boolean b = false;
+                                               UnresolvedType lowerBound = aType.getLowerBound();
+                                               if (lowerBound.isParameterizedType()) {
+                                                       b = lowerBound.isParameterizedWithAMemberTypeVariable();
+                                               } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference)lowerBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
+                                                       b = true;
+                                               }
+                                               if (b) {
+                                                       parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       }
+                       parameterizedWithAMemberTypeVariable=FuzzyBoolean.NO;
+               }
+               return parameterizedWithAMemberTypeVariable.alwaysTrue();
+       }
+           
 }
index 48af493b563fb8ec1b8b9f93c5c669aaa515ebc0..06ae53554a907bf2decab48026362aa9990a03bb 100644 (file)
@@ -321,4 +321,22 @@ public abstract class ResolvedTypeMunger {
        public boolean hasTypeVariableAliases() {
                return (typeVariableAliases!=null && typeVariableAliases.size()>0);
        }
+       
+       /**
+        * return true if type variables are specified with the target type for
+        * this ITD.  e.g. this would return true: "int I<A,B>.m() { return 42; }"
+        */
+       public boolean sharesTypeVariablesWithGenericType() {
+               return (typeVariableAliases!=null && typeVariableAliases.size()>0);
+       }
+       
+       /**
+     * Parameterizes a resolved type munger for a particular usage of
+     * its target type (this is used when the target type is generic
+     * and the ITD shares type variables with the target)
+     * see ConcreteTypeMunger.parameterizedFor
+     */
+       public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
+               throw new BCException("Should *NOT* be called for this kind of munger: "+this);
+       }
 }
index a5307831232fbd37893d38553a4881d2828e7800..2ed9e71fe09f500a397d9a522de30eceb1dbf62e 100644 (file)
@@ -1376,5 +1376,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        return false;
                }
        }
+       
+       public ConcreteTypeMunger parameterizedFor(ResolvedType target) {
+               return new BcelTypeMunger(munger.parameterizedFor(target),aspectType);
+       }
 }
                
\ No newline at end of file