This section provides the essential information about annotations in
		Java 5 needed to understand how annotations are treated in AspectJ 5.
		For a full introduction to annotations in Java, please see the
		documentation for the Java 5 SDK.
	
	      Java 5 introduces annotation types which can
	      be used to express metadata relating to program members in the
	      form of annotations. Annotations in Java 5 
	      can be applied to package and type declarations (classes,
	      interfaces, enums, and annotations), constructors, methods, 
	      fields, parameters, and variables. Annotations are specified in the
	      program source by using the @ symbol. For example,
	      the following piece of code uses the @Deprecated
	      annotation to indicate that the obsoleteMethod()
	      has been deprecated:
	    
		@Deprecated
		public void obsoleteMethod() { ... }
		
			Annotations may be marker annotations,
			single-valued annotations, or 
			multi-valued annotations.
			Annotation types with no members or that provide default values
			for all members may be used simply as marker annotations, as in
			the deprecation example above. Single-value annotation types have
			a single member, and the annotation may be written in one of
			two equivalent forms:
		
		@SuppressWarnings({"unchecked"})
		public void someMethod() {...}
		
			or
		
		@SuppressWarnings(value={"unchecked"})
		public void someMethod() {...}
		
			Multi-value annotations must use the member-name=value
			 syntax to specify annotation values. For example:
		
		@Authenticated(role="supervisor",clearanceLevel=5)
		public void someMethod() {...}
		
	      Annotations can have one of three retention policies:
	    
- Source-file retention
- 
	            	Annotations with source-file retention are read by the 
	            	compiler during the compilation process, but are not
	            	rendered in the generated .class files.
	             
- Class-file retention
- 
	        			This is the default retention policy. Annotations
	        			with class-file retention are read by the compiler
	        			and also retained in the generated 
	        			.class files.
	        		 
- Runtime retention
- 
	        			Annotations with runtime retention are read by the
	        			compiler, retained in the generated 
	        			.class files, and also made available
	        			at runtime.
	        		 
Local variable annotations are not retained in class files (or at runtime)
	    regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.
Accessing Annotations at Runtime
    		Java 5 supports a new interface, 
    		java.lang.reflect.AnnotatedElement, that is
    		implemented by the reflection classes in Java (Class, 
    		Constructor,
    		Field, Method, and 
    		Package). This interface gives you access
    		to annotations that have runtime retention via
    		the getAnnotation, getAnnotations, 
    		and isAnnotationPresent. Because annotation types are
    		just regular Java classes, the annotations returned by these methods
    		can be queried just like any regular Java object.
    	
    		It is important to understand the rules relating to inheritance of
    		annotations, as these have a bearing on join point matching
    		based on the presence or absence of annotations.
    	
    		By default annotations are not inherited. Given
    		the following program
    	
			@MyAnnotation
			class Super {
			  @Oneway public void foo() {}
			}
			
			class Sub extends Super {
			  public void foo() {}
			}
			
    		Then Sub does not have
    		the MyAnnotation annotation, and 
    		Sub.foo() is not an @Oneway
    		method, despite the fact that it overrides 
    		Super.foo() which is.
    	
    		If an annotation type has the meta-annotation @Inherited
    		then an annotation of that type on a class will cause
    		the annotation to be inherited by sub-classes. So, in the example
    		above, if the MyAnnotation type had the
    		@Inherited attribute, then Sub
    		would have the MyAnnotation annotation.    		
    	
    		@Inherited annotations are not inherited when used to
    		annotate anything other than a type. A type
    		that implements one or more interfaces never inherits any annotations from
    		the interfaces it implements.
    	
Join Point Matching based on Annotations
Note: compared to the previous version, this version restricts the
    use of annotations in type patterns (package annotations and outer type annotations
    cannot be specified inline), and requires parenthesis more often. These changes were
    made to make pointcut expressions easier to read and interpret.
  	This section discusses changes to type pattern and signature pattern matching in
  	AspectJ 5 that support matching join points based on the presence or absence of
  	annotations. We then discuss means of exposing annotation values within the body
  	of advice.
  
          For any kind of annotated element (type, method, constructor, package, etc.), 
          an annotation pattern can be used to match against the set of annotations
          on the annotated element. Annotation patterns are defined by the following
          grammar.
      
		AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern* 
        
		AnnotationTypePattern := FullyQualifiedName |
		                         '(' TypePattern ')'
  		                     
  		FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*  		
      
