You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2013/01/22 20:53:32 UTC

svn commit: r1437128 [1/2] - in /commons/sandbox/weaver/branches/mjb: modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/ processor/ processor/src/main/java/org/apache/commons/weaver/ processor/src/main/java/org/apache/commons...

Author: mbenson
Date: Tue Jan 22 19:53:31 2013
New Revision: 1437128

URL: http://svn.apache.org/viewvc?rev=1437128&view=rev
Log:
my proposal for [weaver]; requires proxy2's release as well as https://issues.apache.org/jira/browse/XBEAN-237

Added:
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java   (with props)
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java   (with props)
Modified:
    commons/sandbox/weaver/branches/mjb/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
    commons/sandbox/weaver/branches/mjb/processor/pom.xml
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
    commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java
    commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/WeaveProcessorTest.java
    commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestWeaver.java

Modified: commons/sandbox/weaver/branches/mjb/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java?rev=1437128&r1=1437127&r2=1437128&view=diff
==============================================================================
--- commons/sandbox/weaver/branches/mjb/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java (original)
+++ commons/sandbox/weaver/branches/mjb/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java Tue Jan 22 19:53:31 2013
@@ -1,29 +1,26 @@
 package org.apache.commons.weaver.privilizer;
 
 import java.io.File;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
+import java.lang.annotation.ElementType;
 import java.net.URLClassLoader;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
 import java.util.logging.Logger;
 
-import javassist.CannotCompileException;
-import javassist.NotFoundException;
+import org.apache.commons.weaver.model.ScanRequest;
+import org.apache.commons.weaver.model.ScanResult;
+import org.apache.commons.weaver.model.WeavableClass;
+import org.apache.commons.weaver.model.WeaveInterest;
 import org.apache.commons.weaver.spi.Weaver;
 import org.apache.commons.weaver.utils.URLArray;
 
 /**
  * Weaver which adds doPrivileged blocks for each method annotated with
- * {@link Privileged}.
- * An instance of this class will automatically get picked up by the
- * {@link org.apache.commons.weaver.WeaveProcessor} via the
+ * {@link Privileged}. An instance of this class will automatically get picked
+ * up by the {@link org.apache.commons.weaver.WeaveProcessor} via the
  * {@link java.util.ServiceLoader}.
  */
