JavaDoc modifications and new feature (3 new annotations and corresponding AnnotationHandler and *MethodInterceptor implementations to support them)

git-svn-id: https://svn.apache.org/repos/asf/incubator/jsecurity/trunk@711119 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes.txt b/changes.txt
index 0f9eda4..abf9f2a 100644
--- a/changes.txt
+++ b/changes.txt
@@ -1,9 +1,14 @@
-[0.9 final]

+[0.9 RC3]

 

 * org.jsecurity.spring.SpringWebConfiguration renamed to org.jsecurity.spring.SpringIniWebConfiguration

 * org.jsecurity.util.ThreadContext fixed to correctly work in child/spawned threads from a parent thread (sometimes surfaced in Tomcat environments)

 * org.jsecurity.web.servlet.FilterChainWrapper renamed to org.jsecurity.web.servlet.ProxiedFilterChain to maintain parallel naming conventions with ProxiedSession.

 * org.jsecurity.web.attr.CookieAttribute#onRetrieveValue would return deleted cookies (maxAge of 0) on Tomcat.  It now only returns a value if the cookie is non null and maxAge != 0 (-1 or positive only).

+* Added *AnnotationHandler implementations and refactored the AuthorizingAnnotationMethodInterceptor implementations

+  to delegate to internal AnnotationHandler instances for performing authorization checks based on annotations.  This was

+  done to ensure Annotations could be processed independently of where they are declared (method, class, etc).

+* New Feature: added @RequiresGuest, @RequiresUser, @RequiresAuthentication annotations (and corresponding

+  AnnotationHandler implementations to support them).

 

 [0.9 RC2]

 