In simple terms, an annotation pattern element has one of two basic
      forms:
- @<qualified-name>, for example, @Foo, or 
          @org.xyz.Foo.
- @(<type-pattern>), for example, @(org.xzy..*), or
          @(Foo || Boo)
These simple elements may be negated using !, and
      combined by simple concatentation. The pattern @Foo @Boo
      matches an annotated element that has both an annotation of type Foo
      and an annotation of type Boo.
Some examples of annotation patterns follow:
      @Immutable
      
Matches any annotated element which has an annotation of 
      type Immutable.
      !@Persistent
      
Matches any annotated element which does not have an annotation of 
      type Persistent.
      @Foo @Goo
      
Matches any annotated element which has both an annotation of type Foo and
      an annotation of type Goo.
      @(Foo || Goo)
      
Matches any annotated element which has either an annotation of a type matching
      the type pattern (Foo || Goo). 
      In other words, an annotated element with either an
      annotation of type Foo or
      an annotation of type Goo (or both). (The parenthesis are required in this example).
      
      @(org.xyz..*)
      
Matches any annotated element which has either an annotation of a type matching
      the type pattern (org.xyz..*). 
      In other words, an annotated element with an annotation that is declared in the
      org.xyz package or a sub-package. (The parenthesis are required in this example).
AspectJ 1.5 extends type patterns to allow an optional AnnotationPattern
	prefix. (Extensions to this definition for generics are shown in the next chapter).
  	  	TypePattern := SimpleTypePattern |
  	  	               '!' TypePattern |
  	  	               '(' AnnotationPattern? TypePattern ')'
  	  	               TypePattern '&&' TypePattern |
  	  	               TypePattern '||' TypePattern |
  	  	
  	  	SimpleTypePattern := DottedNamePattern '+'? '[]'*
  	  	
  		DottedNamePattern := FullyQualifiedName RestOfNamePattern? |
  		                     '*' NotStarNamePattern?
  		
  		RestOfNamePattern := '..' DottedNamePattern |
  		                     '*' NotStarNamePattern?
  		                     
  		NotStarNamePattern := FullyQualifiedName RestOfNamePattern? |
  		                      '..' DottedNamePattern               
  		FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*  				  		  		  		               									 				  		             
	