-public class PrivilizerWeaver implements Weaver
-{
+public class PrivilizerWeaver implements Weaver {
     public static final String CONFIG_WEAVER = "privilizer.";
     public static final String CONFIG_ACCESS_LEVEL = CONFIG_WEAVER + "accessLevel";
     public static final String CONFIG_POLICY = CONFIG_WEAVER + "policy";
@@ -36,10 +33,8 @@ public class PrivilizerWeaver implements
 
     private AccessLevel targetAccessLevel;
 
-
     @Override
-    public void configure(List<String> classPath, File target, Properties config)
-    {
+    public void configure(List<String> classPath, File target, Properties config) {
         LOG.info("");
 
         String accessLevel = config.getProperty(CONFIG_ACCESS_LEVEL);
@@ -61,8 +56,7 @@ public class PrivilizerWeaver implements
             }
 
             @Override
-            protected AccessLevel getTargetAccessLevel()
-            {
+            protected AccessLevel getTargetAccessLevel() {
                 return targetAccessLevel;
             }
         };
@@ -70,60 +64,23 @@ public class PrivilizerWeaver implements
     }
 
     @Override
-    public List<Class<? extends Annotation>> getInterest()
-    {
-        List<Class<? extends Annotation>> interest = new ArrayList<Class<? extends Annotation>>();
-        interest.add(Privileged.class);
-        return interest;
+    public ScanRequest getScanRequest() {
+        return new ScanRequest().add(WeaveInterest.of(Privileged.class, ElementType.METHOD));
     }
 
     @Override
-    public void preWeave()
-    {
-        // nothing to do
-    }
-
-    @Override
-    public boolean weave(Class classToWeave, Class<? extends Annotation> processingAnnotation)
-    {
-        // Privilizer does not weave classes
-        return false;
-    }
-
-    @Override
-    public boolean weave(Method methodToWeave, Class<? extends Annotation> processingAnnotation)
-    {
-        try
-        {
-            privilizer.weaveClass(methodToWeave.getDeclaringClass());
-        }
-        catch (NotFoundException e)
-        {
-            throw new RuntimeException(e);
-        }
-        catch (IOException e)
-        {
-            throw new RuntimeException(e);
-        }
-        catch (CannotCompileException e)
-        {
-            throw new RuntimeException(e);
-        }
-        catch (ClassNotFoundException e)
-        {
-            throw new RuntimeException(e);
-        }
-        catch (IllegalAccessException e)
-        {
-            throw new RuntimeException(e);
+    public boolean process(ScanResult scanResult) {
+        boolean result = false;
+        Iterable<WeavableClass<?>> classes = scanResult.getClasses();
+        for (WeavableClass<?> weavableClass : classes) {
+            try {
+                if (privilizer.weaveClass(weavableClass.getTarget())) {
+                    result = true;
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
         }
-
-        return true;
-    }
-
-    @Override
-    public void postWeave()
-    {
-        // nothing to do
+        return result;
     }
 }

Modified: commons/sandbox/weaver/branches/mjb/processor/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/pom.xml?rev=1437128&r1=1437127&r2=1437128&view=diff
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/pom.xml (original)
+++ commons/sandbox/weaver/branches/mjb/processor/pom.xml Tue Jan 22 19:53:31 2013
@@ -39,6 +39,11 @@ under the License.
       <artifactId>xbean-finder-shaded</artifactId>
       <version>3.13-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-proxy2-stub</artifactId>
+      <version>2.0-SNAPSHOT</version>
+    </dependency>
 
   </dependencies>
 

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,483 @@
+package org.apache.commons.weaver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.proxy2.stub.AnnotationFactory;
+import org.apache.xbean.asm.AnnotationVisitor;
+import org.apache.xbean.asm.Attribute;
+import org.apache.xbean.asm.ClassReader;
+import org.apache.xbean.asm.FieldVisitor;
+import org.apache.xbean.asm.MethodVisitor;
+import org.apache.xbean.asm.Type;
+import org.apache.xbean.asm.commons.EmptyVisitor;
+import org.apache.xbean.finder.Annotated;
+import org.apache.xbean.finder.AnnotationFinder;
+import org.apache.xbean.finder.Parameter;
+import org.apache.xbean.finder.archive.Archive;
+
+class Finder extends AnnotationFinder {
+
+    private abstract class AnnotationInflater extends AnnotationCapturer {
+        final Class<? extends Annotation> annotationType;
+        final Map<String, Object> elements = new LinkedHashMap<String, Object>();
+
+        AnnotationInflater(String desc) {
+            super();
+            try {
+                this.annotationType = Class.forName(Type.getType(desc).getClassName()).asSubclass(Annotation.class);
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Annotation inflate() {
+            return AnnotationFactory.INSTANCE.create(annotationType, elements);
+        }
+
+        @Override
+        protected void storeValue(String name, Object value) {
+            elements.put(name, value);
+        }
+    }
+
+    private abstract class AnnotationCapturer implements AnnotationVisitor {
+
+        protected abstract void storeValue(String name, Object value);
+
+        @Override
+        public void visit(String name, Object value) {
+            storeValue(name, value);
+        }
+
+        @Override
+        public AnnotationVisitor visitAnnotation(final String name, final String desc) {
+            final AnnotationCapturer owner = this;
+            return new AnnotationInflater(desc) {
+
+                @Override
+                public void visitEnd() {
+                    owner.storeValue(name, inflate());
+                }
+            };
+        }
+
+        @Override
+        public AnnotationVisitor visitArray(final String name) {
+            final AnnotationCapturer owner = this;
+            final List<Object> values = new ArrayList<Object>();
+            return new AnnotationCapturer() {
+
+                @Override
+                public void visitEnd() {
+                    // TODO hmm, best way to strongly type the array
+                    owner.storeValue(name, values.toArray());
+                }
+
+                @Override
+                protected void storeValue(String name, Object value) {
+                    values.add(value);
+                }
+            };
+        }
+
+        @Override
+        public void visitEnum(String name, String desc, String value) {
+            @SuppressWarnings("rawtypes")
+            final Class<? extends Enum> enumType;
+            try {
+                enumType = Class.forName(Type.getType(desc).getClassName()).asSubclass(Enum.class);
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+            @SuppressWarnings("unchecked")
+            final Enum<?> e = Enum.valueOf(enumType, value);
+            storeValue(name, e);
+        }
+
+    }
+
+    public class Visitor extends EmptyVisitor {
+        private final InfoBuildingVisitor wrapped;
+
+        public Visitor(InfoBuildingVisitor wrapped) {
+            super();
+            this.wrapped = wrapped;
+        }
+
+        @Override
+        public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) {
+            wrapped.visit(arg0, arg1, arg2, arg3, arg4, arg5);
+        }
+
+        @Override
+        public void visitAttribute(Attribute attribute) {
+            wrapped.visitAttribute(attribute);
+        }
+
+        @Override
+        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
+            FieldVisitor toWrap = wrapped.visitField(access, name, desc, signature, value);
+            return new Visitor((InfoBuildingVisitor) toWrap);
+        }
+
+        @Override
+        public void visitInnerClass(String name, String outerName, String innerName, int access) {
+            wrapped.visitInnerClass(name, outerName, innerName, access);
+        }
+
+        @Override
+        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+            MethodVisitor toWrap = wrapped.visitMethod(access, name, desc, signature, exceptions);
+            return new Visitor((InfoBuildingVisitor) toWrap);
+        }
+
+        @Override
+        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+            wrapped.visitAnnotation(desc, visible);
+            if (visible) {
+                return null;
+            }
+            final Info info = wrapped.getInfo();
+
+            return new AnnotationInflater(desc) {
+
+                @Override
+                public void visitEnd() {
+                    classfileAnnotationsFor(info).add(inflate());
+                }
+            };
+        }
+
+        @Override
+        public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) {
+            wrapped.visitParameterAnnotation(param, desc, visible);
+            if (visible) {
+                return null;
+            }
+            final Info info = wrapped.getInfo();
+
+            return new AnnotationInflater(desc) {
+
+                @Override
+                public void visitEnd() {
+                    classfileAnnotationsFor(info).add(inflate());
+                }
+            };
+        }
+
+        private List<Annotation> classfileAnnotationsFor(Info info) {
+            synchronized (CLASSFILE_ANNOTATIONS) {
+                if (!CLASSFILE_ANNOTATIONS.get().containsKey(info)) {
+                    final List<Annotation> result = new ArrayList<Annotation>();
+                    CLASSFILE_ANNOTATIONS.get().put(info, result);
+                    return result;
+                }
+            }
+            return CLASSFILE_ANNOTATIONS.get().get(info);
+        }
+
+    }
+
+    private static class IncludesClassfile<T extends AnnotatedElement> implements Annotated<T> {
+        private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
+
+        private final T target;
+        private final Annotation[] annotations;
+
+        IncludesClassfile(T target, List<Annotation> classfileAnnotations) {
+            this(target, classfileAnnotations.toArray(EMPTY_ANNOTATION_ARRAY));
+        }
+
+        IncludesClassfile(T target, Annotation[] classfileAnnotations) {
+            super();
+            this.target = target;
+
+            final Annotation[] runtime = target.getAnnotations();
+            if (classfileAnnotations == null || classfileAnnotations.length == 0) {
+                annotations = runtime;
+            } else {
+                annotations = new Annotation[runtime.length + classfileAnnotations.length];
+                System.arraycopy(runtime, 0, annotations, 0, runtime.length);
+                System.arraycopy(classfileAnnotations, 0, annotations, runtime.length, classfileAnnotations.length);
+            }
+        }
+
+        @Override
+        public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+            for (Annotation prospect : annotations) {
+                if (prospect.annotationType().equals(annotationType)) {
+                    @SuppressWarnings("unchecked")
+                    final A result = (A) prospect;
+                    return result;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public Annotation[] getAnnotations() {
+            final Annotation[] result = new Annotation[annotations.length];
+            System.arraycopy(annotations, 0, result, 0, annotations.length);
+            return result;
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return getAnnotations();
+        }
+
+        @Override
+        public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+            return getAnnotation(annotationType) != null;
+        }
+
+        @Override
+        public T get() {
+            return target;
+        }
+
+    }
+
+    public class WithAnnotations {
+        private WithAnnotations() {
+        }
+
+        public List<Annotated<Package>> findAnnotatedPackages(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedPackages(annotation);
+            final List<Annotated<Package>> result = new ArrayList<Annotated<Package>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof PackageInfo) {
+                    PackageInfo packageInfo = (PackageInfo) info;
+                    try {
+                        IncludesClassfile<Package> annotated =
+                            new IncludesClassfile<Package>(packageInfo.get(), classfileAnnotationsFor(packageInfo));
+                        if (annotated.isAnnotationPresent(annotation)) {
+                            result.add(annotated);
+                        }
+                    } catch (ClassNotFoundException e) {
+                    }
+                }
+            }
+            return result;
+        }
+
+        public List<Annotated<Class<?>>> findAnnotatedClasses(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedClasses(annotation);
+            final List<Annotated<Class<?>>> result = new ArrayList<Annotated<Class<?>>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof ClassInfo) {
+                    ClassInfo classInfo = (ClassInfo) info;
+
+                    IncludesClassfile<Class<?>> annotated;
+                    try {
+                        annotated =
+                            new IncludesClassfile<Class<?>>(classInfo.get(), classfileAnnotationsFor(classInfo));
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                    if (annotated.isAnnotationPresent(annotation)) {
+                        result.add(annotated);
+                    }
+                }
+            }
+            return result;
+
+        }
+
+        public List<Annotated<Method>> findAnnotatedMethods(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedMethods(annotation);
+            final List<Annotated<Method>> result = new ArrayList<Annotated<Method>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof MethodInfo) {
+                    MethodInfo methodInfo = (MethodInfo) info;
+                    if ("<init>".equals(methodInfo.getName())) {
+                        continue;
+                    }
+                    IncludesClassfile<Method> annotated;
+                    try {
+                        annotated =
+                            new IncludesClassfile<Method>((Method) methodInfo.get(),
+                                classfileAnnotationsFor(methodInfo));
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                    if (annotated.isAnnotationPresent(annotation)) {
+                        result.add(annotated);
+                    }
+                }
+            }
+            return result;
+
+        }
+
+        public List<Annotated<Parameter<Method>>> findAnnotatedMethodParameters(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedMethodParameters(annotation);
+            final List<Annotated<Parameter<Method>>> result = new ArrayList<Annotated<Parameter<Method>>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof ParameterInfo) {
+                    ParameterInfo parameterInfo = (ParameterInfo) info;
+                    if ("<init>".equals(parameterInfo.getDeclaringMethod().getName())) {
+                        continue;
+                    }
+                    Parameter<Method> parameter;
+                    try {
+                        @SuppressWarnings("unchecked")
+                        Parameter<Method> unchecked = (Parameter<Method>) parameterInfo.get();
+                        parameter = unchecked;
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                    IncludesClassfile<Parameter<Method>> annotated =
+                        new IncludesClassfile<Parameter<Method>>(parameter, classfileAnnotationsFor(parameterInfo));
+                    if (annotated.isAnnotationPresent(annotation)) {
+                        result.add(annotated);
+                    }
+                }
+            }
+            return result;
+        }
+
+        public List<Annotated<Constructor<?>>> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedConstructors(annotation);
+            final List<Annotated<Constructor<?>>> result = new ArrayList<Annotated<Constructor<?>>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof MethodInfo) {
+                    MethodInfo methodInfo = (MethodInfo) info;
+                    if (!"<init>".equals(methodInfo.getName())) {
+                        continue;
+                    }
+                    IncludesClassfile<Constructor<?>> annotated;
+                    try {
+                        annotated =
+                            new IncludesClassfile<Constructor<?>>((Constructor<?>) methodInfo.get(),
+                                classfileAnnotationsFor(methodInfo));
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                    if (annotated.isAnnotationPresent(annotation)) {
+                        result.add(annotated);
+                    }
+                }
+            }
+            return result;
+        }
+
+        public List<Annotated<Parameter<Constructor<?>>>> findAnnotatedConstructorParameters(
+            Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedConstructorParameters(annotation);
+            final List<Annotated<Parameter<Constructor<?>>>> result =
+                new ArrayList<Annotated<Parameter<Constructor<?>>>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof ParameterInfo) {
+                    ParameterInfo parameterInfo = (ParameterInfo) info;
+                    if (!"<init>".equals(parameterInfo.getDeclaringMethod().getName())) {
+                        continue;
+                    }
+                    Parameter<Constructor<?>> parameter;
+                    try {
+                        @SuppressWarnings("unchecked")
+                        Parameter<Constructor<?>> unchecked = (Parameter<Constructor<?>>) parameterInfo.get();
+                        parameter = unchecked;
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                    IncludesClassfile<Parameter<Constructor<?>>> annotated =
+                        new IncludesClassfile<Parameter<Constructor<?>>>(parameter,
+                            classfileAnnotationsFor(parameterInfo));
+                    if (annotated.isAnnotationPresent(annotation)) {
+                        result.add(annotated);
+                    }
+                }
+            }
+            return result;
+        }
+
+        public List<Annotated<Field>> findAnnotatedFields(Class<? extends Annotation> annotation) {
+            Finder.this.findAnnotatedFields(annotation);
+            final List<Annotated<Field>> result = new ArrayList<Annotated<Field>>();
+            for (Info info : getAnnotationInfos(annotation.getName())) {
+                if (info instanceof FieldInfo) {
+                    FieldInfo fieldInfo = (FieldInfo) info;
+                    try {
+                        IncludesClassfile<Field> annotated =
+                            new IncludesClassfile<Field>((Field) fieldInfo.get(), classfileAnnotationsFor(fieldInfo));
+                        if (annotated.isAnnotationPresent(annotation)) {
+                            result.add(annotated);
+                        }
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    }
+                }
+            }
+            return result;
+        }
+
+        private List<Annotation> classfileAnnotationsFor(Info info) {
+            synchronized (classfileAnnotations) {
+                if (!classfileAnnotations.containsKey(info)) {
+                    final List<Annotation> result = new ArrayList<Annotation>();
+                    classfileAnnotations.put(info, result);
+                    return result;
+                }
+            }
+            return classfileAnnotations.get(info);
+        }
+
+    }
+
+    private static final int ASM_FLAGS = ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
+
+    private static final ThreadLocal<Map<Info, List<Annotation>>> CLASSFILE_ANNOTATIONS =
+        new ThreadLocal<Map<Info, List<Annotation>>>() {
+            protected java.util.Map<Info, java.util.List<Annotation>> initialValue() {
+                return new IdentityHashMap<AnnotationFinder.Info, List<Annotation>>();
+            }
+        };
+
+    private final Map<Info, List<Annotation>> classfileAnnotations;
+
+    public Finder(Archive archive) {
+        super(archive, false);
+        classfileAnnotations = CLASSFILE_ANNOTATIONS.get();
+        CLASSFILE_ANNOTATIONS.remove();
+    }
+
+    public WithAnnotations withAnnotations() {
+        return new WithAnnotations();
+    }
+
+    protected void readClassDef(InputStream in) throws IOException {
+        try {
+            ClassReader classReader = new ClassReader(in);
+            classReader.accept(new Visitor(new InfoBuildingVisitor()), ASM_FLAGS);
+        } finally {
+            in.close();
+        }
+    }
+
+    @Override
+    public AnnotationFinder select(Class<?>... arg0) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AnnotationFinder select(Iterable<String> clazz) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AnnotationFinder select(String... clazz) {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/Finder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java?rev=1437128&r1=1437127&r2=1437128&view=diff
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java (original)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java Tue Jan 22 19:53:31 2013
@@ -19,7 +19,8 @@
 package org.apache.commons.weaver;
 
 import java.io.File;
-import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
@@ -28,9 +29,12 @@ import java.util.List;
 import java.util.Properties;
 import java.util.ServiceLoader;
 
+import org.apache.commons.weaver.model.ScanResult;
+import org.apache.commons.weaver.model.WeaveInterest;
 import org.apache.commons.weaver.spi.Weaver;
 import org.apache.commons.weaver.utils.URLArray;
-import org.apache.xbean.finder.AnnotationFinder;
+import org.apache.xbean.finder.Annotated;
+import org.apache.xbean.finder.Parameter;
 import org.apache.xbean.finder.archive.FileArchive;
 
 /**
@@ -41,20 +45,20 @@ public class WeaveProcessor {
     private static WeaveProcessor instance;
 
     /**
-     * The classpath which will be used to look up cross references during weaving.
+     * The classpath which will be used to look up cross references during
+     * weaving.
      */
     private List<String> classPath;
 
     /**
-     * The actual path which gets weaved. All the classes in this path
-     * will get weaved. The weaved classes will replace the original classes.
+     * The actual path which gets weaved. All the classes in this path will get
+     * weaved. The weaved classes will replace the original classes.
      */
     private File target;
 
     /** List of picked up weaver plugins */
     private List<Weaver> weavers = new ArrayList<Weaver>();
 
-
     public static synchronized WeaveProcessor getInstance() {
         if (instance == null) {
             instance = new WeaveProcessor();
@@ -75,10 +79,14 @@ public class WeaveProcessor {
 
     /**
      * Configure all Weavers.
-     * @param classPath the classpath to look up cross-references in during weaving
-     * @param target the File path where the classes to weave reside
-     * @param config additional configuration for all plugins.
-     *
+     * 
+     * @param classPath
+     *            the classpath to look up cross-references in during weaving
+     * @param target
+     *            the File path where the classes to weave reside
+     * @param config
+     *            additional configuration for all plugins.
+     * 
      */
     public void configure(List<String> classPath, File target, Properties config) {
         this.classPath = classPath;
@@ -93,36 +101,62 @@ public class WeaveProcessor {
      * perform the weaving on all specified classpath entries
      */
     public void weave() {
+        final ClassLoader classLoader = new URLClassLoader(URLArray.fromPaths(classPath));
+        final Finder finder = new Finder(new FileArchive(classLoader, target));
         for (Weaver weaver : weavers) {
-            weaver.preWeave();
-        }
-
-        for (Weaver weaver : weavers) {
-            weave(weaver);
-        }
-
-        for (Weaver weaver : weavers) {
-            weaver.postWeave();
+            weave(finder, weaver);
         }
     }
 
-    private void weave(Weaver weaver) {
-        List<Class<? extends Annotation>> interest = weaver.getInterest();
-
-        ClassLoader classLoader = new URLClassLoader(URLArray.fromPaths(classPath));
-
-        AnnotationFinder annotationFinder = new AnnotationFinder(new FileArchive(classLoader, target), false);
-        for (Class<? extends Annotation> annotation : interest) {
-            List<Class<?>> annotatedClasses = annotationFinder.findAnnotatedClasses(annotation);
-
-            for (Class<?> annotatedClass : annotatedClasses) {
-                weaver.weave(annotatedClass, annotation);
-            }
+    private void weave(Finder finder, Weaver weaver) {
+        ScanResult result = new ScanResult();
 
-            List<Method> annotateMethods = annotationFinder.findAnnotatedMethods(annotation);
-            for (Method annotatedMethod : annotateMethods) {
-                weaver.weave(annotatedMethod, annotation);
+        for (WeaveInterest interest : weaver.getScanRequest().getInterests()) {
+            switch (interest.target) {
+            case PACKAGE:
+                for (Annotated<Package> pkg : finder.withAnnotations().findAnnotatedPackages(interest.annotationType)) {
+                    result.getWeavable(pkg.get()).addAnnotations(pkg.getAnnotation(interest.annotationType));
+                }
+            case TYPE:
+                for (Annotated<Class<?>> type : finder.withAnnotations().findAnnotatedClasses(interest.annotationType)) {
+                    result.getWeavable(type.get()).addAnnotations(type.getAnnotation(interest.annotationType));
+                }
+                break;
+            case METHOD:
+                for (Annotated<Method> method : finder.withAnnotations().findAnnotatedMethods(interest.annotationType)) {
+                    result.getWeavable(method.get()).addAnnotations(method.getAnnotation(interest.annotationType));
+                }
+                break;
+            case CONSTRUCTOR:
+                for (Annotated<Constructor<?>> cs : finder.withAnnotations().findAnnotatedConstructors(
+                    interest.annotationType)) {
+                    result.getWeavable(cs.get()).addAnnotations(cs.getAnnotation(interest.annotationType));
+                }
+                break;
+            case FIELD:
+                for (Annotated<Field> fld : finder.withAnnotations().findAnnotatedFields(interest.annotationType)) {
+                    result.getWeavable(fld.get()).addAnnotations(fld.getAnnotation(interest.annotationType));
+                }
+                break;
+            case PARAMETER:
+                for (Annotated<Parameter<Method>> parameter : finder.withAnnotations().findAnnotatedMethodParameters(
+                    interest.annotationType)) {
+                    result.getWeavable(parameter.get().getDeclaringExecutable())
+                        .getWeavableParameter(parameter.get().getIndex())
+                        .addAnnotations(parameter.getAnnotation(interest.annotationType));
+                }
+                for (Annotated<Parameter<Constructor<?>>> parameter : finder.withAnnotations()
+                    .findAnnotatedConstructorParameters(interest.annotationType)) {
+                    result.getWeavable(parameter.get().getDeclaringExecutable())
+                        .getWeavableParameter(parameter.get().getIndex())
+                        .addAnnotations(parameter.getAnnotation(interest.annotationType));
+                }
+                break;
+            default:
+                // should we log something?
+                break;
             }
         }
+        weaver.process(result);
     }
 }

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+public abstract class NestedWeavable<SELF extends NestedWeavable<SELF, TARGET, PARENT, PARENT_TARGET>, TARGET, PARENT extends Weavable<PARENT, PARENT_TARGET>, PARENT_TARGET>
+    extends Weavable<SELF, TARGET> {
+
+    private final PARENT parent;
+
+    protected NestedWeavable(TARGET target, PARENT parent) {
+        super(target);
+        this.parent = parent;
+    }
+
+    public PARENT getParent() {
+        return parent;
+    }
+
+    @Override
+    public final int compareTo(SELF o) {
+        int result = getParent().compareTo(o.getParent());
+        return result == 0 ? localCompareTo(o) : result;
+    }
+
+    protected abstract int localCompareTo(SELF o);
+}
\ No newline at end of file

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/NestedWeavable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.weaver.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Weave plan, extensible in future to include e.g. scanning strategy hints.
+ */
+public class ScanRequest {
+
+    private final List<WeaveInterest> interests = new ArrayList<WeaveInterest>();
+
+    public ScanRequest add(WeaveInterest interest) {
+        if (interest == null) {
+            throw new NullPointerException();
+        }
+        interests.add(interest);
+        return this;
+    }
+
+    public Iterable<WeaveInterest> getInterests() {
+        return Collections.unmodifiableList(interests);
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+/**
+ * Encapsulates the result of scanning based on a {@link ScanRequest}.
+ */
+public class ScanResult {
+    private static abstract class Projection<PARENT, CHILD> implements Iterable<CHILD> {
+        private final Iterable<PARENT> parents;
+
+        Projection(Iterable<PARENT> parents) {
+            super();
+            this.parents = parents;
+        }
+
+        protected abstract Iterable<CHILD> childrenOf(PARENT parent);
+
+        @Override
+        public Iterator<CHILD> iterator() {
+            final Iterator<PARENT> parentIterator = parents.iterator();
+            return new Iterator<CHILD>() {
+                private Iterator<CHILD> children = nextChildren();
+
+                @Override
+                public synchronized boolean hasNext() {
+                    return children != null;
+                }
+
+                @Override
+                public synchronized CHILD next() {
+                    if (children == null) {
+                        throw new NoSuchElementException();
+                    }
+                    try {
+                        return children.next();
+                    } finally {
+                        if (!children.hasNext()) {
+                            children = nextChildren();
+                        }
+                    }
+                }
+
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+
+                private Iterator<CHILD> nextChildren() {
+                    while (parentIterator.hasNext()) {
+                        Iterator<CHILD> prospect = childrenOf(parentIterator.next()).iterator();
+                        if (prospect.hasNext()) {
+                            return prospect;
+                        }
+                    }
+                    return null;
+                }
+            };
+        }
+    }
+
+    private final ConcurrentNavigableMap<String, WeavablePackage> packages =
+        new ConcurrentSkipListMap<String, WeavablePackage>();
+
+    public WeavablePackage getWeavable(Package pkg) {
+        final String key = pkg.getName();
+        if (packages.containsKey(key)) {
+            return packages.get(key);
+        }
+        final WeavablePackage result = new WeavablePackage(pkg);
+        final WeavablePackage faster = packages.putIfAbsent(key, result);
+        return faster == null ? result : faster;
+    }
+
+    public <T> WeavableClass<T> getWeavable(Class<T> cls) {
+        return getWeavable(cls.getPackage()).getWeavable(cls);
+    }
+
+    public WeavableField<?> getWeavable(Field fld) {
+        return getWeavable(fld.getDeclaringClass()).getWeavable(fld);
+    }
+
+    public WeavableMethod<?> getWeavable(Method mt) {
+        return getWeavable(mt.getDeclaringClass()).getWeavable(mt);
+    }
+
+    public <T> WeavableConstructor<T> getWeavable(Constructor<T> ctor) {
+        return getWeavable(ctor.getDeclaringClass()).getWeavable(ctor);
+    }
+
+    public Iterable<WeavablePackage> getPackages() {
+        return Collections.unmodifiableCollection(packages.values());
+    }
+
+    public Iterable<WeavableClass<?>> getClasses() {
+        return new Projection<WeavablePackage, WeavableClass<?>>(getPackages()) {
+
+            @Override
+            protected Iterable<WeavableClass<?>> childrenOf(WeavablePackage parent) {
+                return parent.getClasses();
+            }
+        };
+    }
+
+    public Iterable<WeavableField<?>> getFields() {
+        return new Projection<WeavableClass<?>, WeavableField<?>>(getClasses()) {
+
+            @Override
+            protected Iterable<WeavableField<?>> childrenOf(WeavableClass<?> parent) {
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                final Iterable<WeavableField<?>> result = ((WeavableClass) parent).getFields();
+                return result;
+            }
+        };
+    }
+
+    public Iterable<WeavableConstructor<?>> getConstructors() {
+        return new Projection<WeavableClass<?>, WeavableConstructor<?>>(getClasses()) {
+
+            @Override
+            protected Iterable<WeavableConstructor<?>> childrenOf(WeavableClass<?> parent) {
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                final Iterable<WeavableConstructor<?>> result = ((WeavableClass) parent).getConstructors();
+                return result;
+            }
+        };
+    }
+
+    public Iterable<WeavableMethod<?>> getMethods() {
+        return new Projection<WeavableClass<?>, WeavableMethod<?>>(getClasses()) {
+
+            @Override
+            protected Iterable<WeavableMethod<?>> childrenOf(WeavableClass<?> parent) {
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                final Iterable<WeavableMethod<?>> result = ((WeavableClass) parent).getMethods();
+                return result;
+            }
+        };
+    }
+
+    public Iterable<WeavableMethodParameter<?>> getMethodParameters() {
+        return new Projection<WeavableMethod<?>, WeavableMethodParameter<?>>(getMethods()) {
+
+            @Override
+            protected Iterable<WeavableMethodParameter<?>> childrenOf(WeavableMethod<?> parent) {
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                final Iterable<WeavableMethodParameter<?>> result = ((WeavableMethod) parent).getParameters();
+                return result;
+            }
+        };
+    }
+
+    public Iterable<WeavableConstructorParameter<?>> getConstructorParameters() {
+
+        return new Projection<WeavableConstructor<?>, WeavableConstructorParameter<?>>(getConstructors()) {
+
+            @Override
+            protected Iterable<WeavableConstructorParameter<?>> childrenOf(WeavableConstructor<?> parent) {
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                final Iterable<WeavableConstructorParameter<?>> result = ((WeavableConstructor) parent).getParameters();
+                return result;
+            }
+        };
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/ScanResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public abstract class Weavable<SELF extends Weavable<SELF, TARGET>, TARGET> implements Comparable<SELF>,
+    AnnotatedElement {
+    private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
+
+    private final TARGET target;
+    private Set<Annotation> annotations;
+
+    protected Weavable(TARGET target) {
+        this.target = target;
+    }
+
+    public boolean addAnnotations(Annotation... toAdd) {
+        synchronized (this) {
+            if (annotations == null) {
+                annotations = new LinkedHashSet<Annotation>();
+            }
+        }
+        return Collections.addAll(annotations, toAdd);
+    }
+
+    public TARGET getTarget() {
+        return target;
+    }
+
+    public Annotation[] getAnnotations() {
+        synchronized (this) {
+            if (annotations == null) {
+                return EMPTY_ANNOTATION_ARRAY;
+            }
+        }
+        return annotations.toArray(EMPTY_ANNOTATION_ARRAY);
+    }
+
+    @Override
+    public synchronized <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        if (annotations == null) {
+            return null;
+        }
+        for (Annotation prospect : annotations) {
+            if (annotationClass.equals(prospect.annotationType())) {
+                @SuppressWarnings("unchecked")
+                final T result = (T) prospect;
+                return result;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Annotation[] getDeclaredAnnotations() {
+        return getAnnotations();
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return getAnnotation(annotationClass) != null;
+    }
+
+    @Override
+    public String toString() {
+        return "Weavable " + getTarget().toString();
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/Weavable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import org.apache.commons.weaver.utils.Args;
+
+public class WeavableClass<T> extends NestedWeavable<WeavableClass<T>, Class<T>, WeavablePackage, Package> {
+    private final ConcurrentNavigableMap<String, WeavableField<T>> fields =
+        new ConcurrentSkipListMap<String, WeavableField<T>>();
+    private final ConcurrentNavigableMap<Constructor<T>, WeavableConstructor<T>> ctors =
+        new ConcurrentSkipListMap<Constructor<T>, WeavableConstructor<T>>(new Comparator<Constructor<?>>() {
+
+            @Override
+            public int compare(Constructor<?> o1, Constructor<?> o2) {
+                return Args.compare(o1.getParameterTypes(), o2.getParameterTypes());
+            }
+        });
+    private final ConcurrentNavigableMap<Method, WeavableMethod<T>> methods =
+        new ConcurrentSkipListMap<Method, WeavableMethod<T>>(new Comparator<Method>() {
+
+            @Override
+            public int compare(Method o1, Method o2) {
+                int result = o1.getName().compareTo(o2.getName());
+                return result == 0 ? Args.compare(o1.getParameterTypes(), o2.getParameterTypes()) : result;
+            }
+        });
+
+    public WeavableClass(Class<T> target, WeavablePackage parent) {
+        super(target, parent);
+    }
+
+    public WeavableField<T> getWeavable(Field fld) {
+        final String key = fld.getName();
+        if (fields.containsKey(key)) {
+            final WeavableField<T> result = (WeavableField<T>) fields.get(key);
+            return result;
+        }
+        final WeavableField<T> result = new WeavableField<T>(fld, this);
+        final WeavableField<T> faster = (WeavableField<T>) fields.putIfAbsent(key, result);
+        return faster == null ? result : faster;
+    }
+
+    public WeavableMethod<T> getWeavable(Method mt) {
+        if (methods.containsKey(mt)) {
+            final WeavableMethod<T> result = (WeavableMethod<T>) methods.get(mt);
+            return result;
+        }
+        final WeavableMethod<T> result = (WeavableMethod<T>) new WeavableMethod<T>(mt, this);
+        final WeavableMethod<T> faster = (WeavableMethod<T>) methods.putIfAbsent(mt, result);
+        return faster == null ? result : faster;
+    }
+
+    public WeavableConstructor<T> getWeavable(Constructor<T> ctor) {
+        if (ctors.containsKey(ctor)) {
+            final WeavableConstructor<T> result = (WeavableConstructor<T>) ctors.get(ctor);
+            return result;
+        }
+        final WeavableConstructor<T> result = (WeavableConstructor<T>) new WeavableConstructor<T>(ctor, this);
+        final WeavableConstructor<T> faster = (WeavableConstructor<T>) ctors.putIfAbsent(ctor, result);
+        return faster == null ? result : faster;
+    }
+
+    public Iterable<WeavableField<T>> getFields() {
+        return Collections.unmodifiableCollection(fields.values());
+    }
+
+    public Iterable<WeavableConstructor<T>> getConstructors() {
+        return Collections.unmodifiableCollection(ctors.values());
+    }
+
+    public Iterable<WeavableMethod<T>> getMethods() {
+        return Collections.unmodifiableCollection(methods.values());
+    }
+
+    @Override
+    protected int localCompareTo(WeavableClass<T> o) {
+        return getTarget().getName().compareTo(o.getTarget().getName());
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableClass.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Constructor;
+
+public class WeavableConstructor<T> extends WeavableExecutable<WeavableConstructor<T>, Constructor<T>, T> {
+
+    public WeavableConstructor(Constructor<T> target, WeavableClass<T> parent) {
+        super(target, parent);
+    }
+
+    @Override
+    protected Class<?>[] getParameterTypes() {
+        return getTarget().getParameterTypes();
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Constructor;
+
+public class WeavableConstructorParameter<T> extends WeavableParameter<WeavableConstructor<T>, Constructor<T>, T> {
+
+    public WeavableConstructorParameter(Integer target, WeavableConstructor<T> parent) {
+        super(target, parent);
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableConstructorParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.weaver.utils.Args;
+
+public abstract class WeavableExecutable<SELF extends WeavableExecutable<SELF, TARGET, T>, TARGET extends Member, T>
+    extends NestedWeavable<SELF, TARGET, WeavableClass<T>, Class<T>> {
+
+    private final List<WeavableParameter<SELF, TARGET, T>> parameters;
+
+    protected WeavableExecutable(TARGET target, WeavableClass<T> parent) {
+        super(target, parent);
+        final List<WeavableParameter<SELF, TARGET, T>> params = new ArrayList<WeavableParameter<SELF, TARGET, T>>();
+        for (int i = 0, sz = getParameterTypes().length; i < sz; i++) {
+            @SuppressWarnings("unchecked")
+            final WeavableParameter<SELF, TARGET, T> param =
+                new WeavableParameter<SELF, TARGET, T>(Integer.valueOf(i), (SELF) this);
+            params.add(param);
+        }
+        parameters = Collections.unmodifiableList(params);
+    }
+
+    protected abstract Class<?>[] getParameterTypes();
+
+    @Override
+    protected int localCompareTo(SELF o) {
+        return Args.compare(getParameterTypes(), o.getParameterTypes());
+    }
+
+    public WeavableParameter<SELF, TARGET, T> getWeavableParameter(int index) {
+        return parameters.get(index);
+    }
+
+    public Iterable<WeavableParameter<SELF, TARGET, T>> getParameters() {
+        return parameters;
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableExecutable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Field;
+
+public class WeavableField<T> extends NestedWeavable<WeavableField<T>, Field, WeavableClass<T>, Class<T>> {
+
+    public WeavableField(Field target, WeavableClass<T> parent) {
+        super(target, parent);
+    }
+
+    @Override
+    protected int localCompareTo(WeavableField<T> o) {
+        return getTarget().getName().compareTo(o.getTarget().getName());
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableField.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Method;
+
+public class WeavableMethod<T> extends WeavableExecutable<WeavableMethod<T>, Method, T> {
+
+    public WeavableMethod(Method target, WeavableClass<T> parent) {
+        super(target, parent);
+    }
+
+    @Override
+    protected Class<?>[] getParameterTypes() {
+        return getTarget().getParameterTypes();
+    }
+
+    @Override
+    protected int localCompareTo(WeavableMethod<T> o) {
+        int result = getTarget().getName().compareTo(o.getTarget().getName());
+        return result == 0 ? super.localCompareTo(o) : result;
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethod.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Method;
+
+public class WeavableMethodParameter<T> extends WeavableParameter<WeavableMethod<T>, Method, T> {
+
+    public WeavableMethodParameter(Integer target, WeavableMethod<T> parent) {
+        super(target, parent);
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableMethodParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.util.Collections;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+public class WeavablePackage extends Weavable<WeavablePackage, Package> {
+
+    private final ConcurrentNavigableMap<String, WeavableClass<?>> clazzes =
+        new ConcurrentSkipListMap<String, WeavableClass<?>>();
+
+    public WeavablePackage(Package target) {
+        super(target);
+    }
+
+    public synchronized <T> WeavableClass<T> getWeavable(Class<T> cls) {
+        final String key = cls.getName();
+        if (clazzes.containsKey(key)) {
+            @SuppressWarnings("unchecked")
+            final WeavableClass<T> result = (WeavableClass<T>) clazzes.get(key);
+            return result;
+        }
+        final WeavableClass<T> result = new WeavableClass<T>(cls, this);
+        @SuppressWarnings("unchecked")
+        final WeavableClass<T> faster = (WeavableClass<T>) clazzes.putIfAbsent(key, result);
+        return faster == null ? result : faster;
+    }
+
+    public Iterable<WeavableClass<?>> getClasses() {
+        return Collections.unmodifiableCollection(clazzes.values());
+    }
+
+    @Override
+    public int compareTo(WeavablePackage arg0) {
+        return getTarget().getName().compareTo(arg0.getTarget().getName());
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavablePackage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.model;
+
+import java.lang.reflect.Member;
+
+public class WeavableParameter<PARENT extends WeavableExecutable<PARENT, PARENT_TARGET, T>, PARENT_TARGET extends Member, T>
+    extends NestedWeavable<WeavableParameter<PARENT, PARENT_TARGET, T>, Integer, PARENT, PARENT_TARGET> {
+
+    protected WeavableParameter(Integer target, PARENT parent) {
+        super(target, parent);
+    }
+
+    @Override
+    protected int localCompareTo(WeavableParameter<PARENT, PARENT_TARGET, T> o) {
+        return getTarget().compareTo(getTarget());
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeavableParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.weaver.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+
+/**
+ * Weave interest composed of annotation type and target element type.
+ */
+public class WeaveInterest {
+    public final Class<? extends Annotation> annotationType;
+    public final ElementType target;
+
+    private WeaveInterest(Class<? extends Annotation> annotationType, ElementType target) {
+        super();
+        this.annotationType = annotationType;
+        this.target = target;
+    }
+
+    public static WeaveInterest of(Class<? extends Annotation> annotationType, ElementType target) {
+        return new WeaveInterest(annotationType, target);
+    }
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/model/WeaveInterest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java?rev=1437128&r1=1437127&r2=1437128&view=diff
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java (original)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java Tue Jan 22 19:53:31 2013
@@ -19,17 +19,16 @@
 package org.apache.commons.weaver.spi;
 
 import java.io.File;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Properties;
 
+import org.apache.commons.weaver.model.ScanRequest;
+import org.apache.commons.weaver.model.ScanResult;
+
 /**
  * An implementation of a 'Weaver' takes care about
  * certain weaving jobs and will perform the byte code
  * enhancement in the classes.
- *
- * TODO: we might enhance this SPI to gather upfront information about what needs to get scanned at all!
  */
 public interface Weaver
 {
@@ -44,35 +43,14 @@ public interface Weaver
     void configure(List<String> classPath, File target, Properties config);
 
     /**
-     * A Weaver must return a List of Annotations he is interested in.
-     */
-    List<Class<? extends Annotation>> getInterest();
-
-    /**
-     * This will get invoked before any weaver did run
-     */
-    void preWeave();
-
-    /**
-     * Perform weaving on the given class for any class which has one of the required annotations.
-     * If there is nothing to do, then just go on.
-     *
-     * @return <code>true</code> if some bytecode has been changed
-     */
-    boolean weave(Class classToWeave, Class<? extends Annotation> processingAnnotation);
-
-    /**
-     * Perform weaving on the given class for any class which has one of the required annotations.
-     * If there is nothing to do, then just go on.
-     *
-     * @return <code>true</code> if some bytecode has been changed
+     * Get the scan request of this {@link Weaver}.
      */
-    boolean weave(Method methodToWeave, Class<? extends Annotation> processingAnnotation);
+    ScanRequest getScanRequest();
 
     /**
-     * This method will get invoked after all {@link #weave(Class, Class)} and
-     * {@link #weave(java.lang.reflect.Method, Class)} methods got invoked
-     * for all classes on every weaver.
+     * Process the scanning results.
+     * @param scanResult
+     * @return whether any work was done.
      */
-    void postWeave();
+    boolean process(ScanResult scanResult);
 }

Added: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java?rev=1437128&view=auto
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java (added)
+++ commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java Tue Jan 22 19:53:31 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.utils;
+
+public class Args {
+
+    public static int compare(Class<?>[] paramTypes1, Class<?>[] paramTypes2) {
+        int i = 0;
+        while (i < paramTypes1.length) {
+            if (i >= paramTypes2.length) {
+                return 1;
+            }
+            final int test = paramTypes1[i].getName().compareTo(paramTypes2[i].getName());
+            if (test == 0) {
+                continue;
+            }
+            return test;
+        }
+        if (paramTypes1.length == paramTypes2.length) {
+            return 0;
+        }
+        return -1;
+    }
+
+}

Propchange: commons/sandbox/weaver/branches/mjb/processor/src/main/java/org/apache/commons/weaver/utils/Args.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/WeaveProcessorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/WeaveProcessorTest.java?rev=1437128&r1=1437127&r2=1437128&view=diff
==============================================================================
--- commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/WeaveProcessorTest.java (original)
+++ commons/sandbox/weaver/branches/mjb/processor/src/test/java/org/apache/commons/weaver/test/WeaveProcessorTest.java Tue Jan 22 19:53:31 2013
@@ -31,8 +31,7 @@ import org.junit.Test;
 /**
  * Test the {@link WeaveProcessor}
  */
-public class WeaveProcessorTest extends WeaverTestBase
-{
+public class WeaveProcessorTest extends WeaverTestBase {
 
     @Test
     public void testWeaveVisiting() throws Exception {
@@ -48,16 +47,11 @@ public class WeaveProcessorTest extends 
 
         wp.configure(getClassPathEntries(), getTargetFolder(), config);
 
-
-        TestWeaver.postWeaveExecuted = false;
-        TestWeaver.preWeaveExecuted = false;
         TestWeaver.wovenClasses.clear();
         TestWeaver.wovenMethods.clear();
 
         wp.weave();
 
-        Assert.assertTrue(TestWeaver.preWeaveExecuted);
-        Assert.assertTrue(TestWeaver.postWeaveExecuted);
         Assert.assertEquals(1, TestWeaver.wovenClasses.size());
         Assert.assertEquals(TestBeanWithClassAnnotation.class, TestWeaver.wovenClasses.get(0));