diff --git a/src/org/jsecurity/aop/AnnotationHandler.java b/src/org/jsecurity/aop/AnnotationHandler.java
new file mode 100644
index 0000000..02523e5
--- /dev/null
+++ b/src/org/jsecurity/aop/AnnotationHandler.java
@@ -0,0 +1,84 @@
+/*
+ * 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.jsecurity.aop;
+
+import org.jsecurity.SecurityUtils;
+import org.jsecurity.subject.Subject;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Base support class for implementations that reads and processes JSR-175 annotations.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public abstract class AnnotationHandler {
+
+    /**
+     * The type of annotation this handler will process.
+     */
+    protected Class<? extends Annotation> annotationClass;
+
+    /**
+     * Constructs an <code>AnnotationHandler</code> who processes annotations of the
+     * specified type.  Immediately calls {@link #setAnnotationClass(Class)}.
+     *
+     * @param annotationClass the type of annotation this handler will process.
+     */
+    public AnnotationHandler(Class<? extends Annotation> annotationClass) {
+        setAnnotationClass(annotationClass);
+    }
+
+    /**
+     * Returns the {@link org.jsecurity.subject.Subject Subject} associated with the currently-executing code.
+     * <p/>
+     * This default implementation merely calls <code>{@link org.jsecurity.SecurityUtils#getSubject SecurityUtils.getSubject()}</code>.
+     *
+     * @return the {@link org.jsecurity.subject.Subject Subject} associated with the currently-executing code.
+     */
+    protected Subject getSubject() {
+        return SecurityUtils.getSubject();
+    }
+
+    /**
+     * Sets the type of annotation this handler will inspect and process.
+     *
+     * @param annotationClass the type of annotation this handler will process.
+     * @throws IllegalArgumentException if the argument is <code>null</code>.
+     */
+    protected void setAnnotationClass(Class<? extends Annotation> annotationClass)
+            throws IllegalArgumentException {
+        if (annotationClass == null) {
+            String msg = "annotationClass argument cannot be null";
+            throw new IllegalArgumentException(msg);
+        }
+        this.annotationClass = annotationClass;
+    }
+
+    /**
+     * Returns the type of annotation this handler inspects and processes.
+     *
+     * @return the type of annotation this handler inspects and processes.
+     */
+    public Class<? extends Annotation> getAnnotationClass() {
+        return this.annotationClass;
+    }
+
+}
diff --git a/src/org/jsecurity/aop/AnnotationMethodInterceptor.java b/src/org/jsecurity/aop/AnnotationMethodInterceptor.java
index 1fea165..0acaeea 100644
--- a/src/org/jsecurity/aop/AnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/aop/AnnotationMethodInterceptor.java
@@ -30,43 +30,25 @@
  */
 public abstract class AnnotationMethodInterceptor extends MethodInterceptorSupport {
 
-    /**
-     * The type of annotation this interceptor will inspect on methods at runtime.
-     */
-    protected Class<? extends Annotation> annotationClass;
+    private AnnotationHandler handler;
 
     /**
-     * Constructs an <code>AnnotationMethodInterceptor</code> who processes annotations of the
-     * specified type.  Immediately calls {@link #setAnnotationClass(Class)}.
+     * Constructs an <code>AnnotationMethodInterceptor</code> with the
+     * {@link AnnotationHandler AnnotationHandler} that will be used to process annotations of a corresponding
+     * type.
      *
-     * @param annotationClass the type of annotation this interceptor will process.
+     * @param handler the handler to delegate to for processing the annotation.
      */
-    public AnnotationMethodInterceptor(Class<? extends Annotation> annotationClass) {
-        setAnnotationClass(annotationClass);
+    public AnnotationMethodInterceptor(AnnotationHandler handler) {
+        setHandler(handler);
     }
 
-    /**
-     * Sets the type of annotation this interceptor will inspect on methods at runtime.
-     *
-     * @param annotationClass the type of annotation this interceptor will process.
-     * @throws IllegalArgumentException if the argument is <code>null</code>.
-     */
-    protected void setAnnotationClass(Class<? extends Annotation> annotationClass)
-            throws IllegalArgumentException {
-        if (annotationClass == null) {
-            String msg = "annotationClass argument cannot be null";
-            throw new IllegalArgumentException(msg);
-        }
-        this.annotationClass = annotationClass;
+    public AnnotationHandler getHandler() {
+        return handler;
     }
 
-    /**
-     * Returns the type of annotation this interceptor inspects on methods at runtime.
-     *
-     * @return the type of annotation this interceptor inspects on methods at runtime.
-     */
-    public Class<? extends Annotation> getAnnotationClass() {
-        return this.annotationClass;
+    public void setHandler(AnnotationHandler handler) {
+        this.handler = handler;
     }
 
     /**
@@ -91,7 +73,7 @@
      * The default implementation merely gets the underlying {@link Method Method} from the supplied
      * <code>MethodInvocation</code> argument, and returns:
      * <p/>
-     * <code>mi.{@link Method#getAnnotation(Class) getAnnotation}({@link #getAnnotationClass() getAnnotationClass()});</code>
+     * <code>mi.{@link Method#getAnnotation(Class) getAnnotation}({@link AnnotationHandler#getAnnotationClass() handler.getAnnotationClass()});</code>
      *
      * @param mi the MethodInvocation wrapping the Method from which the Annotation will be acquired.
      * @return the Annotation that this interceptor will process for the specified method invocation.
@@ -109,7 +91,7 @@
             throw new IllegalArgumentException(msg);
 
         }
-        return m.getAnnotation(getAnnotationClass());
+        return m.getAnnotation(getHandler().getAnnotationClass());
     }
 
 }
diff --git a/src/org/jsecurity/aop/MethodInterceptor.java b/src/org/jsecurity/aop/MethodInterceptor.java
index 4325b97..4b3a028 100644
--- a/src/org/jsecurity/aop/MethodInterceptor.java
+++ b/src/org/jsecurity/aop/MethodInterceptor.java
@@ -16,6 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+/*
+ * 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.jsecurity.aop;
 
 /**
diff --git a/src/org/jsecurity/aop/MethodInterceptorSupport.java b/src/org/jsecurity/aop/MethodInterceptorSupport.java
index f1ddc03..9ca97a7 100644
--- a/src/org/jsecurity/aop/MethodInterceptorSupport.java
+++ b/src/org/jsecurity/aop/MethodInterceptorSupport.java
@@ -16,6 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+/*
+ * 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.jsecurity.aop;
 
 import org.jsecurity.SecurityUtils;
diff --git a/src/org/jsecurity/aop/MethodInvocation.java b/src/org/jsecurity/aop/MethodInvocation.java
index 9efad09..e358f6d 100644
--- a/src/org/jsecurity/aop/MethodInvocation.java
+++ b/src/org/jsecurity/aop/MethodInvocation.java
@@ -16,6 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+/*
+ * 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.jsecurity.aop;
 
 import java.lang.reflect.Method;
diff --git a/src/org/jsecurity/authz/ModularRealmAuthorizer.java b/src/org/jsecurity/authz/ModularRealmAuthorizer.java
index 43b3a0b..b62fb02 100644
--- a/src/org/jsecurity/authz/ModularRealmAuthorizer.java
+++ b/src/org/jsecurity/authz/ModularRealmAuthorizer.java
@@ -152,7 +152,7 @@
 
     /**
      * Returns <code>true</code> if any of the configured realms' 
-     * {@link Realm#isPermitted(org.jsecurity.subject.PrincipalCollection, List<Permission>)} call returns <code>true</code>,
+     * {@link Realm#isPermitted(org.jsecurity.subject.PrincipalCollection, List)} call returns <code>true</code>,
      * <code>false</code> otherwise.
      */
     public boolean[] isPermitted(PrincipalCollection principals, List<Permission> permissions) {
diff --git a/src/org/jsecurity/authz/aop/AuthenticatedAnnotationHandler.java b/src/org/jsecurity/authz/aop/AuthenticatedAnnotationHandler.java
new file mode 100644
index 0000000..8dadd70
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/AuthenticatedAnnotationHandler.java
@@ -0,0 +1,56 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.authz.UnauthenticatedException;
+import org.jsecurity.authz.annotation.RequiresAuthentication;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Handles {@link RequiresAuthentication RequiresAuthentication} annotations and ensures the calling subject is
+ * authenticated before allowing access.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public class AuthenticatedAnnotationHandler extends AuthorizingAnnotationHandler {
+
+    /**
+     * Default no-argument constructor that ensures this handler to process
+     * {@link org.jsecurity.authz.annotation.RequiresAuthentication RequiresAuthentication} annotations.
+     */
+    public AuthenticatedAnnotationHandler() {
+        super(RequiresAuthentication.class);
+    }
+
+    /**
+     * Ensures that the calling <code>Subject</code> is authenticated, and if not, throws an
+     * {@link org.jsecurity.authz.UnauthenticatedException UnauthenticatedException} indicating the method is not allowed to be executed.
+     *
+     * @param a the annotation to inspect
+     * @throws org.jsecurity.authz.UnauthenticatedException if the calling <code>Subject</code> has not yet
+     * authenticated.
+     */
+    public void assertAuthorized(Annotation a) throws UnauthenticatedException {
+        if (a instanceof RequiresAuthentication && !getSubject().isAuthenticated() ) {
+            throw new UnauthenticatedException( "The current Subject is not authenticated.  Access denied." );
+        }
+    }
+}
diff --git a/src/org/jsecurity/authz/aop/AuthenticatedAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/AuthenticatedAnnotationMethodInterceptor.java
index 2025725..c35d713 100644
--- a/src/org/jsecurity/authz/aop/AuthenticatedAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/AuthenticatedAnnotationMethodInterceptor.java
@@ -18,10 +18,6 @@
  */
 package org.jsecurity.authz.aop;
 
-import org.jsecurity.aop.MethodInvocation;
-import org.jsecurity.authz.UnauthenticatedException;
-import org.jsecurity.authz.annotation.RequiresAuthentication;
-
 /**
  * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresAuthentication RequiresAuthenticated} annotation
  * is declared, and if so, ensures the calling
@@ -35,27 +31,10 @@
 
     /**
      * Default no-argument constructor that ensures this interceptor looks for
-     * @{@link org.jsecurity.authz.annotation.RequiresAuthentication RequiresAuthentication} annotations in a method
+     * {@link org.jsecurity.authz.annotation.RequiresAuthentication RequiresAuthentication} annotations in a method
      * declaration.
      */
     public AuthenticatedAnnotationMethodInterceptor() {
-        super(RequiresAuthentication.class);
-    }
-
-    /**
-     * Ensures that the calling <code>Subject</code> is authenticated, and if not, throws an
-     * {@link UnauthenticatedException UnauthenticatedException} indicating the method is not allowed to be executed.
-     *
-     * @param mi the method invocation to check for authentication
-     * @throws UnauthenticatedException if the calling <code>Subject</code> has not yet
-     * authenticated.
-     */
-    public void assertAuthorized(MethodInvocation mi) throws UnauthenticatedException {
-        RequiresAuthentication annotation = (RequiresAuthentication)getAnnotation(mi);
-        if ( annotation != null ) {
-            if ( !getSubject().isAuthenticated() ) {
-                throw new UnauthenticatedException( "The current Subject is not authenticated.  Method invocation denied." );
-            }
-        }
+        super( new AuthenticatedAnnotationHandler() );
     }
 }
diff --git a/src/org/jsecurity/authz/aop/AuthorizingAnnotationHandler.java b/src/org/jsecurity/authz/aop/AuthorizingAnnotationHandler.java
new file mode 100644
index 0000000..57268c8
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/AuthorizingAnnotationHandler.java
@@ -0,0 +1,56 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.aop.AnnotationHandler;
+import org.jsecurity.authz.AuthorizationException;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * An AnnotationHandler that executes authorization (access control) behavior based on directive(s) found in a
+ * JSR-175 Annotation.
+ *
+ * @since 0.9.0 RC3
+ * @author Les Hazlewood
+ */
+public abstract class AuthorizingAnnotationHandler extends AnnotationHandler {
+
+    /**
+     * Constructs an <code>AuthorizingAnnotationHandler</code> who processes annotations of the
+     * specified type.  Immediately calls <code>super(annotationClass)</code>.
+     *
+     * @param annotationClass the type of annotation this handler will process.
+     */
+    public AuthorizingAnnotationHandler(Class<? extends Annotation> annotationClass) {
+        super(annotationClass);
+    }
+
+    /**
+     * Ensures the calling Subject is authorized to execute based on the directive(s) found in the given
+     * annotation.
+     * <p/>
+     * As this is an AnnotationMethodInterceptor, the implementations of this method typically inspect the annotation
+     * and perform a corresponding authorization check based.
+     *
+     * @param a the <code>Annotation</code> to check for performing an authorization check.
+     * @throws org.jsecurity.authz.AuthorizationException if the class/instance/method is not allowed to proceed/execute.
+     */
+    public abstract void assertAuthorized(Annotation a) throws AuthorizationException;
+}
diff --git a/src/org/jsecurity/authz/aop/AuthorizingAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/AuthorizingAnnotationMethodInterceptor.java
index d8b9968..a04aa53 100644
--- a/src/org/jsecurity/authz/aop/AuthorizingAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/AuthorizingAnnotationMethodInterceptor.java
@@ -22,8 +22,6 @@
 import org.jsecurity.aop.MethodInvocation;
 import org.jsecurity.authz.AuthorizationException;
 
-import java.lang.annotation.Annotation;
-
 /**
  * An <tt>AnnotationMethodInterceptor</tt> that asserts the calling code is authorized to execute the method
  * before allowing the invocation to continue by inspecting code annotations to perform an access control check.
@@ -32,14 +30,15 @@
  * @since 0.1
  */
 public abstract class AuthorizingAnnotationMethodInterceptor extends AnnotationMethodInterceptor {
-
+    
     /**
-     * Default constructor that merely calls {@link org.jsecurity.aop.AnnotationMethodInterceptor super(annotationClass)}
-     * @param annotationClass the specific annotatation class this interceptor will look for when performing an
-     * authorization check.
+     * Constructor that ensures the internal <code>handler</code> is set which will be used to perform the
+     * authorization assertion checks when a supported annotation is encountered.
+     * @param handler the internal <code>handler</code> used to perform authorization assertion checks when a 
+     * supported annotation is encountered.
      */
-    public AuthorizingAnnotationMethodInterceptor(Class<? extends Annotation> annotationClass) {
-        super(annotationClass);
+    public AuthorizingAnnotationMethodInterceptor( AuthorizingAnnotationHandler handler ) {
+        super(handler);
     }
 
     /**
@@ -59,12 +58,15 @@
     /**
      * Ensures the calling Subject is authorized to execute the specified <code>MethodInvocation</code>.
      * <p/>
-     * As this is an AnnotationMethodInterceptor, the implementations of this method typically inspect the method to
-     * see if it has a specific Annotation, and if it does, performs an authorization check based on the information
-     * defined by the Annotation.
+     * As this is an AnnotationMethodInterceptor, this implementation merely delegates to the internal
+     * {@link AuthorizingAnnotationHandler AuthorizingAnnotationHandler} by first acquiring the annotation by
+     * calling {@link #getAnnotation(MethodInvocation) getAnnotation(methodInvocation)} and then calls
+     * {@link AuthorizingAnnotationHandler#assertAuthorized(java.lang.annotation.Annotation) handler.assertAuthorized(annotation)}.
      *
      * @param mi the <code>MethodInvocation</code> to check to see if it is allowed to proceed/execute.
      * @throws AuthorizationException if the method invocation is not allowed to continue/execute.
      */
-    public abstract void assertAuthorized(MethodInvocation mi) throws AuthorizationException;
+    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
+        ((AuthorizingAnnotationHandler)getHandler()).assertAuthorized(getAnnotation(mi));
+    }
 }
diff --git a/src/org/jsecurity/authz/aop/GuestAnnotationHandler.java b/src/org/jsecurity/authz/aop/GuestAnnotationHandler.java
new file mode 100644
index 0000000..8799415
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/GuestAnnotationHandler.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.authz.AuthorizationException;
+import org.jsecurity.authz.UnauthenticatedException;
+import org.jsecurity.authz.annotation.RequiresGuest;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresGuest RequiresGuest} annotation
+ * is declared, and if so, ensures the calling <code>Subject</code> does <em>not</em>
+ * have an {@link org.jsecurity.subject.Subject#getPrincipal() identity} before invoking the method.
+ * <p>
+ * This annotation essentially ensures that <code>subject.{@link org.jsecurity.subject.Subject#getPrincipal() getPrincipal()} == null</code>.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public class GuestAnnotationHandler extends AuthorizingAnnotationHandler {
+
+    /**
+     * Default no-argument constructor that ensures this interceptor looks for
+     *
+     * {@link org.jsecurity.authz.annotation.RequiresGuest RequiresGuest} annotations in a method
+     * declaration.
+     */
+    public GuestAnnotationHandler() {
+        super(RequiresGuest.class);
+    }
+
+    /**
+     * Ensures that the calling <code>Subject</code> is NOT a <em>user</em>, that is, they do not
+     * have an {@link org.jsecurity.subject.Subject#getPrincipal() identity} before continuing.  If they are
+     * a user ({@link org.jsecurity.subject.Subject#getPrincipal() Subject.getPrincipal()} != null), an
+     * <code>AuthorizingException</code> will be thrown indicating that execution is not allowed to continue.
+     *
+     * @param a the annotation to check for one or more roles
+     * @throws org.jsecurity.authz.AuthorizationException
+     *          if the calling <code>Subject</code> is not a &quot;guest&quot;.
+     */
+    public void assertAuthorized(Annotation a) throws AuthorizationException {
+        if (a instanceof RequiresGuest && getSubject().getPrincipal() != null) {
+            throw new UnauthenticatedException("Attempting to perform a guest-only operation.  The current Subject is " +
+                    "not a guest (they have been authenticated or remembered from a previous login).  Access " +
+                    "denied.");
+        }
+    }
+}
diff --git a/src/org/jsecurity/authz/aop/GuestAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/GuestAnnotationMethodInterceptor.java
index f8b1a86..a7173d5 100644
--- a/src/org/jsecurity/authz/aop/GuestAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/GuestAnnotationMethodInterceptor.java
@@ -18,11 +18,6 @@
  */
 package org.jsecurity.authz.aop;
 
-import org.jsecurity.aop.MethodInvocation;
-import org.jsecurity.authz.AuthorizationException;
-import org.jsecurity.authz.UnauthenticatedException;
-import org.jsecurity.authz.annotation.RequiresGuest;
-
 /**
  * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresGuest RequiresGuest} annotation
  * is declared, and if so, ensures the calling <code>Subject</code> does <em>not</em>
@@ -37,31 +32,10 @@
 
     /**
      * Default no-argument constructor that ensures this interceptor looks for
-     * @{@link org.jsecurity.authz.annotation.RequiresGuest RequiresGuest} annotations in a method
+     * {@link org.jsecurity.authz.annotation.RequiresGuest RequiresGuest} annotations in a method
      * declaration.
      */
     public GuestAnnotationMethodInterceptor() {
-        super(RequiresGuest.class);
-    }
-
-    /**
-     * Ensures that the calling <code>Subject</code> is NOT a <em>user</em>, that is, they do not
-     * have an {@link org.jsecurity.subject.Subject#getPrincipal() identity} before invoking the method.  If they are
-     * a user ({@link org.jsecurity.subject.Subject#getPrincipal() Subject.getPrincipal()} != null), an
-     * <code>AuthorizingException</code> will be thrown indicating the method is not allowed to be executed.
-     *
-     * @param mi the method invocation to check for one or more roles
-     * @throws org.jsecurity.authz.AuthorizationException
-     *          if the calling <code>Subject</code> is not a &quot;guest&quot;.
-     */
-    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
-        RequiresGuest annotation = (RequiresGuest) getAnnotation(mi);
-        if (annotation != null) {
-            if (getSubject().getPrincipal() != null) {
-                throw new UnauthenticatedException("Attempting to access a guest-only method.  The current Subject is " +
-                        "not a guest (they have been authenticated or remembered from a previous login).  Method " +
-                        "invocation denied.");
-            }
-        }
+        super(new GuestAnnotationHandler());
     }
 }
diff --git a/src/org/jsecurity/authz/aop/PermissionAnnotationHandler.java b/src/org/jsecurity/authz/aop/PermissionAnnotationHandler.java
new file mode 100644
index 0000000..0bce4f0
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/PermissionAnnotationHandler.java
@@ -0,0 +1,93 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.authz.AuthorizationException;
+import org.jsecurity.authz.UnauthorizedException;
+import org.jsecurity.authz.annotation.RequiresPermissions;
+import org.jsecurity.subject.Subject;
+import org.jsecurity.util.PermissionUtils;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+/**
+ * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresPermissions RequiresPermissions} annotation is
+ * declared, and if so, performs a permission check to see if the calling <code>Subject</code> is allowed continued
+ * access.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public class PermissionAnnotationHandler extends AuthorizingAnnotationHandler {
+
+    /**
+     * Default no-argument constructor that ensures this handler looks for
+     * {@link org.jsecurity.authz.annotation.RequiresPermissions RequiresPermissions} annotations.
+     */
+    public PermissionAnnotationHandler() {
+        super(RequiresPermissions.class);
+    }
+
+    /**
+     * Returns the annotation {@link RequiresPermissions#value value}, from which the Permission will be constructed.
+     *
+     * @param a the RequiresPermissions annotation being inspected.
+     * @return the annotation's <code>value</code>, from which the Permission will be constructed.
+     */
+    protected String getAnnotationValue(Annotation a) {
+        RequiresPermissions rpAnnotation = (RequiresPermissions)a;
+        return rpAnnotation.value();
+    }
+
+    /**
+     * Ensures that the calling <code>Subject</code> has the Annotation's specified permissions, and if not, throws an
+     * <code>AuthorizingException</code> indicating access is denied.
+     *
+     * @param a the RequiresPermission annotation being inspected to check for one or more permissions
+     * @throws org.jsecurity.authz.AuthorizationException if the calling <code>Subject</code> does not have the permission(s) necessary to
+     * continue access or execution.
+     */
+    public void assertAuthorized(Annotation a) throws AuthorizationException {
+        if ( !(a instanceof RequiresPermissions) ) {
+            return;
+        }
+        String p = getAnnotationValue(a);
+        Set<String> perms = PermissionUtils.toPermissionStrings(p);
+
+        Subject subject = getSubject();
+
+        if (perms.size() == 1) {
+            if (!subject.isPermitted(perms.iterator().next())) {
+                String msg = "Calling Subject does not have required permission [" + p + "].  " +
+                        "Method invocation denied.";
+                throw new UnauthorizedException(msg);
+            }
+        } else {
+            String[] permStrings = new String[perms.size()];
+            permStrings = perms.toArray(permStrings);
+            if (!subject.isPermittedAll(permStrings)) {
+                String msg = "Calling Subject does not have required permissions [" + p + "].  " +
+                        "Method invocation denied.";
+                throw new UnauthorizedException(msg);
+            }
+
+        }
+    }
+}
diff --git a/src/org/jsecurity/authz/aop/PermissionAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/PermissionAnnotationMethodInterceptor.java
index 07c696f..1385e81 100644
--- a/src/org/jsecurity/authz/aop/PermissionAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/PermissionAnnotationMethodInterceptor.java
@@ -18,15 +18,7 @@
  */
 package org.jsecurity.authz.aop;
 
-import org.apache.commons.beanutils.PropertyUtils;
-import org.jsecurity.aop.MethodInvocation;
-import org.jsecurity.authz.AuthorizationException;
-import org.jsecurity.authz.UnauthorizedException;
 import org.jsecurity.authz.annotation.RequiresPermissions;
-import org.jsecurity.subject.Subject;
-import org.jsecurity.util.PermissionUtils;
-
-import java.util.Set;
 
 /**
  * Checks to see if a @{@link RequiresPermissions RequiresPermissions} annotation is declared, and if so, performs
@@ -36,26 +28,26 @@
  */
 public class PermissionAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
 
-    /**
+    /*
      * The character to look for that closes a permission definition.
-     */
-    private static final char ARRAY_CLOSE_CHAR = ']';
+     **/
+    //private static final char ARRAY_CLOSE_CHAR = ']';
 
     /**
      * Default no-argument constructor that ensures this interceptor looks for
-     * @{@link RequiresPermissions RequiresPermissions} annotations in a method declaration.
+     * {@link RequiresPermissions RequiresPermissions} annotations in a method declaration.
      */
     public PermissionAnnotationMethodInterceptor() {
-        super(RequiresPermissions.class);
+        super( new PermissionAnnotationHandler() );
     }
 
-    /**
+    /*
      * Infers the permission from the specified name path in the annotation.
      * @param methodArgs the <code>MethodInvocation</code> method arguments.
      * @param namePath the Annotation 'name' value, which is a string-based permission definition.
      * @return the String permission representation.
      * @throws Exception if there is an error infering the target.
-     */
+     *
     protected String inferTargetFromPath(Object[] methodArgs, String namePath) throws Exception {
         int propertyStartIndex = -1;
 
@@ -82,11 +74,11 @@
         return targetValue.toString();
     }
 
-    /**
+    /*
      * Returns the <code>MethodInvocation</code>'s arguments, or <code>null</code> if there were none.
      * @param invocation the methodInvocation to inspect.
      * @return the method invocation's method arguments, or <code>null</code> if there were none.
-     */
+     *
     protected Object[] getMethodArguments(MethodInvocation invocation) {
         if (invocation != null) {
             return invocation.getArguments();
@@ -95,48 +87,14 @@
         }
     }
 
-    /**
+    /*
      * Returns the annotation {@link RequiresPermissions#value value}, from which the Permission will be constructed.
      *
      * @param invocation the method being invoked.
      * @return the method annotation's <code>value</code>, from which the Permission will be constructed.
-     */
+     *
     protected String getAnnotationValue(MethodInvocation invocation) {
         RequiresPermissions prAnnotation = (RequiresPermissions) getAnnotation(invocation);
         return prAnnotation.value();
-    }
-
-    /**
-     * Ensures that the calling <code>Subject</code> has the Annotation's specified permissions, and if not, throws an
-     * <code>AuthorizingException</code> indicating the method is not allowed to be executed.
-     *
-     * @param mi the method invocation to check for one or more permissions
-     * @throws AuthorizationException if the calling <code>Subject</code> does not have the permission(s) necessary to
-     * invoke the method.
-     */
-    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
-        String p = getAnnotationValue(mi);
-        Set<String> perms = PermissionUtils.toPermissionStrings(p);
-
-        Subject subject = getSubject();
-
-        if (perms.size() == 1) {
-            if (!subject.isPermitted(perms.iterator().next())) {
-                String msg = "Calling Subject does not have required permission [" + p + "].  " +
-                        "Method invocation denied.";
-                throw new UnauthorizedException(msg);
-            }
-        } else {
-            String[] permStrings = new String[perms.size()];
-            permStrings = perms.toArray(permStrings);
-            if (!subject.isPermittedAll(permStrings)) {
-                String msg = "Calling Subject does not have required permissions [" + p + "].  " +
-                        "Method invocation denied.";
-                throw new UnauthorizedException(msg);
-            }
-
-        }
-    }
-
-
+    } */
 }
