]> source.dussan.org Git - aspectj.git/commitdiff
265729: fault in binary aspects for itds/decps and search for them correctly
authoraclement <aclement>
Tue, 24 Feb 2009 19:17:25 +0000 (19:17 +0000)
committeraclement <aclement>
Tue, 24 Feb 2009 19:17:25 +0000 (19:17 +0000)
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
weaver/src/org/aspectj/weaver/model/AsmRelationshipProvider.java

index 8d1ad6f8ae01e96d07d13e69983f3debd023e2a6..c93766322475588c3b6208ecae22e7d905267f38 100644 (file)
@@ -874,8 +874,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                        annotationsToAdd.add(ag);
                                                        mg.addAnnotation(decaM.getAnnotationX());
 
-                                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationMethodRelationship(decaM.getSourceLocation(),
-                                                                       clazz.getName(), mg.getMemberView(), world.getModelAsAsmManager());// getMethod());
+                                                       AsmRelationshipProvider.addDeclareAnnotationMethodRelationship(decaM.getSourceLocation(), clazz
+                                                                       .getName(), mg.getMemberView(), world.getModelAsAsmManager());// getMethod());
                                                        reportMethodCtorWeavingMessage(clazz, mg.getMemberView(), decaM, mg.getDeclarationLineNumber());
                                                        isChanged = true;
                                                        modificationOccured = true;
@@ -918,9 +918,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                                annotationsToAdd.add(a);
 
                                                                mg.addAnnotation(decaM.getAnnotationX());
-                                                               AsmRelationshipProvider.getDefault().addDeclareAnnotationMethodRelationship(
-                                                                               decaM.getSourceLocation(), clazz.getName(), mg.getMemberView(),
-                                                                               world.getModelAsAsmManager());// getMethod());
+                                                               AsmRelationshipProvider.addDeclareAnnotationMethodRelationship(decaM.getSourceLocation(), clazz
+                                                                               .getName(), mg.getMemberView(), world.getModelAsAsmManager());// getMethod());
                                                                isChanged = true;
                                                                modificationOccured = true;
                                                                forRemoval.add(decaM);
@@ -1093,8 +1092,8 @@ class BcelClassWeaver implements IClassWeaver {
                                        if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors))
                                                continue; // skip this one...
                                        annotationHolder.addAnnotation(decaF.getAnnotationX());
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
-                                                       decaF.getSourceLocation(), itdIsActually.getSourceLocation());
+                                       AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decaF
+                                                       .getSourceLocation(), itdIsActually.getSourceLocation());
                                        isChanged = true;
                                        modificationOccured = true;
 
@@ -1116,8 +1115,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors))
                                                        continue; // skip this one...
                                                annotationHolder.addAnnotation(decaF.getAnnotationX());
-                                               AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
-                                                               decaF.getSourceLocation(), itdIsActually.getSourceLocation());
+                                               AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decaF
+                                                               .getSourceLocation(), itdIsActually.getSourceLocation());
                                                isChanged = true;
                                                modificationOccured = true;
                                                forRemoval.add(decaF);
@@ -1152,7 +1151,7 @@ class BcelClassWeaver implements IClassWeaver {
                                        }
                                        annotationHolder.addAnnotation(decaMC.getAnnotationX());
                                        isChanged = true;
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
+                                       AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
                                                        unMangledInterMethod.getSourceLocation());
                                        reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC, -1);
                                        modificationOccured = true;
@@ -1175,8 +1174,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                        continue; // skip this one...
                                                annotationHolder.addAnnotation(decaMC.getAnnotationX());
                                                unMangledInterMethod.addAnnotation(decaMC.getAnnotationX());
-                                               AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(asmManager,
-                                                               decaMC.getSourceLocation(), unMangledInterMethod.getSourceLocation());
+                                               AsmRelationshipProvider.addDeclareAnnotationRelationship(asmManager, decaMC.getSourceLocation(),
+                                                               unMangledInterMethod.getSourceLocation());
                                                isChanged = true;
                                                modificationOccured = true;
                                                forRemoval.add(decaMC);
@@ -1294,8 +1293,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                                }
                                                        }
 
-                                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationFieldRelationship(
-                                                                       world.getModelAsAsmManager(), decaF.getSourceLocation(), clazz.getName(), aBcelField);// .getFieldAsIs());
+                                                       AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(), decaF
+                                                                       .getSourceLocation(), clazz.getName(), aBcelField);
                                                        reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);
                                                        isChanged = true;
                                                        modificationOccured = true;
@@ -1329,8 +1328,8 @@ class BcelClassWeaver implements IClassWeaver {
                                                                        continue; // skip this one...
                                                                }
                                                                aBcelField.addAnnotation(decaF.getAnnotationX());
-                                                               AsmRelationshipProvider.getDefault().addDeclareAnnotationFieldRelationship(
-                                                                               world.getModelAsAsmManager(), decaF.getSourceLocation(), clazz.getName(), aBcelField);// .getFieldAsIs());
+                                                               AsmRelationshipProvider.addDeclareAnnotationFieldRelationship(world.getModelAsAsmManager(), decaF
+                                                                               .getSourceLocation(), clazz.getName(), aBcelField);
                                                                isChanged = true;
                                                                modificationOccured = true;
                                                                forRemoval.add(decaF);
index 97d462b12def9f8ed0be74b9e2b5d2bb629fe6cb..5ed1f4df6218687a2f826c5fdbb8e7119527e349 100644 (file)
@@ -121,8 +121,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                }
 
                if (changed && worthReporting) {
-                       AsmRelationshipProvider.getDefault().addRelationship(((BcelWorld) getWorld()).getModelAsAsmManager(),
-                                       weaver.getLazyClassGen().getType(), munger, getAspectType());
+                       AsmRelationshipProvider.addRelationship(((BcelWorld) getWorld()).getModelAsAsmManager(), weaver.getLazyClassGen()
+                                       .getType(), munger, getAspectType());
                }
 
                // TAG: WeavingMessage