Note that in most cases when annotations are used as part of a type pattern,
        the parenthesis are required (as in (@Foo Hello+)). In
        some cases (such as a type pattern used within a this
        pointcut expression, the parenthesis are optional:
        OptionalParensTypePattern := AnnotationPattern? TypePattern
      
		The following examples illustrate the use of annotations in type
		patterns:
	
     (@Immutable *)
     
Matches any type with an @Immutable annotation.
     (!@Immutable *)
     
Matches any type which does not have an @Immutable annotation.
     (@Immutable (org.xyz.* || org.abc.*))
     
Matches any type in the org.xyz or org.abc
     packages with the @Immutable annotation.
     ((@Immutable Foo+) || Goo)
     
Matches a type Foo or any of its subtypes, which have the @Immutable
     annotation, or a type Goo.
     ((@(Immutable || NonPersistent) org.xyz..*)
     
     Matches any type in a package beginning with the prefix org.xyz,
     which has either the @Immutable annotation or the
     @NonPersistent annotation.
     
     (@Immutable @NonPersistent org.xyz..*)
     
     Matches any type in a package beginning with the prefix org.xyz,
     which has both an @Immutable annotation and an
     @NonPersistent annotation.
     
     (@(@Inherited *) org.xyz..*)
     
     Matches any type in a package beginning with the prefix org.xyz,
     which has an inheritable annotation. The annotation pattern 
     @(@Inherited *) matches any annotation of a type matching the
     type pattern @Inherited *, which in turn matches any type with the
     @Inherited annotation.
     
A FieldPattern is described by the following
  	grammar:
  	
  		FieldPattern := 
  		    AnnotationPattern? FieldModifiersPattern? 
  		    TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
		FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
		                         		
		FieldModifier := 'public' | 'private' | 'protected' | 'static' | 
		                 'transient' | 'final' 
		DotOrDotDot := '.' | '..'		            		      
		            		      		            			
		SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?		            
	
  	    The optional AnnotationPattern restricts matches to fields with
  	    annotations that match the pattern. For example:
  	
- @SensitiveData * *
- 
            	Matches a field of any type and any name, that has an annotation of
            	type @SensitiveData
             
- @SensitiveData List org.xyz..*.*
- 
            	Matches a member field of a type in a package with prefix org.xzy,
            	where the field is of type List, and has an annotation of type
            	@SensitiveData
             
- (@SensitiveData *) org.xyz..*.*
- 
            	Matches a member field of a type in a package with prefix org.xzy,
            	where the field is of a type which has a @SensitiveData annotation.
             
- @Foo (@Goo *) (@Hoo *).*
- 
            	Matches a field with an annotation @Foo, of a type with an 
            	annotation @Goo, declared in a type with annotation
            	@Hoo.
             
- @Persisted @Classified * *
- 
            	Matches a field with an annotation @Persisted and
            	an annotation @Classified.
             
A MethodPattern is of the form
  	
  		MethodPattern := 
  		    AnnotationPattern? MethodModifiersPattern? TypePattern 
  		                       (TypePattern DotOrDotDot)? SimpleNamePattern 
  		                       '(' FormalsPattern ')'ThrowsPattern?
		MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*
		
		MethodModifier := 'public' | 'private' | 'protected' | 'static' | 
		                  'synchronized' | 'final' 
		            		      
		FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* |
		                  OptionalParensTypePattern (',' FormalsPattern)* |
		                  TypePattern '...'
		                  
		FormalsPatternAfterDotDot := 
		        OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
		        TypePattern '...'
		                                               		                  
		ThrowsPattern := 'throws' TypePatternList
		
		TypePatternList := TypePattern (',' TypePattern)*
		            					            
	
Note: compared to the previous version, this definition of MethodPattern does
  	not allow parameter annotation matching (only matching on annotations of parameter types).
A ConstructorPattern has the form
  	
  		ConstructorPattern := 
  		    AnnotationPattern? ConstructorModifiersPattern?  
  		                       (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
  		                       ThrowsPattern?
	
		ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
		
		ConstructorModifier := 'public' | 'private' | 'protected'
		
	
  	    The optional AnnotationPattern at the beginning of a 
  	    method or constructor pattern restricts matches to methods/constructors with
  	    annotations that match the pattern. For example:
  	
- @Oneway * *(..)
- 
            	Matches a method with any return type and any name, that has an annotation of
            	type @Oneway.
             
- @Transaction * (@Persistent org.xyz..*).*(..)
- 
            	Matches a method with the @Transaction annotation,
            	declared in a type with the @Persistent annotation, and
            	in a package beginning with the org.xyz prefix.
             
- * *.*(@Immutable *,..)
- 
            	Matches any method taking at least one parameter, where the parameter
            	type has an annotation @Immutable.
             
- within(@Secure *)
- 
            	Matches any join point where the code executing is declared in a 
            	type with an @Secure
            	annotation. The format of the within pointcut designator
            	in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
             
- staticinitialization(@Persistent *)
- 
            	Matches the staticinitialization join point of any type with the
            	@Persistent annotation. The format of the 
            	staticinitialization pointcut designator
            	in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
             
- call(@Oneway * *(..))
- 
            	Matches a call to a method with a @Oneway annotation.
             
- execution(public (@Immutable *) org.xyz..*.*(..)
- 
                The execution of any public method in a package with prefix 
                org.xyz, where the method returns an 
                immutable result.
             
- set(@Cachable * *)
- 
                Matches the set of any cachable field.
             
- handler(!@Catastrophic *)
- 
                Matches the handler join point for the handling of any exception that is
                not Catastrophic. The format of the handler
                pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
             
Runtime type matching and context exposure
AspectJ 5 supports a set of "@" pointcut designators which
    can be used both to match based on the presence of an annotation at
    runtime, and to expose the annotation value as context in a pointcut or
    advice definition. These designators are @args, @this, @target,
    @within, @withincode, and @annotation
    
It is a compilation error to attempt to match on an annotation type 
    that does not have runtime retention using @this, @target
    or @args. It is a compilation error to attempt to use
    any of these designators to expose an annotation value that does not
    have runtime retention.
        The this(), target(), and
        args() pointcut designators allow matching based
        on the runtime type of an object, as opposed to the statically 
        declared type. In AspectJ 5, these designators are supplemented
        with three new designators : @this() (read, "this
        annotation"), @target(), and @args().    
    
        Like their counterparts, these pointcut designators can be used 
        both for join point matching, and to expose context. The format of 
        these new designators is:
    
  	
  	    AtThis := '@this' '(' AnnotationOrIdentifer ')'
    
  	    AtTarget := '@target' '(' AnnotationOrIdentifier ')'
  	
  	    AnnotationOrIdentifier := '@' FullyQualifiedName | Identifier
        
  	    AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
        
  	    AnnotationsOrIdentifiersPattern :=
  	                      '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
  	                      AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
  	                      '*' (',' AnnotationsOrIdentifiersPattern)*
		                  
  	    AnnotationsOrIdentifiersPatternAfterDotDot := 
		                  AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
		                  '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
  	
	
        The forms of @this() and @target() that
        take a single annotation name are analogous to their counterparts that take
        a single type name. They match at join points where the object bound to 
        this (or target, respectively) has an
        annotation of the specified type. For example: 
    
- @this(@Foo)
- 
            	Matches any join point where the object currently bound to 'this'
            	has an annotation of type Foo.
             
- call(* *(..)) && @target(@Classified)
- 
            	Matches a call to any object where the target of the call has
            	a @Classified annotation.
             
        Annotations can be exposed as context in the body of advice by 
        using the forms of @this(), @target() and
        @args() that use bound variables in the place
        of annotation names. For example:
    
  	pointcut callToClassifiedObject(Classified classificationInfo) :
  	    call(* *(..)) && @target(classificationInfo);
  	pointcut txRequiredMethod(Tx transactionAnnotation) :
  	    execution(* *(..)) && @this(transactionAnnotation) 
  	    && if(transactionAnnotation.policy == Tx.Policy.REQUIRED);
	
        The @args pointcut designator behaves as its args
        counterpart, matching join points based on number and position of arguments, and 
        supporting the * wildcard and at most one ..
        wildcard. An annotation at a given position in an @args expression
        indicates that the runtime type of the argument in that position at a join point must
        have an annotation of the indicated type. For example:
    
  	/**
  	 * matches any join point with at least one argument, and where the
  	 * type of the first argument has the @Classified annotation
  	 */
  	pointcut classifiedArgument() : @args(@Classified,..);
  	
  	/**
  	 * matches any join point with three arguments, where the third
  	 * argument has an annotation of type @Untrusted.
  	 */
  	pointcut untrustedData(Untrusted untrustedDataSource) : 
  	    @args(*,*,untrustedDataSource);
	
        Note: an alternative design would be to allow both annotation
        patterns and type patterns to be specified in the existing args pcd.
        This works well for matching, but is more awkward when it comes to
        exposing context.
    
Access to AnnotatedElement information is available
    reflectively with the body of advice through the thisJoinPoint,
    thisJoinPointStaticPart, and 
    thisEnclosingJoinPointStaticPart variables. To access 
    annotations on the arguments, or object bound to this or target at a join
    point you can use the following code fragments:
  	Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
  	Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations();
  	Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
	
        Note: it would be nicer to provide direct helper methods in
        the JoinPoint interface or a sub-interface that provide the annotations
        directly, something like "AnnotatedElement getThisAnnotationInfo()".
        The problem here is that the "AnnotatedElement" type is only in the
        Java 5 runtime libraries, and we don't want to tie the AspectJ runtime
        library to Java 5. A sub-interface and downcast solution could be used
        if these helpers were felt to be sufficiently important.
    
    The @within and @withincode pointcut designators
    match any join point where the executing code is defined within a type (@within),
     or a method/constructor (@withincode) that has an annotation of the specified 
    type. The form of these designators is:
    
  	
        AtWithin := '@within' '(' AnnotationOrIdentifier ')'
        AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'        
    
Some examples of using these designators follow:
- @within(@Foo)
- 
            	Matches any join point where the executing code is defined 
            	within a type which has an annotation of type Foo.
             
- pointcut insideCriticalMethod(Critical c) : 
                  @withincode(c);
- 
            	Matches any join point where the executing code is defined
            	in a method or constructor which has an annotation of type @Critical,
            	and exposes the value of the annotation in the parameter 
            	c.
             
The @annotation pointcut designator matches any
    join point where the subject of the join point has 
    an annotation of the given type. Like the other @pcds, it can also be
    used for context exposure.
  	
        AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
    
The subject of a join point is defined in the table in chapter one of
    this guide.
      Access to annotation information on members at a matched join point is also available
      through the getSignature method of the JoinPoint
      and JoinPoint.StaticPart interfaces. The MemberSignature
      interface is extended with the additional operation 
      java.lang.reflect.AccessibleObject getAccessibleObject(). The following fragment
      illustrates an example use of this interface to access annotation information.
    
  	Signature sig = thisJoinPointStaticPart.getSignature();
  	AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType();
  	if (sig instanceof MemberSignature) {
  	  // this must be an initialization, pre-initialization, call, execution, get, or
  	  // set join point.
  	  AnnotatedElement memberAnnotationInfo = ((MemberSignature)sig).getAccessibleObject();
  	}
	
        Note again that it would be nicer to add the method getAnnotationInfo
        directly to MemberSignature, but this would once more couple the runtime library
        to Java 5.
    
        The @this,@target and @args 
        pointcut designators can only be used to match against annotations 
        that have runtime retention. The @within, @withincode
        and @annotation pointcut designators can only be used
        to match against annotations that have at least class-file retention, and
        if used in the binding form the annotation must have runtime retention. 
    
Package and Parameter Annotations
          Note: A previous design allowed package annotation patterns to be specified
          directly in type patterns, and parameter annotation patterns to be
          specified directly in method and constructor signature patterns. Because
          this made some pointcut expressions hard to read and understand, we moved
          in favour of the design presented below, which also has its drawbacks. 
          Matching on package and parameter annotations will be
          deferred until after the 1.5.0 release so that we can gain more understanding
          of the kinds of uses AspectJ users are making of annotations in pointcut
          expressions before commiting to any one approach.
      
Annotation Inheritance and pointcut matching
  	    According to the Java 5 specification, non-type annotations are not
  	    inherited, and annotations on types are only inherited if they have the 
  	    @Inherited meta-annotation.
  	    
  	    Given the following program:
  	
  	class C1 {
  	  @SomeAnnotation
  	  public void aMethod() {...}
  	}
  	
  	class C2 extends C1 {
  	  public void aMethod() {...}
  	}
  	
  	class Main {
  	  public static void main(String[] args) {
  	    C1 c1 = new C1();
  	    C2 c2 = new C2();
  	    c1.aMethod();
  	    c2.aMethod();
  	  }
  	}
  	
  	aspect X {
  	
  	  pointcut annotatedMethodCall() : 
  	    call(@SomeAnnotation * C1.aMethod());
  	
  	  pointcut c1MethodCall() :
  	    call(* C1.aMethod());
  	}
	
  	    The pointcut annotatedMethodCall will match the call
  	    to c1.aMethod(), but not the call to 
  	    c2.aMethod().
  	
  	    The pointcut c1MethodCall matches both 
  	    c1.aMethod() and c2.aMethod().
  	
It would be useful to be able to match join points based on annotation
values, rather than merely the presence of a class-file retention
annotation of a given type. This facility may be supported in a future
version of AspectJ, by expanding the definition of AnnotationPattern. Matching annotation values for
        annotations with runtime retention can be done by exposing the annotation value
        as a pointcut parameter and then using an if pointcut expression
        to test the value.