diff --git a/src/org/jsecurity/authz/aop/RoleAnnotationHandler.java b/src/org/jsecurity/authz/aop/RoleAnnotationHandler.java
new file mode 100644
index 0000000..3812270
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/RoleAnnotationHandler.java
@@ -0,0 +1,81 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.authz.AuthorizationException;
+import org.jsecurity.authz.UnauthorizedException;
+import org.jsecurity.authz.annotation.RequiresRoles;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresRoles RequiresRoles} annotation is declared, and if so, performs
+ * a role check to see if the calling <code>Subject</code> is allowed to proceed.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public class RoleAnnotationHandler extends AuthorizingAnnotationHandler {
+
+    /**
+     * Default no-argument constructor that ensures this handler looks for
+     * {@link org.jsecurity.authz.annotation.RequiresRoles RequiresRoles} annotations.
+     */
+    public RoleAnnotationHandler() {
+        super(RequiresRoles.class);
+    }
+
+    /**
+     * Ensures that the calling <code>Subject</code> has the Annotation's specified roles, and if not, throws an
+     * <code>AuthorizingException</code> indicating that access is denied.
+     *
+     * @param a the RequiresRoles annotation to use to check for one or more roles
+     * @throws org.jsecurity.authz.AuthorizationException if the calling <code>Subject</code> does not have the role(s) necessary to
+     * proceed.
+     */
+    public void assertAuthorized(Annotation a) throws AuthorizationException {
+        if ( !(a instanceof RequiresRoles ) ) {
+            return;
+        }
+        RequiresRoles rrAnnotation = (RequiresRoles)a;
+
+        String roleId = rrAnnotation.value();
+
+        String[] roles = roleId.split(",");
+
+        if (roles.length == 1) {
+            if (!getSubject().hasRole(roles[0])) {
+                String msg = "Calling Subject does not have required role [" + roleId + "].  " +
+                        "MethodInvocation denied.";
+                throw new UnauthorizedException(msg);
+            }
+        } else {
+            Set<String> rolesSet = new LinkedHashSet<String>(Arrays.asList(roles));
+            if (!getSubject().hasAllRoles(rolesSet)) {
+                String msg = "Calling Subject does not have required roles [" + roleId + "].  " +
+                        "MethodInvocation denied.";
+                throw new UnauthorizedException(msg);
+            }
+        }
+    }
+
+}
diff --git a/src/org/jsecurity/authz/aop/RoleAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/RoleAnnotationMethodInterceptor.java
index f0bd2c2..683ef8a 100644
--- a/src/org/jsecurity/authz/aop/RoleAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/RoleAnnotationMethodInterceptor.java
@@ -18,15 +18,8 @@
  */
 package org.jsecurity.authz.aop;
 