index f5298dd11724ce6ca0c2b120439793ed17ac33dc..44f4713faaa7079ca594eeb9edcbfe7b2db89ef6 100644 (file)
@@ -1598,8 +1598,8 @@ public class BcelWeaver {
                        boolean problemReported = verifyTargetIsOK(decA, onType, annoX, reportProblems);
 
                        if (!problemReported) {
-                               AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(world.getModelAsAsmManager(),
-                                               decA.getSourceLocation(), onType.getSourceLocation());
+                               AsmRelationshipProvider.addDeclareAnnotationRelationship(world.getModelAsAsmManager(), decA.getSourceLocation(),
+                                               onType.getSourceLocation());
                                // TAG: WeavingMessage
                                if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
                                        getWorld().getMessageHandler().handleMessage(
index 1d9b92d6e607eee24d1296607cad71db30f3ae02..95d6ecb732bb09ee79502d11efc736c91d980044 100644 (file)
@@ -132,14 +132,12 @@ public class BcelWorld extends World implements Repository {
                                        );
                }
 
-               // TAG: WeavingMessage
                if (!getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
                        reportWeavingMessage(munger, shadow);
                }
 
                if (getModel() != null) {
-                       // System.err.println("munger: " + munger + " on " + this);
-                       AsmRelationshipProvider.adviceMunger(getModelAsAsmManager(), shadow, munger);
+                       AsmRelationshipProvider.addAdvisedRelationship(getModelAsAsmManager(), shadow, munger);
                }
        }
 
@@ -795,7 +793,7 @@ public class BcelWorld extends World implements Repository {
                }
 
                if (getModel() != null) {
-                       AsmRelationshipProvider.checkerMunger(getModelAsAsmManager(), shadow, checker);
+                       AsmRelationshipProvider.addDeclareErrorOrWarningRelationship(getModelAsAsmManager(), shadow, checker);
                }
 
        }
index fdc7030ff7e77f172a0cd315967979b580787016..ebbf7d4128685c211867ecd045c213dce8e0ea34 100644 (file)
 
 package org.aspectj.weaver.model;
 
+import java.io.File;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 
 import org.aspectj.asm.AsmManager;
 import org.aspectj.asm.IHierarchy;
@@ -30,6 +33,7 @@ import org.aspectj.weaver.AdviceKind;
 import org.aspectj.weaver.Checker;
 import org.aspectj.weaver.Lint;
 import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ReferenceType;
 import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedType;
@@ -39,13 +43,13 @@ import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelShadow;
+import org.aspectj.weaver.bcel.BcelTypeMunger;
 import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
+import org.aspectj.weaver.patterns.DeclareParents;
 import org.aspectj.weaver.patterns.Pointcut;
 
 public class AsmRelationshipProvider {
 
-       protected static AsmRelationshipProvider INSTANCE = new AsmRelationshipProvider();
-
        public static final String ADVISES = "advises";
        public static final String ADVISED_BY = "advised by";
        public static final String DECLARES_ON = "declares on";
@@ -60,66 +64,92 @@ public class AsmRelationshipProvider {
        public static final String ANNOTATES = "annotates";
        public static final String ANNOTATED_BY = "annotated by";
 
-       public static void checkerMunger(AsmManager asm, Shadow shadow, Checker checker) {
-               if (asm == null) // !AsmManager.isCreatingModel())
+       /**
+        * Add a relationship for a declare error or declare warning
+        */
+       public static void addDeclareErrorOrWarningRelationship(AsmManager model, Shadow affectedShadow, Checker deow) {
+               if (model == null) {
                        return;
-               if (shadow.getSourceLocation() == null || checker.getSourceLocation() == null)
+               }
+               if (affectedShadow.getSourceLocation() == null || deow.getSourceLocation() == null) {
                        return;
+               }
 
                if (World.createInjarHierarchy) {
-                       createHierarchy(asm, checker);
+                       createHierarchyForBinaryAspect(model, deow);
                }
 
-               // Ensure a node for the target exists
-               IProgramElement targetNode = getNode(asm, shadow);
-               if (targetNode == null)
+               IProgramElement targetNode = getNode(model, affectedShadow);
+               if (targetNode == null) {
                        return;
-               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
-               if (targetHandle == null)
+               }
+               String targetHandle = model.getHandleProvider().createHandleIdentifier(targetNode);
+               if (targetHandle == null) {
                        return;
+               }
 
-               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(checker.getSourceLocation());
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
+               IProgramElement sourceNode = model.getHierarchy().findElementForSourceLine(deow.getSourceLocation());
+               String sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null) {
                        return;
+               }
 
-               IRelationshipMap mapper = asm.getRelationshipMap();
-               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY, false, true);
+               IRelationshipMap relmap = model.getRelationshipMap();
+               IRelationship foreward = relmap.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY, false, true);
                foreward.addTarget(targetHandle);
 
-               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE, false, true);
+               IRelationship back = relmap.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE, false, true);
                if (back != null && back.getTargets() != null) {
                        back.addTarget(sourceHandle);
                }
                if (sourceNode.getSourceLocation() != null) {
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+                       model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
                }
-
        }
 