-import org.jsecurity.aop.MethodInvocation;
-import org.jsecurity.authz.AuthorizationException;
-import org.jsecurity.authz.UnauthorizedException;
 import org.jsecurity.authz.annotation.RequiresRoles;
 
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
 /**
  * Checks to see if a @{@link RequiresRoles RequiresRoles} annotation is declared, and if so, performs
  * a role check to see if the calling <code>Subject</code> is allowed to invoke the method.
@@ -38,40 +31,9 @@
 
     /**
      * Default no-argument constructor that ensures this interceptor looks for
-     * @{@link RequiresRoles RequiresRoles} annotations in a method declaration.
+     * {@link RequiresRoles RequiresRoles} annotations in a method declaration.
      */
     public RoleAnnotationMethodInterceptor() {
-        super(RequiresRoles.class);
-    }
-
-    /**
-     * Ensures that the calling <code>Subject</code> has the Annotation's specified roles, and if not, throws an
-     * <code>AuthorizingException</code> indicating the method is not allowed to be executed.
-     *
-     * @param mi the method invocation to check for one or more roles
-     * @throws AuthorizationException if the calling <code>Subject</code> does not have the role(s) necessary to
-     * invoke the method.
-     */
-    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
-        RequiresRoles rrAnnotation = (RequiresRoles) getAnnotation(mi);
-
-        String roleId = rrAnnotation.value();
-
-        String[] roles = roleId.split(",");
-
-        if (roles.length == 1) {
-            if (!getSubject().hasRole(roles[0])) {
-                String msg = "Calling Subject does not have required role [" + roleId + "].  " +
-                        "MethodInvocation denied.";
-                throw new UnauthorizedException(msg);
-            }
-        } else {
-            Set<String> rolesSet = new LinkedHashSet<String>(Arrays.asList(roles));
-            if (!getSubject().hasAllRoles(rolesSet)) {
-                String msg = "Calling Subject does not have required roles [" + roleId + "].  " +
-                        "MethodInvocation denied.";
-                throw new UnauthorizedException(msg);
-            }
-        }
+        super( new RoleAnnotationHandler() );
     }
 }
diff --git a/src/org/jsecurity/authz/aop/UserAnnotationHandler.java b/src/org/jsecurity/authz/aop/UserAnnotationHandler.java
new file mode 100644
index 0000000..69a9ec3
--- /dev/null
+++ b/src/org/jsecurity/authz/aop/UserAnnotationHandler.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jsecurity.authz.aop;
+
+import org.jsecurity.authz.AuthorizationException;
+import org.jsecurity.authz.UnauthenticatedException;
+import org.jsecurity.authz.annotation.RequiresUser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresUser RequiresUser} annotation
+ * is declared, and if so, ensures the calling <code>Subject</code> is <em>either</em>
+ * {@link org.jsecurity.subject.Subject#isAuthenticated() authenticated} <b><em>or</em></b> remembered via remember
+ * me services before allowing access.
+ * <p>
+ * This annotation essentially ensures that <code>subject.{@link org.jsecurity.subject.Subject#getPrincipal() getPrincipal()} != null</code>.
+ *
+ * @author Les Hazlewood
+ * @since 0.9.0 RC3
+ */
+public class UserAnnotationHandler extends AuthorizingAnnotationHandler {
+
+    /**
+     * Default no-argument constructor that ensures this handler looks for
+     *
+     * {@link org.jsecurity.authz.annotation.RequiresUser RequiresUser} annotations.
+     */
+    public UserAnnotationHandler() {
+        super(RequiresUser.class);
+    }
+
+    /**
+     * Ensures that the calling <code>Subject</code> is a <em>user</em>, that is, they are <em>either</code>
+     * {@link org.jsecurity.subject.Subject#isAuthenticated() authenticated} <b><em>or</em></b> remembered via remember
+     * me services before allowing access, and if not, throws an
+     * <code>AuthorizingException</code> indicating access is not allowed.
+     *
+     * @param a the RequiresUser annotation to check
+     * @throws org.jsecurity.authz.AuthorizationException
+     *         if the calling <code>Subject</code> is not authenticated or remembered via rememberMe services.
+     */
+    public void assertAuthorized(Annotation a) throws AuthorizationException {
+        if (a instanceof RequiresUser && getSubject().getPrincipal() == null) {
+            throw new UnauthenticatedException("Attempting to perform a user-only operation.  The current Subject is " +
+                    "not a user (they haven't been authenticated or remembered from a previous login).  " +
+                    "Access denied.");
+        }
+    }
+}
diff --git a/src/org/jsecurity/authz/aop/UserAnnotationMethodInterceptor.java b/src/org/jsecurity/authz/aop/UserAnnotationMethodInterceptor.java
index 0d0b1c0..70e7aeb 100644
--- a/src/org/jsecurity/authz/aop/UserAnnotationMethodInterceptor.java
+++ b/src/org/jsecurity/authz/aop/UserAnnotationMethodInterceptor.java
@@ -18,11 +18,6 @@
  */
 package org.jsecurity.authz.aop;
 
-import org.jsecurity.aop.MethodInvocation;
-import org.jsecurity.authz.AuthorizationException;
-import org.jsecurity.authz.UnauthenticatedException;
-import org.jsecurity.authz.annotation.RequiresUser;
-
 /**
  * Checks to see if a @{@link org.jsecurity.authz.annotation.RequiresUser RequiresUser} annotation
  * is declared, and if so, ensures the calling <code>Subject</code> is <em>either</em>
@@ -39,31 +34,11 @@
     /**
      * Default no-argument constructor that ensures this interceptor looks for
      *
-     * @{@link org.jsecurity.authz.annotation.RequiresUser RequiresUser} annotations in a method
+     * {@link org.jsecurity.authz.annotation.RequiresUser RequiresUser} annotations in a method
      * declaration.
      */
     public UserAnnotationMethodInterceptor() {
-        super(RequiresUser.class);
+        super( new UserAnnotationHandler() );
     }
 
-    /**
-     * Ensures that the calling <code>Subject</code> is a <em>user</em>, that is, they are <em>either</code>
-     * {@link org.jsecurity.subject.Subject#isAuthenticated() authenticated} <b><em>or</em></b> remembered via remember
-     * me services before invoking the method, and if not, throws an
-     * <code>AuthorizingException</code> indicating the method is not allowed to be executed.
-     *
-     * @param mi the method invocation to check for one or more roles
-     * @throws org.jsecurity.authz.AuthorizationException
-     *          if the calling <code>Subject</code> is not authenticated or remembered via rememberMe services.
-     */
-    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
-        RequiresUser annotation = (RequiresUser) getAnnotation(mi);
-        if (annotation != null) {
-            if (getSubject().getPrincipal() == null) {
-                throw new UnauthenticatedException("Attempting to access a user-only method.  The current Subject is " +
-                        "not a user (they haven't been authenticated or remembered from a previous login).  " +
-                        "Method invocation denied.");
-            }
-        }
-    }
 }