-       // For ITDs
-       public void addRelationship(AsmManager asm, ResolvedType onType, ResolvedTypeMunger munger, ResolvedType originatingAspect) {
-
-               if (asm == null)// !AsmManager.isCreatingModel())
+       /**
+        * Add a relationship for a type transformation (declare parents, intertype method declaration, declare annotation on type).
+        */
+       public static void addRelationship(AsmManager model, ResolvedType onType, ResolvedTypeMunger typeTransformer,
+                       ResolvedType originatingAspect) {
+               if (model == null) {
                        return;
+               }
+
+               if (World.createInjarHierarchy && isBinaryAspect(originatingAspect)) {
+                       createHierarchy(model, typeTransformer, originatingAspect);
+               }
+
                if (originatingAspect.getSourceLocation() != null) {
                        String sourceHandle = "";
                        IProgramElement sourceNode = null;
-                       if (munger.getSourceLocation() != null && munger.getSourceLocation().getOffset() != -1) {
-                               sourceNode = asm.getHierarchy().findElementForSourceLine(munger.getSourceLocation());
-                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+                       if (typeTransformer.getSourceLocation() != null && typeTransformer.getSourceLocation().getOffset() != -1) {
+                               sourceNode = model.getHierarchy().findElementForType(originatingAspect.getPackageName(),
+                                               originatingAspect.getClassName());
+                               IProgramElement closer = model.getHierarchy().findCloserMatchForLineNumber(sourceNode,
+                                               typeTransformer.getSourceLocation().getLine());
+                               if (closer != null) {
+                                       sourceNode = closer;
+                               }
+                               sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
                        } else {
-                               sourceNode = asm.getHierarchy().findElementForSourceLine(originatingAspect.getSourceLocation());
-                               sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
+                               sourceNode = model.getHierarchy().findElementForType(originatingAspect.getPackageName(),
+                                               originatingAspect.getClassName());
+                               // sourceNode = asm.getHierarchy().findElementForSourceLine(originatingAspect.getSourceLocation());
+                               sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
                        }
+                       // sourceNode = asm.getHierarchy().findElementForType(originatingAspect.getPackageName(),
+                       // originatingAspect.getClassName());
+                       // // sourceNode = asm.getHierarchy().findElementForSourceLine(munger.getSourceLocation());
+                       // sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
                        if (sourceHandle == null)
                                return;
-                       IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(onType.getSourceLocation());
-                       String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
+                       IProgramElement targetNode = model.getHierarchy().findElementForSourceLine(onType.getSourceLocation());
+                       String targetHandle = model.getHandleProvider().createHandleIdentifier(targetNode);
                        if (targetHandle == null)
                                return;
 
-                       IRelationshipMap mapper = asm.getRelationshipMap();
+                       IRelationshipMap mapper = model.getRelationshipMap();
                        IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false,
                                        true);
                        foreward.addTarget(targetHandle);
@@ -127,78 +157,205 @@ public class AsmRelationshipProvider {
                        IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
                                        true);
                        back.addTarget(sourceHandle);
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+                       model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
                }
        }
 
-       // public void addDeclareParentsRelationship(ISourceLocation decp,
-       // ResolvedType targetType, List newParents) {
-       // if (!AsmManager.isCreatingModel())
-       // return;
-       //
-       // IProgramElement sourceNode =
-       // AsmManager.getDefault().getHierarchy().findElementForSourceLine(decp);
-       // String sourceHandle =
-       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
-       // (sourceNode);
-       // if (sourceHandle == null)
-       // return;
-       //
-       // IProgramElement targetNode = AsmManager.getDefault().getHierarchy()
-       // .findElementForSourceLine(targetType.getSourceLocation());
-       // String targetHandle =
-       // AsmManager.getDefault().getHandleProvider().createHandleIdentifier
-       // (targetNode);
-       // if (targetHandle == null)
-       // return;
-       //
-       // IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap();
-       // IRelationship foreward = mapper.get(sourceHandle,
-       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false, true);
-       // foreward.addTarget(targetHandle);
-       //
-       // IRelationship back = mapper.get(targetHandle,
-       // IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false,
-       // true);
-       // back.addTarget(sourceHandle);
-       // }
+       private static boolean isBinaryAspect(ResolvedType aspect) {
+               return aspect.getBinaryPath() != null;
+       }
+
+       /**
+        * Returns the binarySourceLocation for the given sourcelocation. This isn't cached because it's used when faulting in the
+        * binary nodes and is called with ISourceLocations for all advice, pointcuts and deows contained within the
+        * resolvedDeclaringAspect.
+        */
+       private static ISourceLocation getBinarySourceLocation(ResolvedType aspect, ISourceLocation sl) {
+               if (sl == null) {
+                       return null;
+               }
+               String sourceFileName = null;
+               if (aspect instanceof ReferenceType) {
+                       String s = ((ReferenceType) aspect).getDelegate().getSourcefilename();
+                       int i = s.lastIndexOf('/');
+                       if (i != -1) {
+                               sourceFileName = s.substring(i + 1);
+                       } else {
+                               sourceFileName = s;
+                       }
+               }
+               ISourceLocation sLoc = new SourceLocation(getBinaryFile(aspect), sl.getLine(), sl.getEndLine(),
+                               ((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourceFileName);
+               return sLoc;
+       }
+
+       private static ISourceLocation createSourceLocation(String sourcefilename, ResolvedType aspect, ISourceLocation sl) {
+               ISourceLocation sLoc = new SourceLocation(getBinaryFile(aspect), sl.getLine(), sl.getEndLine(),
+                               ((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourcefilename);
+               return sLoc;
+       }
+
+       private static String getSourceFileName(ResolvedType aspect) {
+               String sourceFileName = null;
+               if (aspect instanceof ReferenceType) {
+                       String s = ((ReferenceType) aspect).getDelegate().getSourcefilename();
+                       int i = s.lastIndexOf('/');
+                       if (i != -1) {
+                               sourceFileName = s.substring(i + 1);
+                       } else {
+                               sourceFileName = s;
+                       }
+               }
+               return sourceFileName;
+       }
+
+       /**
+        * Returns the File with pathname to the class file, for example either C:\temp
+        * \ajcSandbox\workspace\ajcTest16957.tmp\simple.jar!pkg\BinaryAspect.class if the class file is in a jar file, or
+        * C:\temp\ajcSandbox\workspace\ajcTest16957.tmp!pkg\BinaryAspect.class if the class file is in a directory
+        */
+       private static File getBinaryFile(ResolvedType aspect) {
+               String s = aspect.getBinaryPath();
+               File f = aspect.getSourceLocation().getSourceFile();
+               // Replace the source file suffix with .class
+               int i = f.getPath().lastIndexOf('.');
+               String path = null;
+               if (i != -1) {
+                       path = f.getPath().substring(0, i) + ".class";
+               } else {
+                       path = f.getPath() + ".class";
+               }
+               return new File(s + "!" + path);
+       }
+
+       /**
+        * Create a basic hierarchy to represent an aspect only available in binary (from the aspectpath).
+        */
+       private static void createHierarchy(AsmManager model, ResolvedTypeMunger typeTransformer, ResolvedType aspect) {
+               assert aspect != null;
+
+               // Check if already defined in the model
+               // IProgramElement filenode = model.getHierarchy().findElementForType(aspect.getPackageName(), aspect.getClassName());
+               // SourceLine(typeTransformer.getSourceLocation());
+               IProgramElement filenode = model.getHierarchy().findElementForSourceLine(typeTransformer.getSourceLocation());
+               // the call to findElementForSourceLine(ISourceLocation) returns a file
+               // node
+               // if it can't find a node in the hierarchy for the given
+               // sourcelocation.
+               // Therefore, if this is returned, we know we can't find one and have to
+               // // continue to fault in the model.
+               // if (filenode != null) { //
+               if (!filenode.getKind().equals(IProgramElement.Kind.FILE_JAVA)) {
+                       return;
+               }
+
+               // create the class file node
+               IProgramElement classFileNode = new ProgramElement(model, filenode.getName(), IProgramElement.Kind.FILE,
+                               getBinarySourceLocation(aspect, aspect.getSourceLocation()), 0, null, null);
+
+               // create package ipe if one exists....
+               IProgramElement root = model.getHierarchy().getRoot();
+               IProgramElement binaries = model.getHierarchy().findElementForLabel(root, IProgramElement.Kind.SOURCE_FOLDER, "binaries");
+               if (binaries == null) {
+                       binaries = new ProgramElement(model, "binaries", IProgramElement.Kind.SOURCE_FOLDER, new ArrayList());
+                       root.addChild(binaries);
+               }
+               // if (aspect.getPackageName() != null) {
+               String packagename = aspect.getPackageName() == null ? "" : aspect.getPackageName();
+               // check that there doesn't already exist a node with this name
+               IProgramElement pkgNode = model.getHierarchy().findElementForLabel(binaries, IProgramElement.Kind.PACKAGE, packagename);
+               // note packages themselves have no source location
+               if (pkgNode == null) {
+                       pkgNode = new ProgramElement(model, packagename, IProgramElement.Kind.PACKAGE, new ArrayList());
+                       binaries.addChild(pkgNode);
+                       pkgNode.addChild(classFileNode);
+               } else {
+                       // need to add it first otherwise the handle for classFileNode
+                       // may not be generated correctly if it uses information from
+                       // it's parent node
+                       pkgNode.addChild(classFileNode);
+                       for (Iterator iter = pkgNode.getChildren().iterator(); iter.hasNext();) {
+                               IProgramElement element = (IProgramElement) iter.next();
+                               if (!element.equals(classFileNode) && element.getHandleIdentifier().equals(classFileNode.getHandleIdentifier())) {
+                                       // already added the classfile so have already
+                                       // added the structure for this aspect
+                                       pkgNode.removeChild(classFileNode);
+                                       return;
+                               }
+                       }
+               }
+               // } else {
+               // // need to add it first otherwise the handle for classFileNode
+               // // may not be generated correctly if it uses information from
+               // // it's parent node
+               // root.addChild(classFileNode);
+               // for (Iterator iter = root.getChildren().iterator(); iter.hasNext();) {
+               // IProgramElement element = (IProgramElement) iter.next();
+               // if (!element.equals(classFileNode) && element.getHandleIdentifier().equals(classFileNode.getHandleIdentifier())) {
+               // // already added the sourcefile so have already
+               // // added the structure for this aspect
+               // root.removeChild(classFileNode);
+               // return;
+               // }
+               // }
+               // }
+
+               // add and create empty import declaration ipe
+               classFileNode.addChild(new ProgramElement(model, "import declarations", IProgramElement.Kind.IMPORT_REFERENCE, null, 0,
+                               null, null));
+
+               // add and create aspect ipe
+               IProgramElement aspectNode = new ProgramElement(model, aspect.getSimpleName(), IProgramElement.Kind.ASPECT,
+                               getBinarySourceLocation(aspect, aspect.getSourceLocation()), aspect.getModifiers(), null, null);
+               classFileNode.addChild(aspectNode);
+
+               addChildNodes(model, aspect, aspectNode, aspect.getDeclaredPointcuts());
+
+               addChildNodes(model, aspect, aspectNode, aspect.getDeclaredAdvice());
+               addChildNodes(model, aspect, aspectNode, aspect.getDeclares());
+               addChildNodes(model, aspect, aspectNode, aspect.getTypeMungers());
+       }
 
        /**
         * Adds a declare annotation relationship, sometimes entities don't have source locs (methods/fields) so use other variants of
         * this method if that is the case as they will look the entities up in the structure model.
         */
-       public void addDeclareAnnotationRelationship(AsmManager asm, ISourceLocation declareAnnotationLocation,
+       public static void addDeclareAnnotationRelationship(AsmManager model, ISourceLocation declareAnnotationLocation,
                        ISourceLocation annotatedLocation) {
-               if (asm == null) // !AsmManager.isCreatingModel())
+               if (model == null) {
                        return;
+               }
 
-               IProgramElement sourceNode = asm.getHierarchy().findElementForSourceLine(declareAnnotationLocation);
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
+               IProgramElement sourceNode = model.getHierarchy().findElementForSourceLine(declareAnnotationLocation);
+               String sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null) {
                        return;
+               }
 
-               IProgramElement targetNode = asm.getHierarchy().findElementForSourceLine(annotatedLocation);
-               String targetHandle = asm.getHandleProvider().createHandleIdentifier(targetNode);
-               if (targetHandle == null)
+               IProgramElement targetNode = model.getHierarchy().findElementForSourceLine(annotatedLocation);
+               String targetHandle = model.getHandleProvider().createHandleIdentifier(targetNode);
+               if (targetHandle == null) {
                        return;
+               }
 
-               IRelationshipMap mapper = asm.getRelationshipMap();
+               IRelationshipMap mapper = model.getRelationshipMap();
                IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
                foreward.addTarget(targetHandle);
 
                IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
                back.addTarget(sourceHandle);
                if (sourceNode.getSourceLocation() != null) {
-                       asm.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
+                       model.addAspectInEffectThisBuild(sourceNode.getSourceLocation().getSourceFile());
                }
        }
 
        /**
         * Creates the hierarchy for binary aspects
         */
-       public static void createHierarchy(AsmManager asm, ShadowMunger munger) {
-               if (!munger.isBinary())
+       public static void createHierarchyForBinaryAspect(AsmManager asm, ShadowMunger munger) {
+               if (!munger.isBinary()) {
                        return;
+               }
 
                IProgramElement sourceFileNode = asm.getHierarchy().findElementForSourceLine(munger.getSourceLocation());
                // the call to findElementForSourceLine(ISourceLocation) returns a file
@@ -273,13 +430,36 @@ public class AsmRelationshipProvider {
                                .getBinarySourceLocation(aspect.getSourceLocation()), aspect.getModifiers(), null, null);
                classFileNode.addChild(aspectNode);
 
-               addChildNodes(asm, munger, aspectNode, aspect.getDeclaredPointcuts());
+               String sourcefilename = getSourceFileName(aspect);
+               addPointcuts(asm, sourcefilename, aspect, aspectNode, aspect.getDeclaredPointcuts());
+               addChildNodes(asm, aspect, aspectNode, aspect.getDeclaredAdvice());
+               addChildNodes(asm, aspect, aspectNode, aspect.getDeclares());
+               addChildNodes(asm, aspect, aspectNode, aspect.getTypeMungers());
 
-               addChildNodes(asm, munger, aspectNode, aspect.getDeclaredAdvice());
-               addChildNodes(asm, munger, aspectNode, aspect.getDeclares());
        }
 
-       private static void addChildNodes(AsmManager asm, ShadowMunger munger, IProgramElement parent, ResolvedMember[] children) {
+       private static void addPointcuts(AsmManager model, String sourcefilename, ResolvedType aspect,
+                       IProgramElement containingAspect, ResolvedMember[] pointcuts) {
+               for (int i = 0; i < pointcuts.length; i++) {
+                       ResolvedMember pointcut = pointcuts[i];
+                       if (pointcut instanceof ResolvedPointcutDefinition) {
+                               ResolvedPointcutDefinition rpcd = (ResolvedPointcutDefinition) pointcut;
+                               Pointcut p = rpcd.getPointcut();
+                               ISourceLocation sLoc = (p == null ? null : p.getSourceLocation());
+                               if (sLoc == null) {
+                                       sLoc = rpcd.getSourceLocation();
+                               }
+                               ISourceLocation pointcutLocation = createSourceLocation(sourcefilename, aspect, sLoc);
+                               ProgramElement pointcutElement = new ProgramElement(model, pointcut.getName(), IProgramElement.Kind.POINTCUT,
+                                               pointcutLocation, pointcut.getModifiers(), NO_COMMENT, Collections.EMPTY_LIST);
+                               containingAspect.addChild(pointcutElement);
+                       }
+               }
+       }
+
+       private static final String NO_COMMENT = null;
+
+       private static void addChildNodes(AsmManager asm, ResolvedType aspect, IProgramElement parent, ResolvedMember[] children) {
                for (int i = 0; i < children.length; i++) {
                        ResolvedMember pcd = children[i];
                        if (pcd instanceof ResolvedPointcutDefinition) {
@@ -289,13 +469,13 @@ public class AsmRelationshipProvider {
                                if (sLoc == null) {
                                        sLoc = rpcd.getSourceLocation();
                                }
-                               parent.addChild(new ProgramElement(asm, pcd.getName(), IProgramElement.Kind.POINTCUT, munger
-                                               .getBinarySourceLocation(sLoc), pcd.getModifiers(), null, Collections.EMPTY_LIST));
+                               parent.addChild(new ProgramElement(asm, pcd.getName(), IProgramElement.Kind.POINTCUT, getBinarySourceLocation(
+                                               aspect, sLoc), pcd.getModifiers(), null, Collections.EMPTY_LIST));
                        }
                }
        }
 
-       private static void addChildNodes(AsmManager asm, ShadowMunger munger, IProgramElement parent, Collection children) {
+       private static void addChildNodes(AsmManager asm, ResolvedType aspect, IProgramElement parent, Collection children) {
                int deCtr = 1;
                int dwCtr = 1;
                for (Iterator iter = children.iterator(); iter.hasNext();) {
@@ -308,18 +488,34 @@ public class AsmRelationshipProvider {
                                } else {
                                        counter = dwCtr++;
                                }
-                               parent.addChild(createDeclareErrorOrWarningChild(asm, munger, decl, counter));
+                               parent.addChild(createDeclareErrorOrWarningChild(asm, aspect, decl, counter));
                        } else if (element instanceof Advice) {
                                Advice advice = (Advice) element;
                                parent.addChild(createAdviceChild(asm, advice));
+                       } else if (element instanceof DeclareParents) {
+                               parent.addChild(createDeclareParentsChild(asm, (DeclareParents) element));
+                       } else if (element instanceof BcelTypeMunger) {
+                               parent.addChild(createIntertypeDeclaredChild(asm, aspect, (BcelTypeMunger) element));
                        }
                }
        }
 
-       private static IProgramElement createDeclareErrorOrWarningChild(AsmManager asm, ShadowMunger munger,
+       // private static IProgramElement createDeclareErrorOrWarningChild(AsmManager asm, ShadowMunger munger,
+       // DeclareErrorOrWarning decl, int count) {
+       // IProgramElement deowNode = new ProgramElement(asm, decl.getName(), decl.isError() ? IProgramElement.Kind.DECLARE_ERROR
+       // : IProgramElement.Kind.DECLARE_WARNING, munger.getBinarySourceLocation(decl.getSourceLocation()), decl
+       // .getDeclaringType().getModifiers(), null, null);
+       // deowNode.setDetails("\"" + AsmRelationshipUtils.genDeclareMessage(decl.getMessage()) + "\"");
+       // if (count != -1) {
+       // deowNode.setBytecodeName(decl.getName() + "_" + count);
+       // }
+       // return deowNode;
+       // }
+
+       private static IProgramElement createDeclareErrorOrWarningChild(AsmManager model, ResolvedType aspect,
                        DeclareErrorOrWarning decl, int count) {
-               IProgramElement deowNode = new ProgramElement(asm, decl.getName(), decl.isError() ? IProgramElement.Kind.DECLARE_ERROR
-                               : IProgramElement.Kind.DECLARE_WARNING, munger.getBinarySourceLocation(decl.getSourceLocation()), decl
+               IProgramElement deowNode = new ProgramElement(model, decl.getName(), decl.isError() ? IProgramElement.Kind.DECLARE_ERROR
+                               : IProgramElement.Kind.DECLARE_WARNING, getBinarySourceLocation(aspect, decl.getSourceLocation()), decl
                                .getDeclaringType().getModifiers(), null, null);
                deowNode.setDetails("\"" + AsmRelationshipUtils.genDeclareMessage(decl.getMessage()) + "\"");
                if (count != -1) {
@@ -328,21 +524,59 @@ public class AsmRelationshipProvider {
                return deowNode;
        }
 
-       private static IProgramElement createAdviceChild(AsmManager asm, Advice advice) {
-               IProgramElement adviceNode = new ProgramElement(asm, advice.getKind().getName(), IProgramElement.Kind.ADVICE, advice
+       private static IProgramElement createAdviceChild(AsmManager model, Advice advice) {
+               IProgramElement adviceNode = new ProgramElement(model, advice.getKind().getName(), IProgramElement.Kind.ADVICE, advice
                                .getBinarySourceLocation(advice.getSourceLocation()), advice.getSignature().getModifiers(), null,
                                Collections.EMPTY_LIST);
                adviceNode.setDetails(AsmRelationshipUtils.genPointcutDetails(advice.getPointcut()));
                adviceNode.setBytecodeName(advice.getSignature().getName());
-               // String nn = advice.getSignature().getName();
-               // if (counter != 1) {
-               // adviceNode.setBytecodeName(advice.getKind().getName() + "$"
-               // + counter + "$");
-               // }
                return adviceNode;
        }
 
-       public static String getHandle(Advice advice, AsmManager asm) {
+       /**
+        * Half baked implementation - will need completing if we go down this route rather than replacing it all for binary aspects
+        */
+       private static IProgramElement createIntertypeDeclaredChild(AsmManager model, ResolvedType aspect, BcelTypeMunger itd) {
+               ResolvedTypeMunger rtMunger = itd.getMunger();
+               if (rtMunger.getKind() == ResolvedTypeMunger.Field) {
+                       String name = rtMunger.getSignature().toString();
+                       IProgramElement newElement = new ProgramElement(model, name, IProgramElement.Kind.INTER_TYPE_FIELD,
+                                       getBinarySourceLocation(aspect, itd.getSourceLocation()), rtMunger.getSignature().getModifiers(), null,
+                                       Collections.EMPTY_LIST);
+                       return newElement;
+               } else if (rtMunger.getKind() == ResolvedTypeMunger.Method) {
+                       ResolvedMember sig = rtMunger.getSignature();
+                       String name = sig.getDeclaringType() + "." + sig.getName();
+                       if (name.indexOf("$") != -1) {
+                               name = name.substring(name.indexOf("$") + 1);
+                       }
+                       IProgramElement pe = new ProgramElement(model, name, IProgramElement.Kind.INTER_TYPE_METHOD, getBinarySourceLocation(
+                                       aspect, itd.getSourceLocation()), rtMunger.getSignature().getModifiers(), null, Collections.EMPTY_LIST);
+                       UnresolvedType[] ts = sig.getParameterTypes();
+                       if (ts == null) {
+                               pe.setParameterNames(Collections.EMPTY_LIST);
+                               pe.setParameterSignatures(Collections.EMPTY_LIST);
+                       } else {
+                               List paramSigs = new ArrayList();
+                               for (int i = 0; i < ts.length; i++) {
+                                       paramSigs.add(ts[i].getSignature().toCharArray());
+                               }
+                               pe.setParameterSignatures(paramSigs);
+                       }
+                       return pe;
+               }
+               // other cases ignored for now
+               return null;
+       }
+
+       private static IProgramElement createDeclareParentsChild(AsmManager model, DeclareParents decp) {
+               IProgramElement decpElement = new ProgramElement(model, "declare parents", IProgramElement.Kind.DECLARE_PARENTS,
+                               getBinarySourceLocation(decp.getDeclaringType(), decp.getSourceLocation()), Modifier.PUBLIC, null,
+                               Collections.EMPTY_LIST);
+               return decpElement;
+       }
+
+       public static String getHandle(AsmManager asm, Advice advice) {
                if (null == advice.handle) {
                        ISourceLocation sl = advice.getSourceLocation();
                        if (sl != null) {
@@ -353,9 +587,11 @@ public class AsmRelationshipProvider {
                return advice.handle;
        }
 
-       public static void adviceMunger(AsmManager asm, Shadow shadow, ShadowMunger munger) {
-               if (asm == null) // !AsmManager.isCreatingModel())
+       public static void addAdvisedRelationship(AsmManager model, Shadow matchedShadow, ShadowMunger munger) {
+               if (model == null) {
                        return;
+               }
+
                if (munger instanceof Advice) {
                        Advice advice = (Advice) munger;
 
@@ -365,55 +601,52 @@ public class AsmRelationshipProvider {
                        }
 
                        if (World.createInjarHierarchy) {
-                               createHierarchy(asm, advice);
+                               createHierarchyForBinaryAspect(model, advice);
                        }
 
-                       IRelationshipMap mapper = asm.getRelationshipMap();
-                       IProgramElement targetNode = getNode(asm, shadow);
-                       if (targetNode == null)
+                       IRelationshipMap mapper = model.getRelationshipMap();
+                       IProgramElement targetNode = getNode(model, matchedShadow);
+                       if (targetNode == null) {
                                return;
+                       }
                        boolean runtimeTest = advice.hasDynamicTests();
 
-                       // Work out extra info to inform interested UIs !
-                       IProgramElement.ExtraInformation ai = new IProgramElement.ExtraInformation();
+                       IProgramElement.ExtraInformation extra = new IProgramElement.ExtraInformation();
 
-                       String adviceHandle = getHandle(advice, asm);
-                       if (adviceHandle == null)
+                       String adviceHandle = getHandle(model, advice);
+                       if (adviceHandle == null) {
                                return;
+                       }
 
-                       // What kind of advice is it?
-                       // TODO: Prob a better way to do this but I just want to
-                       // get it into CVS !!!
-                       AdviceKind ak = ((Advice) munger).getKind();
-                       ai.setExtraAdviceInformation(ak.getName());
-                       IProgramElement adviceElement = asm.getHierarchy().findElementForHandle(adviceHandle);
+                       extra.setExtraAdviceInformation(advice.getKind().getName());
+                       IProgramElement adviceElement = model.getHierarchy().findElementForHandle(adviceHandle);
                        if (adviceElement != null) {
-                               adviceElement.setExtraInfo(ai);
+                               adviceElement.setExtraInfo(extra);
                        }
                        String targetHandle = targetNode.getHandleIdentifier();
                        if (advice.getKind().equals(AdviceKind.Softener)) {
                                IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.DECLARE_SOFT, SOFTENS, runtimeTest, true);
-                               if (foreward != null)
-                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
-                               // (targetHandle);
+                               if (foreward != null) {
+                                       foreward.addTarget(targetHandle);
+                               }
 
                                IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, SOFTENED_BY, runtimeTest, true);
-                               if (back != null)
-                                       back.addTarget(adviceHandle);// back.getTargets().add(
-                               // adviceHandle);
+                               if (back != null) {
+                                       back.addTarget(adviceHandle);
+                               }
                        } else {
                                IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.ADVICE, ADVISES, runtimeTest, true);
-                               if (foreward != null)
-                                       foreward.addTarget(targetHandle);// foreward.getTargets().add
-                               // (targetHandle);
+                               if (foreward != null) {
+                                       foreward.addTarget(targetHandle);
+                               }
 
                                IRelationship back = mapper.get(targetHandle, IRelationship.Kind.ADVICE, ADVISED_BY, runtimeTest, true);
-                               if (back != null)
-                                       back.addTarget(adviceHandle);// back.getTargets().add(
-                               // adviceHandle);
+                               if (back != null) {
+                                       back.addTarget(adviceHandle);
+                               }
                        }
                        if (adviceElement.getSourceLocation() != null) {
-                               asm.addAspectInEffectThisBuild(adviceElement.getSourceLocation().getSourceFile());
+                               model.addAspectInEffectThisBuild(adviceElement.getSourceLocation().getSourceFile());
                        }
                }
        }
@@ -460,7 +693,8 @@ public class AsmRelationshipProvider {
 
                Member shadowSig = shadow.getSignature();
                // pr235204
-               if (shadow.getKind() == Shadow.MethodCall || shadow.getKind()==Shadow.ConstructorCall || !shadowSig.equals(enclosingMember)) {
+               if (shadow.getKind() == Shadow.MethodCall || shadow.getKind() == Shadow.ConstructorCall
+                               || !shadowSig.equals(enclosingMember)) {
                        IProgramElement bodyNode = findOrCreateCodeNode(model, enclosingNode, shadowSig, shadow);
                        return bodyNode;
                } else {
@@ -468,10 +702,8 @@ public class AsmRelationshipProvider {
                }
        }
 
-       private static boolean sourceLinesMatch(ISourceLocation loc1, ISourceLocation loc2) {
-               if (loc1.getLine() != loc2.getLine())
-                       return false;
-               return true;
+       private static boolean sourceLinesMatch(ISourceLocation location1, ISourceLocation location2) {
+               return (location1.getLine() == location2.getLine());
        }
 
        /**
@@ -524,89 +756,47 @@ public class AsmRelationshipProvider {
                return peNode;
        }
 
-       protected static IProgramElement lookupMember(IHierarchy model, Member member) {
-               UnresolvedType declaringType = member.getDeclaringType();
-               IProgramElement classNode = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName());
-               return findMemberInClass(classNode, member);
-       }
-
-       protected static IProgramElement lookupMember(IHierarchy model, UnresolvedType declaringType, Member member) {
-               IProgramElement classNode = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName());
-               return findMemberInClass(classNode, member);
-       }
-
-       protected static IProgramElement findMemberInClass(IProgramElement classNode, Member member) {
-               if (classNode == null)
-                       return null; // XXX remove this check
-               for (Iterator it = classNode.getChildren().iterator(); it.hasNext();) {
-                       IProgramElement node = (IProgramElement) it.next();
-                       if (member.getName().equals(node.getBytecodeName()) && member.getSignature().equals(node.getBytecodeSignature())) {
-                               return node;
+       private static IProgramElement lookupMember(IHierarchy model, UnresolvedType declaringType, Member member) {
+               IProgramElement typeElement = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName());
+               if (typeElement == null) {
+                       return null;
+               }
+               for (Iterator it = typeElement.getChildren().iterator(); it.hasNext();) {
+                       IProgramElement element = (IProgramElement) it.next();
+                       if (member.getName().equals(element.getBytecodeName()) && member.getSignature().equals(element.getBytecodeSignature())) {
+                               return element;
                        }
                }
                // if we can't find the member, we'll just put it in the class
-               return classNode;
-       }
-
-       // private static IProgramElement.Kind genShadowKind(Shadow shadow) {
-       // IProgramElement.Kind shadowKind;
-       // if (shadow.getKind() == Shadow.MethodCall
-       // || shadow.getKind() == Shadow.ConstructorCall
-       // || shadow.getKind() == Shadow.FieldGet
-       // || shadow.getKind() == Shadow.FieldSet
-       // || shadow.getKind() == Shadow.ExceptionHandler) {
-       // return IProgramElement.Kind.CODE;
-       //                      
-       // } else if (shadow.getKind() == Shadow.MethodExecution) {
-       // return IProgramElement.Kind.METHOD;
-       //                      
-       // } else if (shadow.getKind() == Shadow.ConstructorExecution) {
-       // return IProgramElement.Kind.CONSTRUCTOR;
-       //                      
-       // } else if (shadow.getKind() == Shadow.PreInitialization
-       // || shadow.getKind() == Shadow.Initialization) {
-       // return IProgramElement.Kind.CLASS;
-       //                      
-       // } else if (shadow.getKind() == Shadow.AdviceExecution) {
-       // return IProgramElement.Kind.ADVICE;
-       //                      
-       // } else {
-       // return IProgramElement.Kind.ERROR;
-       // }
-       // }
-
-       public static AsmRelationshipProvider getDefault() {
-               return INSTANCE;
+               return typeElement;
        }
 
        /**
-        * Add a relationship to the known set for a declare @method/@constructor construct. Locating the method is a messy (for messy
-        * read 'fragile') bit of code that could break at any moment but it's working for my simple testcase. Currently just fails
-        * silently if any of the lookup code doesn't find anything...
-        * 
-        * @param hierarchy
+        * Add a relationship for a matching declare annotation method or declare annotation constructor. Locating the method is a messy
+        * (for messy read 'fragile') bit of code that could break at any moment but it's working for my simple testcase.
         */
-       public void addDeclareAnnotationMethodRelationship(ISourceLocation sourceLocation, String typename, ResolvedMember method,
-                       AsmManager structureModel) {
-               if (structureModel == null) // !AsmManager.isCreatingModel())
+       public static void addDeclareAnnotationMethodRelationship(ISourceLocation sourceLocation, String affectedTypeName,
+                       ResolvedMember affectedMethod, AsmManager model) {
+               if (model == null) {
                        return;
+               }
 
                String pkg = null;
-               String type = typename;
-               int packageSeparator = typename.lastIndexOf(".");
+               String type = affectedTypeName;
+               int packageSeparator = affectedTypeName.lastIndexOf(".");
                if (packageSeparator != -1) {
-                       pkg = typename.substring(0, packageSeparator);
-                       type = typename.substring(packageSeparator + 1);
+                       pkg = affectedTypeName.substring(0, packageSeparator);
+                       type = affectedTypeName.substring(packageSeparator + 1);
                }
 
-               IHierarchy hierarchy = structureModel.getHierarchy();
+               IHierarchy hierarchy = model.getHierarchy();
 
                IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
                if (typeElem == null)
                        return;
 
                StringBuffer parmString = new StringBuffer("(");
-               UnresolvedType[] args = method.getParameterTypes();
+               UnresolvedType[] args = affectedMethod.getParameterTypes();
                // Type[] args = method.getArgumentTypes();
                for (int i = 0; i < args.length; i++) {
                        String s = args[i].getName();// Utility.signatureToString(args[i].
@@ -618,14 +808,15 @@ public class AsmRelationshipProvider {
                parmString.append(")");
                IProgramElement methodElem = null;
 
-               if (method.getName().startsWith("<init>")) {
+               if (affectedMethod.getName().startsWith("<init>")) {
                        // its a ctor
                        methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.CONSTRUCTOR, type + parmString);
                        if (methodElem == null && args.length == 0)
                                methodElem = typeElem; // assume default ctor
                } else {
                        // its a method
-                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.METHOD, method.getName() + parmString);
+                       methodElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.METHOD, affectedMethod.getName()
+                                       + parmString);
                }
 
                if (methodElem == null)
@@ -637,11 +828,11 @@ public class AsmRelationshipProvider {
                                return;
 
                        IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
-                       String sourceHandle = structureModel.getHandleProvider().createHandleIdentifier(sourceNode);
+                       String sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
                        if (sourceHandle == null)
                                return;
 
-                       IRelationshipMap mapper = structureModel.getRelationshipMap();
+                       IRelationshipMap mapper = model.getRelationshipMap();
                        IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
                        foreward.addTarget(targetHandle);
 
@@ -655,45 +846,49 @@ public class AsmRelationshipProvider {
        }
 
        /**
-        * Add a relationship to the known set for a declare @field construct. Locating the field is trickier than it might seem since
-        * we have no line number info for it, we have to dig through the structure model under the fields' type in order to locate it.
-        * Currently just fails silently if any of the lookup code doesn't find anything...
+        * Add a relationship for a matching declare ATfield. Locating the field is trickier than it might seem since we have no line
+        * number info for it, we have to dig through the structure model under the fields' type in order to locate it.
         */
-       public void addDeclareAnnotationFieldRelationship(AsmManager asm, ISourceLocation sourceLocation, String typename,
-                       ResolvedMember field) {
-               if (asm == null) // !AsmManager.isCreatingModel())
+       public static void addDeclareAnnotationFieldRelationship(AsmManager model, ISourceLocation declareLocation,
+                       String affectedTypeName, ResolvedMember affectedFieldName) {
+               if (model == null) {
                        return;
+               }
 
                String pkg = null;
-               String type = typename;
-               int packageSeparator = typename.lastIndexOf(".");
+               String type = affectedTypeName;
+               int packageSeparator = affectedTypeName.lastIndexOf(".");
                if (packageSeparator != -1) {
-                       pkg = typename.substring(0, packageSeparator);
-                       type = typename.substring(packageSeparator + 1);
+                       pkg = affectedTypeName.substring(0, packageSeparator);
+                       type = affectedTypeName.substring(packageSeparator + 1);
                }
-               IHierarchy hierarchy = asm.getHierarchy();
+               IHierarchy hierarchy = model.getHierarchy();
                IProgramElement typeElem = hierarchy.findElementForType(pkg, type);
-               if (typeElem == null)
+               if (typeElem == null) {
                        return;
+               }
 
-               IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD, field.getName());
-               if (fieldElem == null)
+               IProgramElement fieldElem = hierarchy.findElementForSignature(typeElem, IProgramElement.Kind.FIELD, affectedFieldName
+                               .getName());
+               if (fieldElem == null) {
                        return;
+               }
 
                String targetHandle = fieldElem.getHandleIdentifier();
-               if (targetHandle == null)
+               if (targetHandle == null) {
                        return;
+               }
 
-               IProgramElement sourceNode = hierarchy.findElementForSourceLine(sourceLocation);
-               String sourceHandle = asm.getHandleProvider().createHandleIdentifier(sourceNode);
-               if (sourceHandle == null)
+               IProgramElement sourceNode = hierarchy.findElementForSourceLine(declareLocation);
+               String sourceHandle = model.getHandleProvider().createHandleIdentifier(sourceNode);
+               if (sourceHandle == null) {
                        return;
+               }
 
-               IRelationshipMap mapper = asm.getRelationshipMap();
-               IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
+               IRelationshipMap relmap = model.getRelationshipMap();
+               IRelationship foreward = relmap.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true);
                foreward.addTarget(targetHandle);
-
-               IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
+               IRelationship back = relmap.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true);
                back.addTarget(sourceHandle);
        }