diff --git a/src/org/jsecurity/authz/aop/package-info.java b/src/org/jsecurity/authz/aop/package-info.java
index a4b609b..8519138 100644
--- a/src/org/jsecurity/authz/aop/package-info.java
+++ b/src/org/jsecurity/authz/aop/package-info.java
@@ -17,6 +17,7 @@
  * under the License.

  */

 /**

- * Contains AOP implementation support classes specifically used for authorization operations.

+ * Contains AOP implementation support classes specifically used for authorization operations, particularly supporting

+ * AOP Method Interceptors and JSR-175 metadata Annotations.

  */

 package org.jsecurity.authz.aop;
\ No newline at end of file
diff --git a/src/org/jsecurity/mgt/SessionsSecurityManager.java b/src/org/jsecurity/mgt/SessionsSecurityManager.java
index e96fd5c..59a5a9b 100644
--- a/src/org/jsecurity/mgt/SessionsSecurityManager.java
+++ b/src/org/jsecurity/mgt/SessionsSecurityManager.java
@@ -137,7 +137,7 @@
     }
 
     /**
-     * Calls {@link super#afterCacheManagerSet() super.afterCacheManagerSet()} and then immediately calls
+     * Calls {@link AuthorizingSecurityManager#afterCacheManagerSet() super.afterCacheManagerSet()} and then immediately calls
      * {@link #applyCacheManagerToSessionManager() applyCacheManagerToSessionManager()} to ensure the
      * <code>CacheManager</code> is applied to the SessionManager as necessary.
      */
diff --git a/src/org/jsecurity/realm/Realm.java b/src/org/jsecurity/realm/Realm.java
index d60fada..1b9dfae 100644
--- a/src/org/jsecurity/realm/Realm.java
+++ b/src/org/jsecurity/realm/Realm.java
@@ -34,7 +34,8 @@
  * <a href="http://en.wikipedia.org/wiki/Data_Access_Object" target="_blank">DAO</a>s.
  *
  * <p>Because most of these datasources usually contain Subject (a.k.a. User) information such as usernames and
- * passwords, a Realm can act as a pluggable authentication module in a PAM configuration.  This allows a Realm to
+ * passwords, a Realm can act as a pluggable authentication module in a
+ * <a href="http://en.wikipedia.org/wiki/Pluggable_Authentication_Modules">PAM</a> configuration.  This allows a Realm to
  * perform <i>both</i> authentication and authorization duties for a single datasource, which caters to the large
  * majority of applications.  If for some reason you don't want your Realm implementation to perform authentication
  * duties, you should override the {@link #supports(org.jsecurity.authc.AuthenticationToken)} method to always
diff --git a/src/org/jsecurity/util/LifecycleUtils.java b/src/org/jsecurity/util/LifecycleUtils.java
index ab212e5..8a2fbe5 100644
--- a/src/org/jsecurity/util/LifecycleUtils.java
+++ b/src/org/jsecurity/util/LifecycleUtils.java
@@ -77,10 +77,10 @@
     }

 

     /**

-     * Calls {@link #destroy destroy) for each object in the collection.  If the collection is <code>null</code> or

+     * Calls {@link #destroy(Object) destroy} for each object in the collection.  If the collection is <code>null</code> or

      * empty, this method returns quietly.

      *

-     * @param c the collection of objects to {@link #destroy destroy}.

+     * @param c the collection of objects to destroy.

      * @since 0.9

      */

     public static void destroy(Collection c) {

diff --git a/src/org/jsecurity/web/config/IniWebConfiguration.java b/src/org/jsecurity/web/config/IniWebConfiguration.java
index 2e2d1c8..d3da157 100644
--- a/src/org/jsecurity/web/config/IniWebConfiguration.java
+++ b/src/org/jsecurity/web/config/IniWebConfiguration.java
@@ -112,16 +112,7 @@
         this.filterConfig = filterConfig;
     }
 
-    /**
-     * This implementation:
-     * <ol>
-     * <li>
-     *
-     * @param request
-     * @param response
-     * @param originalChain
-     * @return
-     */
+    //TODO - JAVADOC
     public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
         if (this.chains == null || this.chains.isEmpty()) {
             return null;