[jboss-cvs] JBossAS SVN: r75858 - in projects/aop/branches/joinpoint_graph/aop/src: test/org/jboss/aop/joinpoint/graph and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jul 15 22:16:41 EDT 2008


Author: flavia.rainone at jboss.com
Date: 2008-07-15 22:16:41 -0400 (Tue, 15 Jul 2008)
New Revision: 75858

Added:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/NegativeCompositeSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParameterParser.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegator.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/todo.txt
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AbstractSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorJoinPointSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CalleeSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKeyTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKeyTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/EmptySearchKeyTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FullScenarioBuilder.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ParamSearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/PointcutDelegatorTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SearchKeyParserTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/StandardSearchKeyTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SubtypeSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypedefParserTest.java
Removed:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegateSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyImpl.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SimpleSearchKey.java
Modified:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisableClassNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AllSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorFilter.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorType.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CallSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcherFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/EmptySearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParsedSearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Searcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SubtypeSearcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypeFilter.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypedefParser.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisedDataTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisorMock.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllTests.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AnnPojo.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorNodeTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassNodeTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeDomainDataTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo2.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo4.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypeFilterTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Util.java
Log:
[JBAOP-508] The graph search mechanism tested and tidied up.

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisableClassNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisableClassNode.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisableClassNode.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -27,16 +27,9 @@
 import org.jboss.aop.Advisor;
 
 /**
- * Node that represents a class in the graph.
- * Such class must follow one of the restrictions:
+ * Node that represents an advisable class in the graph.
+ * Every advisable class node can contain:
  * <ul>
- * <li> it is a weaved class;</li>
- * <li> or it is a super type (class or interface) of a weaved class in the graph.
- * </li>
- * </ul>
- * 
- * Every advisable class node contains:
- * <ul>
  * <li> references to all the nodes that represent direct subtypes of it in the
  *      graph;</li>
  * <li> a subtree of behaviors, containing all behavior nodes associated with this
@@ -51,7 +44,6 @@
  */
 abstract class AdvisableClassNode extends ClassNode
 {
-   private Class clazz;
    private AdvisedData advisedData;
    
    /**
@@ -118,15 +110,6 @@
       return advisedData.searchFields(fieldExpression);
    }
    
-   public String toString()
-   {
-      if (clazz == null)
-      {
-         return "[node: null]";
-      }
-      return "[node: " + clazz.getName() + "]";
-   }
-   
    /**
     * Returns the advised data contained in this node.
     * 

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -50,7 +50,7 @@
    {
       this.advisor = advisor;
       this.fields = new Tree<FieldNode>();
-      this.behaviors = new Tree<BehaviorNode>();
+      this.behaviors = new Tree<BehaviorNode>(BehaviorNode.SEPARATOR);
    }
 
    /**

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AllSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AllSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AllSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -26,8 +26,8 @@
 import org.jboss.aop.JoinPointInfo;
 
 /**
- * Performs a search for all field-related joinpoints and method executions on a
- * class node.
+ * Performs a search for all field-related joinpoints and method/constructor
+ * executions on a class node.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -43,7 +43,7 @@
       return INSTANCE;
    }
 
-   private BehaviorSearcher allMethodExecutions;
+   private BehaviorSearcher allBehaviorExecutions;
    private FieldSearcher allFieldAccesses;
    
    /**
@@ -51,9 +51,9 @@
     */
    public AllSearcher()
    {
-      this.allMethodExecutions = new BehaviorSearcher("* *(*)",
-            ParsedSearchKey.EMPTY_ATTRIBUTES, ParsedSearchKey.EMPTY_EXCEPTIONS, null, true);
-      this.allMethodExecutions.setSearchType(BehaviorSearcher.SearchType.EXECUTION);
+      this.allBehaviorExecutions = new BehaviorSearcher("*",
+            ParsedSearchKey.EMPTY_ATTRIBUTES, ParsedSearchKey.EMPTY_EXCEPTIONS);
+      this.allBehaviorExecutions.setSearchType(BehaviorSearcher.SearchType.EXECUTION);
       this.allFieldAccesses = new FieldSearcher("*", ParsedSearchKey.EMPTY_ATTRIBUTES, null);
       this.allFieldAccesses.setSearchType(FieldSearcher.SearchType.ALL);
    }
@@ -61,6 +61,6 @@
    public void search(ClassNode node, Collection<JoinPointInfo> searchResult)
    {
       this.allFieldAccesses.search(node, searchResult);
-      this.allMethodExecutions.search(node, searchResult);
+      this.allBehaviorExecutions.search(node, searchResult);
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorFilter.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorFilter.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorFilter.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -42,22 +42,25 @@
    /**
     * Tests whether or not {@code constructor} is accepted or rejected by this filter.
     * 
-    * @param constructor the constructor to be tested.
-    * @return            {@code true} if this filter accepts {@code constructor}
+    * @param constructorWrapper wraps the constructor to be tested.
+    * @return                  {@code true} if this filter accepts the constructor
+    *                          wrapped in {@code constructorWrapper}
     */
    public boolean acceptConstructor(BehaviorWrapper<Constructor> constructorWrapper);
    
    /**
     * Tests whether or not {@code method} is accepted or rejected by this filter.
     * 
-    * @param method the method to be tested
-    * @return       {@code true} if this filter accepts {@code method}
+    * @param methodWrapper wraps the method to be tested
+    * @return                    {@code true} if this filter accepts the method
+    *                            wrapped in {@code methodWrapper}
     */
    public boolean acceptMethod(BehaviorWrapper<Method> methodWrapper);
 }
 
 /**
- * Checks if a behavior is accepted by two filters.
+ * A composite filter that accepts a behavior only if it is accepted by its
+ * component filters.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -67,7 +70,7 @@
    private BehaviorFilter filter2;
    
    /**
-    * Creates a disjunctive filter that will apply the restrictions represented by
+    * Creates a conjunctive filter that will apply the restrictions represented by
     * both {@code filter1} and {@code filter2}.
     * Always pick as filter1 the most likely one to fail for acceptance.
     */
@@ -91,7 +94,7 @@
 }
 
 /**
- * Checks if the return type of a method follow a type restriction.
+ * Checks if the return type of a method follows a type restriction.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -125,7 +128,7 @@
 }
 
 /**
- * Checks if the target type of a behavior follow a type restriction.
+ * Checks if the target type of a behavior follows a type restriction.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -176,7 +179,7 @@
     * superclass, or that are the implementation of an abstract method defined in a
     * superclass or implemented interface. 
     * 
-    * @param identifierExpression the parsed exception that contains the $implements
+    * @param identifierExpression the parsed expression that contains the $implements
     *                             or $implementing declaration. 
     */
    public ImplementedMethodFilter(IdentifierExpression identifierExpression)
@@ -231,14 +234,14 @@
    
    public boolean acceptConstructor(BehaviorWrapper<Constructor> constructorWrapper)
    {
-      return Util.matchesParameters(null, (ASTConstructor) astBehavior,
-            constructorWrapper.getBehavior());
+      return Util.matchesParameters(constructorWrapper.getMetaDataContainer(),
+            (ASTConstructor) astBehavior, constructorWrapper.getBehavior());
    }
    
    public boolean acceptMethod(BehaviorWrapper<Method> methodWrapper)
    {
-      return Util.matchesParameters(null, (ASTMethod) astBehavior,
-            methodWrapper.getBehavior());
+      return Util.matchesParameters(methodWrapper.getMetaDataContainer(),
+            (ASTMethod) astBehavior, methodWrapper.getBehavior());
    }
 }
 
@@ -323,7 +326,7 @@
    
    protected boolean checkParameters(Class[] parameters, Advisor metaDataContainer)
    {
-      for (int i = 0; i < classExpressions.length; i++)
+      for (int i = 0; i < classExpressions.length && i < parameters.length; i++)
       {
          if (classExpressions[i] != null &&
                !Util.matchesClassExpr(classExpressions[i], parameters[i],
@@ -332,6 +335,15 @@
             return false;
          }
       }
+      // we don't need this code because BehaviorSearcher will always search for
+      // methods that have only the minimum necessary number of params to match 
+      /*while (i < classExpressions.length)
+      {
+         if (classExpressions[i++] != null)
+         {
+            return false;
+         }
+      }*/
       return true;
    }
 }
@@ -353,8 +365,9 @@
    
    protected boolean checkParameters(Class[] parameters, Advisor metaDataContainer)
    {
-      int paramIndex = parameters.length - 1;
-      for (int i = classExpressions.length -1; i >= 0 ; i--,paramIndex--)
+      int i = classExpressions.length - 1;
+      for (int paramIndex = parameters.length - 1; paramIndex >= 0 && i >= 0;
+         i--,paramIndex--)
       {
          if (classExpressions[i] != null &&
                !Util.matchesClassExpr(classExpressions[i], parameters[paramIndex],
@@ -363,6 +376,15 @@
             return false;
          }
       }
+      // we don't need this code because BehaviorSearcher will always search for
+      // methods that have only the minimum necessary number of params to match 
+      /*while (i >=0)
+      {
+         if (classExpressions[i--] != null)
+         {
+            return false;
+         }
+      }*/
       return true;
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -47,6 +47,16 @@
  */
 class BehaviorNode implements Node, BehaviorWrapper
 {
+   /**
+    * Character used to separate return type, name, and parameters in a behavior node
+    * key.
+    */
+   public static final char SEPARATOR = '|';
+   /**
+    * Character used to separate return type and behavior name from the parameter
+    * list
+    */
+   public static final String PARAMS = "#";
    private static final CalleeMetaDataKeyLoader CALLEE_KEY_LOADER =
          new CalleeMetaDataKeyLoader();
    private Advisor advisor;
@@ -54,7 +64,7 @@
    private Member behavior;
    private JoinPointInfo execution;
    private ConstructionInfo construction;
-   private Tree<JoinPointInfo> calls = new Tree<JoinPointInfo>();
+   private Tree<JoinPointInfo> calls = new Tree<JoinPointInfo>(BehaviorNode.SEPARATOR);
    
    /**
     * Constructor. Creates a behavior node that represents {@code method} in the
@@ -134,13 +144,11 @@
    static final void loadMetaDataKeys(Member behavior, BehaviorType type,
          String prefix, Advisor advisor, Collection<String> keys)
    {
-      String commonPrefix = prefix + type.getReturnType(behavior) + "@";
-      String commonSuffix = getParameterList(behavior, type);
       Collection<String> metaDataTags =
             type.getMetaDataTags(advisor, behavior);
       for (String metaDataTag: metaDataTags)
       {
-         keys.add(commonPrefix + metaDataTag + commonSuffix);
+         keys.add(prefix + getMetaDataKey(behavior, metaDataTag, type));
       }
    }
    
@@ -269,7 +277,7 @@
          try
          {
             TreeInsertionUtil.insertObject(callInfo, calls,
-                  callInfo.getCalledClass().getName() + '.' + getIdentifierKey(
+                  callInfo.getCalledClass().getName() + SEPARATOR + getIdentifierKey(
                   callInfo.getConstructor()), CALLEE_KEY_LOADER);
          }
          finally
@@ -294,8 +302,8 @@
          try
          {
             TreeInsertionUtil.insertObject(callInfo, calls,
-                  callInfo.getCalledClass().getName() + '.' + getIdentifierKey(
-                  callInfo.getMethod()), CALLEE_KEY_LOADER);
+                  callInfo.getCalledClass().getName() + SEPARATOR +
+                  getIdentifierKey(callInfo.getMethod()), CALLEE_KEY_LOADER);
          }
          finally
          {
@@ -336,19 +344,25 @@
       return type.getName(member) + getParameterList(member, type);
    }
    
+   private static final String getMetaDataKey(Member member, String metaData, BehaviorType type)
+   {
+      return type.getMetaDataName(member, metaData) + getParameterList(member, type);
+   }
+   
    private static final String getParameterList(Member member, BehaviorType type)
    {
       Class[] parameterTypes = type.getParameterTypes(member);
       if (parameterTypes.length == 0)
       {
-         return "()";
+         return PARAMS;
       }
-      StringBuffer paramList = new StringBuffer("(");
+      StringBuffer paramList = new StringBuffer(PARAMS);
       for (int i = 0; i < parameterTypes.length; i++)
       {
-         paramList.append(parameterTypes[i].getName()).append(' ');
+         paramList.append(SEPARATOR).append(' ').append(parameterTypes[i].getName());
+         paramList.append(' ');
       }
-      paramList.append(')');
+      paramList.append(' ');
       return paramList.toString();
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -100,12 +100,15 @@
    private String behaviorExpression;
    private Collection<ASTAttribute> attributes;
    private Collection<ASTException> exceptions;
-   private BehaviorFilter behaviorFilter;
-   private boolean isMethod;
+   private Filter filter;
    private Searcher<BehaviorNode> internalSearcher;
 
+   
    /**
     * Creates an instance of this searcher.
+    * <p>
+    * Call this constructor if there are no extra checks to be performed on the
+    * searched behavior. 
     * 
     * @param behaviorExpression the expression that will be used to identify a
     *                            behavior in a {@code ClassNode}
@@ -113,10 +116,31 @@
     *                            behavior must follow 
     * @param exceptions          the type of the exceptions that the searched
     *                            behavior must declare to throw
+    */
+   public BehaviorSearcher(String behaviorExpression,
+         Collection<ASTAttribute> attributes, Collection<ASTException> exceptions)
+   {
+      
+      this.behaviorExpression = behaviorExpression;
+      this.attributes = attributes;
+      this.exceptions = exceptions;
+      this.filter = null;
+   }
+   
+   /**
+    * Creates an instance of this searcher.
+    * <p>
+    * Call this constructor if there no extra checks to be performed on the
+    * searched behavior.
+    * 
+    * @param behaviorExpression the expression that will be used to identify a
+    *                            behavior in a {@code ClassNode}
+    * @param attributes          the attribute restrictions that the searched
+    *                            behavior must follow 
+    * @param exceptions          the type of the exceptions that the searched
+    *                            behavior must declare to throw
     * @param behaviorFilter     a filter for extra checks on the searched behavior.
-    *                            This filter should be {@code null} if there are no
-    *                           extra checks to be performed on the searched
-    *                            behavior.
+    *                            This filter can't be {@code null}
     * @param isMethod            indicates whether {@code behaviorExpression} selects
     *                            only methods or constructor. If {@code
     *                            behaviorFilter} is {@code null}, the value of this
@@ -126,15 +150,31 @@
          Collection<ASTAttribute> attributes, Collection<ASTException> exceptions,
          BehaviorFilter behaviorFilter, boolean isMethod)
    {
-      
-      this.behaviorExpression = behaviorExpression;
-      this.attributes = attributes;
-      this.exceptions = exceptions;
-      this.behaviorFilter = behaviorFilter;
-      this.isMethod = isMethod;
+      this(behaviorExpression, attributes, exceptions);
+      this.filter = isMethod? new MethodFilter(behaviorFilter):
+         new ConstructorFilter(behaviorFilter);
    }
 
    /**
+    * Returns the type of search that this searcher should perform.
+    * 
+    * @return a search type that indicates the type of joinpoint that this class
+    *         searches for
+    */
+   public SearchType getSearchType()
+   {
+      if (this.internalSearcher instanceof SearchType)
+      {
+         return (SearchType) this.internalSearcher;
+      }
+      if (this.internalSearcher instanceof CallSearcher)
+      {
+         return SearchType.CALL;
+      }
+      return SearchType.ALL;
+   }
+   
+   /**
     * Sets the type of search that this searcher should perform.
     * <p>
     * This method must be called before this object performs a search.
@@ -165,31 +205,57 @@
    public void search(ClassNode node, Collection<JoinPointInfo> result)
    {
       Collection<BehaviorNode> behaviors = node.searchBehaviors(behaviorExpression);
-      if (isMethod)
+      for (BehaviorNode behaviorNode: behaviors)
       {
-         for (BehaviorNode behaviorNode: behaviors)
+         if (Util.matchModifiers(attributes, behaviorNode.getBehavior().getModifiers())
+               && Util.matchExceptions(exceptions, behaviorNode.getExceptionTypes())
+               && (filter == null || filter.accept(behaviorNode)))
          {
-            if (Util.matchModifiers(attributes, behaviorNode.getBehavior().getModifiers())
-               && Util.matchExceptions(exceptions, behaviorNode.getExceptionTypes())
-               && (behaviorFilter == null || behaviorFilter.acceptMethod(
-                     (BehaviorWrapper<Method>)behaviorNode)))
-            {
-               this.internalSearcher.search(behaviorNode, result);
-            }
+            this.internalSearcher.search(behaviorNode, result);
          }
       }
-      else
+   }
+   
+   private static abstract class Filter
+   {
+      protected BehaviorFilter internalFilter;
+      
+      public Filter(BehaviorFilter internalFilter)
       {
-         for (BehaviorNode behaviorNode: behaviors)
-         {
-            if (Util.matchModifiers(attributes, behaviorNode.getBehavior().getModifiers())
-               && Util.matchExceptions(exceptions, behaviorNode.getExceptionTypes())
-               && (behaviorFilter == null || behaviorFilter.acceptConstructor(
-                     (BehaviorWrapper<Constructor>) behaviorNode)))
-            {
-               this.internalSearcher.search(behaviorNode, result);
-            }
-         }
+         this.internalFilter = internalFilter;
       }
+      
+      public abstract boolean accept(BehaviorWrapper<?> wrapper);
    }
+   
+   private static class ConstructorFilter extends Filter
+   {
+      public ConstructorFilter(BehaviorFilter internalFilter)
+      {
+         super(internalFilter);
+      }
+      
+      @Override
+      @SuppressWarnings("all")
+      public boolean accept(BehaviorWrapper<?> wrapper)
+      {
+         return this.internalFilter.acceptConstructor(
+               (BehaviorWrapper<Constructor>) wrapper);
+      }
+   }
+   
+   private static class MethodFilter extends Filter
+   {
+      public MethodFilter(BehaviorFilter internalFilter)
+      {
+         super(internalFilter);
+      }
+      
+      @Override
+      @SuppressWarnings("all")
+      public boolean accept(BehaviorWrapper<?> wrapper)
+      {
+         return this.internalFilter.acceptMethod((BehaviorWrapper<Method>) wrapper);
+      }
+   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorType.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorType.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorType.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -38,7 +38,7 @@
 {
    CONSTRUCTOR
    {
-      public String getDefaultKey(Member member)
+      public String getIdentifierKey(Member member)
       {
          return BehaviorNode.getIdentifierKey((Constructor) member);
       }
@@ -48,14 +48,14 @@
          return "new";
       }
       
-      public Class[] getParameterTypes(Member member)
+      public String getMetaDataName(Member member, String metaData)
       {
-         return ((Constructor) member).getParameterTypes();
+         return '@' + metaData;
       }
       
-      public String getReturnType(Member member)
+      public Class[] getParameterTypes(Member member)
       {
-         return "";
+         return ((Constructor) member).getParameterTypes();
       }
       
       public Class[] getExceptionTypes(Member member)
@@ -70,24 +70,26 @@
    },
    METHOD
    {
-      public String getDefaultKey(Member member)
+      public String getIdentifierKey(Member member)
       {
          return BehaviorNode.getIdentifierKey((Method) member);
       }
       
       public String getName(Member member)
       {
-         return ((Method) member).getReturnType().getName() + " " + member.getName();
+         return ((Method) member).getReturnType().getName() + BehaviorNode.SEPARATOR +
+            " " + member.getName();
       }
       
-      public Class[] getParameterTypes(Member member)
+      public String getMetaDataName(Member member, String metaData)
       {
-         return ((Method) member).getParameterTypes();
+         return ((Method) member).getReturnType().getName() + BehaviorNode.SEPARATOR +
+         " @" + metaData;
       }
       
-      public String getReturnType(Member member)
+      public Class[] getParameterTypes(Member member)
       {
-         return ((Method) member).getReturnType().getName() + " ";
+         return ((Method) member).getParameterTypes();
       }
       
       public Class[] getExceptionTypes(Member member)
@@ -110,19 +112,31 @@
     * @see BehaviorNode#getIdentifierKey(Constructor)
     * @see BehaviorNode#getIdentifierKey(Method)
     */
-   public abstract String getDefaultKey(Member behavior);
+   public abstract String getIdentifierKey(Member behavior);
    
    /**
     * Returns the name of {@code behavior}.
     * 
     * @param behavior a behavior ({@code Constructor} or {@code Method})
     * @return if {@code behavior} is a constructor, returns {@code "new"}, if it is
-    *         a method, returns the name of the method
+    *         a method, returns the return type of the method followed by the name
+    *         of the method, using {@link BehaviorNode#SEPARATOR} as a splitter.
     * @see Method#getName()
     */
    public abstract String getName(Member behavior);
    
    /**
+    * Returns the metadata name of {@code behavior}.
+    * 
+    * @param behavior a behavior ({@code Constructor} or {@code Method})
+    * @param metaData a metadata tag associated with {@code behavior}
+    * 
+    * @return the metadata name of {@code behavior}
+    * @see Method#getName()
+    */
+   public abstract String getMetaDataName(Member behavior, String metaData);
+   
+   /**
     * Returns the parameter list of {@code behavior}.
     * 
     * @param behavior a behavior ({@code Constructor} or {@code Method})
@@ -133,15 +147,6 @@
    public abstract Class[] getParameterTypes(Member behavior);
    
    /**
-    * Returns a {@code String} representing the return type of {@code behavior}.
-    * 
-    * @param behavior a behavior ({@code Constructor} or {@code Method})
-    * @return an empty {@code String} if behavior is a {@code Constructor}, the name
-    *         of the return type of behavior otherwise
-    */
-   public abstract String getReturnType(Member behavior);
-   
-   /**
     * Returns the list of exceptions that {@code behavior} declares to throw.
     * 
     * @param behavior a behavior ({@code Constructor} or {@code Method})

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CallSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CallSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CallSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -32,30 +32,27 @@
  */
 class CallSearcher implements Searcher<BehaviorNode>
 {
-   private Collection<CalleeSearcher> calleeRestrictionList;
+   private CalleeSearcher calleeRestriction;
    
    /**
     * Sets the l
     * @param calleeRestrictionList
     */
-   public void setCalleeRestrictionList(Collection<CalleeSearcher> calleeRestrictionList)
+   public void setCalleeRestriction(CalleeSearcher calleeRestriction)
    {
-      this.calleeRestrictionList = calleeRestrictionList;
+      this.calleeRestriction = calleeRestriction;
    }
    
    
    public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
    {
-      if (calleeRestrictionList.isEmpty())
+      if (calleeRestriction == null)
       {
          node.searchCallees("*", searchResult);
       }
       else
       {
-         for (CalleeSearcher calleeRestriction: calleeRestrictionList)
-         {
-            calleeRestriction.search(node, searchResult);
-         }
+         calleeRestriction.search(node, searchResult);
       }
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -107,12 +107,13 @@
          try
          {
             AdvisableClassNode.loadMetaDataKeys(advisor, tempKeys);
-            BehaviorNode.loadMetaDataKeys(member, type, className + '.', advisor, keys);
+            BehaviorNode.loadMetaDataKeys(member, type, className +
+                  BehaviorNode.SEPARATOR, advisor, keys);
             for (String metaDataKey: tempKeys)
             {
-               keys.add(metaDataKey + '.' + type.getDefaultKey(member));
-               BehaviorNode.loadMetaDataKeys(member, type, metaDataKey + '.', advisor,
-                     keys);
+               String prefix = metaDataKey + BehaviorNode.SEPARATOR;
+               keys.add(prefix + type.getIdentifierKey(member));
+               BehaviorNode.loadMetaDataKeys(member, type, prefix, advisor, keys);
             }
          }
          finally

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -39,12 +39,22 @@
 import org.jboss.aop.pointcut.ast.ASTException;
 
 /**
- * Searcher for call joinpoints whose context matches a within expression. 
+ * Searcher for call joinpoints whose callee matches XXX todo a within expression. 
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-abstract class CalleeSearcher implements Searcher<BehaviorNode>
+interface CalleeSearcher extends Searcher<BehaviorNode>
 {
+   
+}
+
+/**
+ * Searcher for call joinpoints whose callee matches a within expression. 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+abstract class SimpleCalleeSearcher implements CalleeSearcher
+{
    String calleeExpression;
    
    /**
@@ -53,19 +63,107 @@
     * 
     * @param calleeExpression search expression to be used on a search for callees.
     */
-   public CalleeSearcher(String calleeExpression)
+   public SimpleCalleeSearcher(String calleeExpression)
    {
       this.calleeExpression = calleeExpression;
    }
 }
 
+abstract class CompositeCalleeSearcher implements CalleeSearcher
+{
+   protected CalleeSearcher restriction1;
+   protected CalleeSearcher restriction2;
+   
+   public CompositeCalleeSearcher(CalleeSearcher calleeRestriction1,
+         CalleeSearcher calleeRestriction2)
+   {
+      this.restriction1 = calleeRestriction1;
+      this.restriction2 = calleeRestriction2;
+   }
+
+}
+
 /**
+ * Searcher that selects all the call joinpoints whose context match two
+ * callee expressions. 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ConjunctiveCalleeSearcher extends CompositeCalleeSearcher
+{
+   public ConjunctiveCalleeSearcher(CalleeSearcher calleeRestriction1,
+         CalleeSearcher calleeRestriction2)
+   {
+      super(calleeRestriction1, calleeRestriction2);
+   }
+
+   public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
+   {
+      Set<JoinPointInfo> temp1 = new HashSet<JoinPointInfo>();
+      Set<JoinPointInfo> temp2 = new HashSet<JoinPointInfo>();
+      restriction1.search(node, temp1);
+      restriction2.search(node, temp2);
+      temp1.retainAll(temp2);
+      searchResult.addAll(temp1);
+   }
+}
+
+/**
+ * Searcher that selects all the call joinpoints whose context match one of two
+ * callee expressions. 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class DisjunctiveCalleeSearcher extends CompositeCalleeSearcher
+{
+   public DisjunctiveCalleeSearcher(CalleeSearcher calleeRestriction1,
+         CalleeSearcher calleeRestriction2)
+   {
+      super(calleeRestriction1, calleeRestriction2);
+   }
+
+   public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
+   {
+      Set<JoinPointInfo> temp = new HashSet<JoinPointInfo>();
+      restriction1.search(node, temp);
+      restriction2.search(node, temp);
+      searchResult.addAll(temp);
+   }
+}
+
+/**
+ * Searcher that selects all the call joinpoints whose callee does not match a
+ * callee expression. 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class NegativeCalleeSearcher implements CalleeSearcher
+{
+   private CalleeSearcher calleeRestriction;
+   
+   public NegativeCalleeSearcher(CalleeSearcher calleeRestriction)
+   {
+      this.calleeRestriction = calleeRestriction;
+   }
+
+   public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
+   {
+      Set<JoinPointInfo> temp = new HashSet<JoinPointInfo>();
+      node.searchCallees("*", temp);
+      Collection<JoinPointInfo> toRemove = new ArrayList<JoinPointInfo>();
+      calleeRestriction.search(node, toRemove);
+      temp.removeAll(toRemove);
+      searchResult.addAll(temp);
+   }
+}
+
+/**
  * Searcher that does not apply any extra check to the callee of the searched call
  * joinpoints.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-class OptimizedCalleeSearcher extends CalleeSearcher
+class OptimizedCalleeSearcher extends SimpleCalleeSearcher
 {
    public OptimizedCalleeSearcher(String calleeExpression)
    {
@@ -83,7 +181,7 @@
  *  
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-abstract class NonOptimizedCalleeSearcher extends CalleeSearcher
+abstract class NonOptimizedCalleeSearcher extends SimpleCalleeSearcher
 {
    private static final Collection<JoinPointInfo> temp =
       new HashSet<JoinPointInfo>(2);
@@ -264,59 +362,4 @@
          Util.matchExceptions(exceptions, method.getExceptionTypes()) &&
          super.accept(method);
    }
-}
-
-/**
- * Searcher that selects all the call joinpoints whose callee does not match a
- * callee expression. 
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-class NegativeCalleeSearcher extends CalleeSearcher
-{
-   private CalleeSearcher calleeRestriction;
-   
-   public NegativeCalleeSearcher(CalleeSearcher calleeRestriction)
-   {
-      super(null);
-      this.calleeRestriction = calleeRestriction;
-   }
-
-   public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
-   {
-      Set<JoinPointInfo> temp = new HashSet<JoinPointInfo>();
-      node.searchCallees("*", temp);
-      Collection<JoinPointInfo> toRemove = new ArrayList<JoinPointInfo>();
-      calleeRestriction.search(node, toRemove);
-      temp.removeAll(toRemove);
-      searchResult.addAll(temp);
-   }
-}
-
-/**
- * Searcher that selectes all the call joinpoints whose context match one of two
- * callee expressions. 
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-class DisjunctiveCalleeSearcher extends CalleeSearcher
-{
-   private CalleeSearcher calleeSearcher1;
-   private CalleeSearcher calleeSearcher2;
-   
-   public DisjunctiveCalleeSearcher(CalleeSearcher calleeRestriction1,
-         CalleeSearcher calleeRestriction2)
-   {
-      super(null);
-      this.calleeSearcher1 = calleeRestriction1;
-      this.calleeSearcher2 = calleeRestriction2;
-   }
-
-   public void search(BehaviorNode node, Collection<JoinPointInfo> searchResult)
-   {
-      Set<JoinPointInfo> temp = new HashSet<JoinPointInfo>();
-      calleeSearcher1.search(node, temp);
-      calleeSearcher2.search(node, temp);
-      searchResult.addAll(temp);
-   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcherFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcherFactory.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeSearcherFactory.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -32,22 +32,9 @@
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
 class CalleeSearcherFactory
-{
+{   
    /**
     * Creates a {@code CalleeSearcher} that searches for all call joinpoints that
-    * match {@code calleeExpression}.
-    * 
-    * @param calleeExpression the callee expression
-    * @return                 a {@code CalleeSearcher} that searches for all call
-    *                         joinpoints that match {@code calleeExpression}
-    */
-   public static CalleeSearcher create(String calleeExpression)
-   {
-      return new OptimizedCalleeSearcher(calleeExpression);
-   }
-   
-   /**
-    * Creates a {@code CalleeSearcher} that searches for all call joinpoints that
     * match {@code calleeExpression}, and whose callee satisfy the attribute and
     * exception restrictions.
     * 

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -14,18 +14,6 @@
  * </li>
  * </ul>
  * 
- * Every class node contains:
- * <ul>
- * <li> references to all the nodes that represent direct subtypes of it in the
- *      graph;</li>
- * <li> a subtree of behaviors, containing all behavior nodes associated with this
- *      class node;<li>
- * <li> and a subtree of fields, containing all field nodes associated with this
- *      class node.</li>
- * </ul>
- * 
- * The subtrees are held indirectly, by a reference to {@link AdvisedData}.
- * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
 abstract class ClassNode implements Node
@@ -43,7 +31,6 @@
       this.clazz = clazz;
    }
    
-
    /**
     * Returns the key that would identify a class node in the graph.
     * <p>
@@ -150,4 +137,13 @@
    {
       return AspectManager.instance().getTempClassAdvisorIfNotExist(clazz);
    }
+   
+   public String toString()
+   {
+      if (this.clazz == null)
+      {
+         return "[node: null]";
+      }
+      return "[node: " + clazz.getName() + "]";
+   }
 }
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeSearchKey.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,161 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+
+/**
+ * A search key composed by two internal search keys. This search key uses its
+ * internal search keys to perform search.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+abstract class CompositeSearchKey extends NegativeCompositeSearchKey
+{
+   protected ParsedSearchKey searchKey1;
+   protected ParsedSearchKey searchKey2;
+   
+   /**
+    * Constructor.
+    * 
+    * @param searchKey1 one of the internal search keys
+    * @param searchKey2 one of the internal search keys
+    */
+   public CompositeSearchKey(ParsedSearchKey searchKey1, ParsedSearchKey searchKey2)
+   {
+      this.searchKey1 = searchKey1;
+      this.searchKey2 = searchKey2;
+   }
+
+   @Override
+   public final void setClassExpression(String className, boolean instanceOf)
+   {
+      searchKey2.setClassExpression(className, instanceOf);
+   }
+   
+   @Override
+   public final void setSearcher(Searcher<ClassNode> classNodeSearcher)
+   {
+      searchKey2.setSearcher(classNodeSearcher);
+   }
+
+   @Override
+   public final boolean hasSearcher()
+   {
+      return searchKey2.hasSearcher();
+   }
+
+   @Override
+   public final ParsedSearchKey addConjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      searchKey1 = searchKey1.addConjunctiveTypeFilter(typeFilter);
+      searchKey2 = searchKey2.addConjunctiveTypeFilter(typeFilter);
+      return this;
+   }
+   
+   @Override
+   public final ParsedSearchKey addDisjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      ParsedSearchKey newSearchKey1 = searchKey1.addDisjunctiveTypeFilter(typeFilter);
+      ParsedSearchKey newSearchKey2 = searchKey2.addDisjunctiveTypeFilter(typeFilter);
+      if (newSearchKey1 != searchKey1 && newSearchKey2 != searchKey2)
+      {
+         ParsedSearchKey searchKey = new StandardSearchKey();
+         searchKey.addConjunctiveTypeFilter(typeFilter);
+         return new DisjunctiveSearchKey(this, searchKey);
+      }
+      else
+      {
+         this.searchKey1 = newSearchKey1;
+         this.searchKey2 = newSearchKey2;
+         return this;
+      }
+   }
+
+   @Override
+   public final ParsedSearchKey addConjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      searchKey1 = searchKey1.addConjunctiveCalleeRestriction(calleeRestriction);
+      searchKey2 = searchKey2.addConjunctiveCalleeRestriction(calleeRestriction);
+      return this;
+   }
+   
+   @Override
+   public final ParsedSearchKey addDisjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      ParsedSearchKey newSearchKey1 = searchKey1.addDisjunctiveCalleeRestriction(calleeRestriction);
+      ParsedSearchKey newSearchKey2 = searchKey2.addDisjunctiveCalleeRestriction(calleeRestriction);
+      if (newSearchKey1 != searchKey1 && newSearchKey2 != searchKey2)
+      {
+         ParsedSearchKey searchKey = new StandardSearchKey();
+         searchKey.addConjunctiveCalleeRestriction(calleeRestriction);
+         return new DisjunctiveSearchKey(this, searchKey);
+      }
+      else
+      {
+         this.searchKey1 = newSearchKey1;
+         this.searchKey2 = newSearchKey2;
+         return this;
+      }
+   }
+   
+   @Override
+   public final ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      if (searchKey instanceof StandardSearchKey && !searchKey.hasSearcher())
+      {
+         StandardSearchKey key = (StandardSearchKey) searchKey;
+         ParsedSearchKey result = this;
+         if (key.calleeRestriction != null)
+         {
+            result = this.addConjunctiveCalleeRestriction(
+               key.calleeRestriction);
+         }
+         if (key.typeFilter != null)
+         {
+            result = result.addConjunctiveTypeFilter(key.typeFilter);
+         }
+         if (key.negativeSearchKeys != null)
+         {
+            for (ParsedSearchKey negativeKey: key.negativeSearchKeys)
+            {
+               this.addNegativeSearchKey(negativeKey);
+            }
+         }
+         return result;
+      }
+      return new ConjunctiveSearchKey(this, searchKey);
+   }
+   
+   @Override
+   public final ParsedSearchKey addDisjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      return new DisjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   public ParsedSearchKey finishParsing()
+   {
+      this.searchKey1 = searchKey1.finishParsing();
+      this.searchKey2 = searchKey2.finishParsing();
+      return this;
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -29,81 +29,78 @@
 import org.jboss.aop.joinpoint.graph.tree.Tree;
 
 /**
+ * A composite search key that returns as a search result only the joinpoints that
+ * can be found by both internal search keys.
+ * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- *
  */
-public class ConjunctiveSearchKey extends ParsedSearchKey
+class ConjunctiveSearchKey extends CompositeSearchKey
 {
-   private SearchKey searchKey1;
-   private SearchKey searchKey2;
-   
-   public ConjunctiveSearchKey(SearchKey searchKey1, ParsedSearchKey searchKey2)
+   /**
+    * Constructor.
+    * 
+    * @param searchKey1 one of the internal search keys
+    * @param searchKey2 one of the internal search keys
+    */
+   public ConjunctiveSearchKey(ParsedSearchKey searchKey1, ParsedSearchKey searchKey2)
    {
-      this.searchKey1 = searchKey1;
-      this.searchKey2 = searchKey2;
+      super(searchKey1, searchKey2);
    }
-
-   public void addTypeFilter(TypeFilter typeRestriction)
+   
+   @Override
+   public SearchType getSearchType()
    {
-      ((ParsedSearchKey) searchKey2).addTypeFilter(typeRestriction);
+      SearchType type1 = searchKey1.getSearchType();
+      SearchType type2 = searchKey2.getSearchType();
+      if (type1 == SearchType.ALL)
+      {
+         return type2;
+      }
+      if (type2 == SearchType.ALL)
+      {
+         return type1;
+      }
+      if (type1 == SearchType.FIELD || type1 == SearchType.BEHAVIOR)
+      {
+         return type2;
+      }
+      return type1;
    }
-
-   public void addCalleeSearcher(CalleeSearcher calleeRestriction)
-   {
-      ((ParsedSearchKey) searchKey2).addCalleeSearcher(calleeRestriction);
-   }
-
-   public boolean hasSearcher()
-   {
-      return ((ParsedSearchKey) searchKey2).hasSearcher();
-   }
-
-   public void setClassExpression(String className, boolean instanceOf)
-   {
-      ((ParsedSearchKey) searchKey2).setClassExpression(className, instanceOf);
-   }
-
-   public void setSearcher(Searcher<ClassNode> classNodeSearcher)
-   {
-      ((ParsedSearchKey) searchKey2).setSearcher(classNodeSearcher);
-   }
-
-   public void addNegativeSearchKey(SearchKey searchKey)
-   {
-      ((ParsedSearchKey) searchKey2).addNegativeSearchKey(searchKey);
-   }
-
+   
+   @Override
    public ParsedSearchKey finishParsing()
    {
-      this.searchKey2 = ((ParsedSearchKey) searchKey2).finishParsing();
+      super.finishParsing();
+      if (searchKey1 instanceof EmptySearchKey)
+      {
+         return searchKey1;
+      }
+      if (searchKey2 instanceof EmptySearchKey)
+      {
+         return searchKey2;
+      }
+      SearchType type1 = searchKey1.getSearchType();
+      SearchType type2 = searchKey2.getSearchType();
+      if (type1 != type2 && type1 != SearchType.UNDEFINED &&
+            type2 != SearchType.UNDEFINED &&
+            !(type1 == SearchType.FIELD &&
+                  (type2 == SearchType.FIELD_GET || type2 == SearchType.FIELD_SET))
+         && !(type2 == SearchType.FIELD &&
+               (type1 == SearchType.FIELD_GET || type1 == SearchType.FIELD_SET))
+         && !(type1 == SearchType.BEHAVIOR && (type2 == SearchType.CONSTRUCTION ||
+               type2 == SearchType.CALL || type2 == SearchType.EXECUTION))
+         && !(type2 == SearchType.BEHAVIOR && (type1 == SearchType.CONSTRUCTION ||
+               type1 == SearchType.CALL || type1 == SearchType.EXECUTION))
+         && !(type1 == SearchType.ALL && (type2 != SearchType.CONSTRUCTION &&
+               type2 != SearchType.CALL))
+         && !(type2 == SearchType.ALL && (type1 != SearchType.CONSTRUCTION &&
+               type1 != SearchType.CALL)))
+      {
+         return EmptySearchKey.getInstance();
+      }
       return this;
    }
-
-   public Object getLastAddedElement()
-   {
-      return ((ParsedSearchKey) searchKey2).getLastAddedElement();
-   }
-
-   public void merge(SimpleSearchKey simpleSearchKey)
-   {
-      ((ParsedSearchKey) searchKey2).merge(simpleSearchKey);
-   }
-
-   public void replaceNegativeSearchKey(ParsedSearchKey searchKey)
-   {
-      ((ParsedSearchKey) searchKey2).replaceNegativeSearchKey(searchKey);
-   }
-
-   public void replaceTypeFilter(TypeFilter restriction)
-   {
-      ((ParsedSearchKey) searchKey2).replaceTypeFilter(restriction);
-   }
-
-   public void replaceCalleeSearcher(CalleeSearcher restriction)
-   {
-      ((ParsedSearchKey) searchKey2).replaceCalleeSearcher(restriction);
-   }
-
+   
    public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
    {
       Set<JoinPointInfo> firstResult = new HashSet<JoinPointInfo>();

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -22,89 +22,106 @@
 package org.jboss.aop.joinpoint.graph;
 
 import java.util.Collection;
+import java.util.HashSet;
 
 import org.jboss.aop.JoinPointInfo;
 import org.jboss.aop.joinpoint.graph.tree.Tree;
 
 /**
+ * A composite search key that returns as a search result all the joinpoints that
+ * can be found by either internal search key.
+ * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- *
  */
-public class DisjunctiveSearchKey extends ParsedSearchKey
+class DisjunctiveSearchKey extends CompositeSearchKey
 {
-   private SearchKey searchKey1;
-   private SearchKey searchKey2;
-   
-   public DisjunctiveSearchKey(SearchKey searchKey1, SearchKey searchKey2)
+   /**
+    * Constructor.
+    * 
+    * @param searchKey1 one of the internal search keys
+    * @param searchKey2 one of the internal search keys
+    */
+   public DisjunctiveSearchKey(ParsedSearchKey searchKey1, ParsedSearchKey searchKey2)
    {
-      this.searchKey1 = searchKey1;
-      this.searchKey2 = searchKey2;
+      super(searchKey1, searchKey2);
    }
 
-   public void addTypeFilter(TypeFilter typeRestriction)
+   @Override
+   public SearchType getSearchType()
    {
-      ((ParsedSearchKey) searchKey2).addTypeFilter(typeRestriction);
+      SearchType type1 = searchKey1.getSearchType();
+      SearchType type2 = searchKey2.getSearchType();
+      if (type1 == type2)
+      {
+         return type1;
+      }
+      if (type1 == SearchType.ALL)
+      {
+         return (type2 != SearchType.CONSTRUCTION && type2 != SearchType.CALL)?
+               type1: SearchType.UNDEFINED;
+      }
+      if (type2 == SearchType.ALL)
+      {
+         return (type1 != SearchType.CONSTRUCTION && type1 != SearchType.CALL)?
+               type2: SearchType.UNDEFINED;
+      }
+      if (type1 == SearchType.FIELD)
+      {
+         return  (type2 == SearchType.FIELD_GET || type2 == SearchType.FIELD_SET)?
+               type1: SearchType.UNDEFINED;
+      }
+      if (type2 == SearchType.FIELD)
+      {
+         return (type1 == SearchType.FIELD_GET || type1 == SearchType.FIELD_SET)?
+               type2: SearchType.UNDEFINED;
+      }
+      if (type1 == SearchType.BEHAVIOR)
+      {
+         return  (type2 == SearchType.EXECUTION || type2 == SearchType.CALL ||
+               type2 == SearchType.CONSTRUCTION)? type1: SearchType.UNDEFINED;
+      }
+      if (type2 == SearchType.BEHAVIOR)
+      {
+         return  (type1 == SearchType.EXECUTION || type1 == SearchType.CALL ||
+               type1 == SearchType.CONSTRUCTION)? type2: SearchType.UNDEFINED;
+      }
+      return SearchType.UNDEFINED;
    }
-
-   public void addCalleeSearcher(CalleeSearcher calleeRestriction)
+   
+   @Override
+   public ParsedSearchKey finishParsing()
    {
-      ((ParsedSearchKey) searchKey2).addCalleeSearcher(calleeRestriction);
-   }
-
-   public boolean hasSearcher()
-   {
-      return ((ParsedSearchKey) searchKey2).hasSearcher();
-   }
-
-   public void setClassExpression(String className, boolean instanceOf)
-   {
-      ((ParsedSearchKey) searchKey2).setClassExpression(className, instanceOf);
-   }
-
-   public void setSearcher(Searcher<ClassNode> classNodeSearcher)
-   {
-      ((ParsedSearchKey) searchKey2).setSearcher(classNodeSearcher);
-   }
-
-   public void addNegativeSearchKey(SearchKey searchKey)
-   {
-      ((ParsedSearchKey) searchKey2).addNegativeSearchKey(searchKey);
-   }
-
-   public SearchKey finishParsing()
-   {
-      this.searchKey2 = ((ParsedSearchKey) searchKey2).finishParsing();
+      super.finishParsing();
+      if (searchKey1 instanceof EmptySearchKey)
+      {
+         return searchKey2;
+      }
+      if (searchKey2 instanceof EmptySearchKey)
+      {
+         return searchKey1;
+      }
       return this;
    }
-
-   public Object getLastAddedElement()
+   
+   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
    {
-      return ((ParsedSearchKey) searchKey2).getLastAddedElement();
+      this.delegateSearch(searchKey1, classTree, result);
+      this.delegateSearch(searchKey2, classTree, result);
+      this.applyNegativeResult(classTree, result);
    }
-
-   public void merge(SimpleSearchKey simpleSearchKey)
+   
+   private void delegateSearch(SearchKey searchKey,
+         Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
    {
-      ((ParsedSearchKey) searchKey2).merge(simpleSearchKey);
+      if (((ParsedSearchKey) searchKey).requiresExclusiveResult())
+      {
+         Collection<JoinPointInfo> tempResult = new HashSet<JoinPointInfo>();
+         searchKey.search(classTree, tempResult);
+         result.addAll(tempResult);
+      }
+      else
+      {
+         searchKey.search(classTree, result);
+      }
    }
-
-   public void replaceNegativeSearchKey(ParsedSearchKey searchKey)
-   {
-      ((ParsedSearchKey) searchKey2).replaceNegativeSearchKey(searchKey);
-   }
-
-   public void replaceTypeFilter(TypeFilter restriction)
-   {
-      ((ParsedSearchKey) searchKey2).replaceTypeFilter(restriction);
-   }
-
-   public void replaceCalleeSearcher(CalleeSearcher restriction)
-   {
-      ((ParsedSearchKey) searchKey2).replaceCalleeSearcher(restriction);
-   }
-
-   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
-   {
-      this.searchKey1.search(classTree, result);
-      this.searchKey2.search(classTree, result);
-   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/EmptySearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/EmptySearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/EmptySearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -34,10 +34,102 @@
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-class EmptySearchKey extends SearchKey
+class EmptySearchKey extends ParsedSearchKey
 {
-   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
+   private static final EmptySearchKey INSTANCE = new EmptySearchKey();
+   
+   private EmptySearchKey(){}
+   
+   /**
+    * Returns the singleton instance of this class.
+    * 
+    * @return the singleton empty search key instance
+    */
+   public static final EmptySearchKey getInstance()
    {
-      // do nothing  
+      return INSTANCE;
    }
+   
+   @Override
+   void setClassExpression(String classExpression, boolean instanceOf)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   void setSearcher(Searcher<ClassNode> classNodeSearcher)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   boolean hasSearcher()
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+   
+   @Override
+   SearchType getSearchType()
+   {
+      return SearchType.UNDEFINED;
+   }
+
+   @Override
+   ParsedSearchKey addConjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+   
+   @Override
+   ParsedSearchKey addConjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      throw new IllegalStateException("This search key must be created only after parsing.");
+   }
+
+   @Override
+   ParsedSearchKey addNegativeSearchKey(ParsedSearchKey searchKey)
+   {
+      return this;
+   }
+
+   @Override
+   ParsedSearchKey finishParsing()
+   {
+      return this;
+   }
+
+   @Override
+   boolean requiresExclusiveResult()
+   {
+      return false;
+   }
+
+   public void search(Tree<? extends ClassNode> target, Collection<JoinPointInfo> searchResult)
+   {
+      
+   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -88,7 +88,7 @@
       }
    }
    
-   private Searcher<FieldNode> internalSearcher;
+   private SearchType internalSearcher;
    private String fieldExpression;
    private Collection<ASTAttribute> attributes;
    private FieldFilter fieldFilter;
@@ -113,6 +113,16 @@
    }
    
    /**
+    * Returns the type of search that this searcher should perform.
+    * 
+    * @return the type that indicates the type of joinpoint that this class searches for
+    */
+   public SearchType getSearchType()
+   {
+      return this.internalSearcher;
+   }
+   
+   /**
     * Sets the type of search that this searcher should perform.
     * <p>
     * This method must be called before this object performs a search.

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -61,7 +61,7 @@
    public synchronized void register(FieldInfo info)
    {
       Advisor advisor = info.getAdvisor();
-      AdvisedData advisedData = getClassNode(info.getClazz()).getAdvisedData(advisor);
+      AdvisedData advisedData = getAdvisedData(info.getClazz(), advisor);
       FieldNode fieldNode = advisedData.getField(info.getField());
       if (info.isRead())
       {
@@ -139,25 +139,27 @@
    private BehaviorNode getBehavior(Advisor advisor, Class clazz,
          Constructor constructor)
    {
-      AdvisedData advisedData = getClassNode(clazz).getAdvisedData(advisor);
+      AdvisedData advisedData = getAdvisedData(clazz, advisor);
       return advisedData.getBehavior(constructor);
    }
    
    private BehaviorNode getBehavior(Advisor advisor, Class clazz, Method method)
    {
-      AdvisedData advisedData = getClassNode(clazz).getAdvisedData(advisor);
+      AdvisedData advisedData = getAdvisedData(clazz, advisor);
       return advisedData.getBehavior(method);
    }
    
-   private StandardClassNode getClassNode(Class<?> clazz)
+   private AdvisedData getAdvisedData(Class<?> clazz, Advisor advisor)
    {
       String defaultKey = ClassNode.getIdentifierKey(clazz);
       StandardClassNode classNode = classTree.searchValue(defaultKey);
       if (classNode == null)
       {
          classNode = new StandardClassNode(clazz);
+         AdvisedData advisedData = classNode.getAdvisedData(advisor);
          insertClassNode(classNode, defaultKey);
+         return advisedData;
       }
-      return classNode;
+      return classNode.getAdvisedData(advisor);
    }
 }
\ No newline at end of file

Copied: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/NegativeCompositeSearchKey.java (from rev 75821, projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SimpleSearchKey.java)
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/NegativeCompositeSearchKey.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/NegativeCompositeSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+
+/**
+ * A search key that contains negative search key components.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+abstract class NegativeCompositeSearchKey extends ParsedSearchKey
+{
+   protected ArrayList<ParsedSearchKey> negativeSearchKeys;
+   
+   
+   @Override
+   public final ParsedSearchKey addNegativeSearchKey(ParsedSearchKey searchKey)
+   {
+      if (searchKey instanceof StandardSearchKey && !searchKey.hasSearcher())
+      {
+         StandardSearchKey key = (StandardSearchKey) searchKey;
+         if (key.typeFilter != null && key.calleeRestriction == null)
+         {
+            return this.addConjunctiveTypeFilter(new NegativeTypeFilter(key.typeFilter));
+         }
+         if (key.calleeRestriction != null && key.typeFilter == null)
+         {
+            return this.addConjunctiveCalleeRestriction(new NegativeCalleeSearcher(key.calleeRestriction));
+         }
+      }
+      searchKey = searchKey.finishParsing();
+      if (searchKey instanceof EmptySearchKey)
+      {
+         return this;
+      }
+      if (this.negativeSearchKeys == null)
+      {
+         this.negativeSearchKeys = new ArrayList<ParsedSearchKey>(1);
+      }
+      this.negativeSearchKeys.add(searchKey);
+      return this;
+   }
+
+   @Override
+   public final boolean requiresExclusiveResult()
+   {
+      return this.negativeSearchKeys != null && !this.negativeSearchKeys.isEmpty();
+   }
+   
+   protected final void applyNegativeResult(Tree<? extends ClassNode> classTree,
+         Collection<JoinPointInfo> result)
+   {
+      if (this.negativeSearchKeys != null && !this.negativeSearchKeys.isEmpty())
+      { 
+         Collection<JoinPointInfo> negativeResult = new HashSet<JoinPointInfo>();
+         for (SearchKey searchKey: negativeSearchKeys)
+         {
+            negativeResult.clear();
+            searchKey.search(classTree, negativeResult);
+            result.removeAll(negativeResult);
+         }
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParameterParser.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParameterParser.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParameterParser.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,444 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.jboss.aop.pointcut.ast.ASTBehavior;
+import org.jboss.aop.pointcut.ast.ASTParameter;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+
+/**
+ * Parses the parameter list of an {@code ASTBehavior} for searching.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ParameterParser
+{
+   private static final ClassExpression WILDCARD = new ClassExpression("");
+   private State currentState = State.START;
+   
+   /**
+    * Parses the parameter list of {@code behavior}.
+    * 
+    * @param behavior contains the parameter list to be parsed
+    * @param buffer   where the result of the parsing will be appended
+    * @return a behavior filter if there is extra need for filtering the parameters
+    *         of behaviors whose list match the parsed expression
+    */
+   public BehaviorFilter parse(ASTBehavior behavior, StringBuffer buffer)
+   {
+      buffer.append(BehaviorNode.PARAMS);
+      if (behavior.isAnyParameters())
+      {
+         ParameterType.WILDCARD.parse(null, buffer);
+         return null;
+      }
+      Collection<ASTParameter> parameters = behavior.getParameters();
+      if (parameters.isEmpty())
+      {
+         return null;
+      }
+      boolean wildcardFound = false;
+      PartialParameterFilter filter = null;
+      BehaviorFilter beforeWildcardFilter = null;
+      boolean fullParameterFilter = false;
+      currentState = State.START;
+      Iterator<ASTParameter> iterator = parameters.iterator();
+      for (int currentIndex = 0; iterator.hasNext(); currentIndex++)
+      {
+         ASTParameter parameter = iterator.next();
+         // get the expression of a restriction to be filtered
+         ClassExpression exp = currentState.parse(this, parameter, buffer);
+         if (exp == WILDCARD)
+         {
+            // if there are restrictions to be filtered between two wildcards
+            // abort partial filter; use full parameter filter
+            if (wildcardFound && filter != null)
+            {
+               fullParameterFilter = true;
+               break;
+            }
+            // set flag
+            wildcardFound = true;
+            // if there is a beforeWildcardFilter, save it and reset filter
+            if (filter != null)
+            {
+               beforeWildcardFilter = filter;
+               filter = null;
+            }
+         }
+         // if there is a restriction, add it to the appropriate filter
+         else if (exp != null)
+         {
+            if (filter == null)
+            {
+               // initialize filter accordingly to wildcardFound value
+               filter = wildcardFound ? new DescendingPartialParameterFilter(
+                     parameters.size()) : new AscendingPartialParameterFilter(
+                     parameters.size());
+            }
+            // add the restriction to the filter
+            filter.addParameterRestriction(exp, currentIndex);
+         }
+      }
+      // if full parameter filter, finish parsing and return the full parameter filter
+      if (fullParameterFilter)
+      {
+         while(iterator.hasNext())
+         {
+            currentState.parse(this, iterator.next(), buffer);
+         }
+         currentState.finishParsing(buffer);
+         return new FullParameterFilter(behavior);
+      }
+      // finish parameter list parsing
+      currentState.finishParsing(buffer);
+      // if there is a filter to be applied on parameters before wildcard
+      if (beforeWildcardFilter != null)
+      {
+         // and there is a filter to be applied on parameters after wildcard
+         if (filter != null)
+         {
+            // use composite filter
+            return new ConjunctiveBehaviorFilter(beforeWildcardFilter, filter);
+         }
+         // otherwise, use the beforeWildcardFilter
+         return beforeWildcardFilter;
+      }
+      // use current filter (may be null)
+      return filter;
+   }
+   
+   enum ParameterType{
+      INSTANCE_ANNOTATED
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return parameter.getType();
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            buffer.append("||");
+         }
+      },
+      TYPEDEF
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return parameter.getType();
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            throw new RuntimeException("This method is not supposed to be called");
+         }
+      },
+      WILDCARD
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return ParameterParser.WILDCARD;
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            buffer.append('*');
+         }
+      },
+      SIMPLE
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return null;
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            buffer.append(' ');
+            buffer.append(parameterType.getOriginal());
+            buffer.append(' ');
+         }
+      },
+      PATTERN
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return parameter.getType();
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            buffer.append("||");
+         }
+      },
+      ANY
+      {
+         public ClassExpression getTypeFilterInfo(ASTParameter parameter)
+         {
+            return null;
+         }
+         
+         public void parse(ClassExpression parameterType, StringBuffer buffer)
+         {
+            buffer.append("||");
+         }
+      };
+   
+      public static final ParameterType getInstance(ASTParameter parameter)
+      {
+         if (parameter.isAnyZeroOrMoreParameters())
+         {
+            return ParameterType.WILDCARD;
+         }
+         return getInstance(parameter.getType());
+      }
+      
+      public static final ParameterType getInstance(ClassExpression parameter)
+      {
+         if (parameter.isAnnotation() || parameter.isInstanceOf()
+               || parameter.isInstanceOfAnnotated())
+         {
+            return ParameterType.INSTANCE_ANNOTATED;
+         }
+         if (parameter.isTypedef())
+         {
+            return ParameterType.TYPEDEF;
+         }
+         if (parameter.isSimple())
+         {
+            if (parameter.getOriginal().equals("*"))
+            {
+               return ParameterType.ANY;
+            }
+            if (parameter.getOriginal().indexOf('*') != -1)
+            {
+               return PATTERN;
+            }
+            return ParameterType.SIMPLE;
+         }
+         throw new IllegalArgumentException("Unexpected class expression type");
+      }
+      
+      public abstract ClassExpression getTypeFilterInfo(ASTParameter parameter);
+      public abstract void parse(ClassExpression parameterType, StringBuffer buffer);
+   }
+   
+   private enum State {
+      START
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            switch(type)
+            {
+               case SIMPLE:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case INSTANCE_ANNOTATED:
+               case PATTERN:
+               case ANY:
+                  type.parse(parameter, buffer);
+                  return ANY_PARAM;
+               case TYPEDEF:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case WILDCARD:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return FIRST_PARAM_WILDCARD;
+            }
+            throw new IllegalArgumentException("Unexpected parameter type");
+         }
+         
+         public void finishParsing(StringBuffer buffer)
+         {
+            throw new IllegalStateException("This method must not be called on this state.");
+         }
+      },
+      FIRST_PARAM_WILDCARD
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            switch(type)
+            {
+               // redo zero or more appending
+               // replacing "|*" by "*"
+               case INSTANCE_ANNOTATED:
+               case PATTERN:
+               case ANY:
+                  buffer.setLength(buffer.length() - 2);
+                  ParameterType.WILDCARD.parse(parameter, buffer);
+            }
+            State result = WILDCARD.parse(parameter, type, buffer);
+            return result == WILDCARD? this: result;
+         }
+         
+         public void finishParsing(StringBuffer buffer) {}
+      },
+      WILDCARD
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            switch(type)
+            {
+               case SIMPLE:
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case INSTANCE_ANNOTATED:
+               case PATTERN:
+               case ANY:
+                  type.parse(parameter, buffer);
+                  return ANY_PARAM;
+               case TYPEDEF:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+                  // zero or more (..) caracters must be combined
+               case WILDCARD:
+                  return WILDCARD;
+            }
+            throw new IllegalArgumentException("Unexpected parameter type");
+         }
+         
+         public void finishParsing(StringBuffer buffer)
+         {
+            buffer.append(' ');
+         }
+      },
+      // ||*
+      ANY_PARAM_WILDCARD
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            return  WILDCARD.parse(parameter, type, buffer);
+         }
+         
+         public void finishParsing(StringBuffer buffer) {}
+      },
+      // int *
+      SIMPLE_PARAM_WILDCARD
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            if (type == ParameterType.SIMPLE || type == ParameterType.TYPEDEF)
+            {
+               buffer.append(BehaviorNode.SEPARATOR);
+            }
+            return  WILDCARD.parse(parameter, type, buffer);
+         }
+         
+         public void finishParsing(StringBuffer buffer)
+         {
+            WILDCARD.finishParsing(buffer);
+         }
+      },
+      // ||
+      ANY_PARAM
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            switch(type)
+            {
+               case SIMPLE:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case INSTANCE_ANNOTATED:
+               case PATTERN:
+               case ANY:
+                  type.parse(parameter, buffer);
+                  return ANY_PARAM;
+               case TYPEDEF:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+                  // zero or more (..) caracters must be combined
+               case WILDCARD:
+                  type.parse(parameter, buffer);
+                  return ANY_PARAM_WILDCARD;
+            }
+            throw new IllegalArgumentException("Unexpected parameter type");
+         }
+         
+         public void finishParsing(StringBuffer buffer) {}
+      },
+      SIMPLE_PARAM
+      {
+         public State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer)
+         {
+            switch(type)
+            {
+               case SIMPLE:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case INSTANCE_ANNOTATED:
+               case PATTERN:
+               case ANY:
+                  type.parse(parameter, buffer);
+                  return ANY_PARAM;
+               case TYPEDEF:
+                  buffer.append('|');
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM;
+               case WILDCARD:
+                  type.parse(parameter, buffer);
+                  return SIMPLE_PARAM_WILDCARD;
+            }
+            throw new IllegalArgumentException("Unexpected parameter type");
+         }
+         
+         public void finishParsing(StringBuffer buffer)
+         {
+            buffer.append(' ');
+         }
+      };
+      
+      public ClassExpression parse(ParameterParser parser, ASTParameter parameter,
+            StringBuffer buffer)
+      {
+         ParameterType parameterType = ParameterType.getInstance(parameter);
+         ParameterType typeToParse;
+         ClassExpression parameterToParse;
+         if (parameterType == ParameterType.TYPEDEF)
+         {
+            parameterToParse = TypedefParser.extractClassExpression(
+                  parameter.getType());
+            typeToParse = ParameterType.getInstance(parameterToParse);
+         }
+         else
+         {
+            typeToParse = parameterType;
+            parameterToParse = parameter.getType();
+         }
+         parser.currentState = parse(parameterToParse, typeToParse, buffer);
+         return parameterType.getTypeFilterInfo(parameter);
+      }
+      
+      public abstract void finishParsing(StringBuffer buffer);
+      abstract State parse(ClassExpression parameter, ParameterType type, StringBuffer buffer);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParsedSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParsedSearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParsedSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -35,19 +35,16 @@
  */
 abstract class ParsedSearchKey extends SearchKey
 {
-   static final Collection<ASTAttribute> EMPTY_ATTRIBUTES = new ArrayList<ASTAttribute>(0);
-   static final Collection<ASTException> EMPTY_EXCEPTIONS = new ArrayList<ASTException>(0);
-   
-   
    /**
-    * Indicates whether this parsed search key has a main searcher defined. If it has
-    * not, then this search key is partially filled, and has only filters and
-    * auxiliary searchers defined.
-    * 
-    * @return {@code true} if this parsed search key has a main searcher defined
+    * The type of search to be performed by a search key.
     */
-   abstract boolean hasSearcher();
+   enum SearchType {ALL, FIELD, FIELD_GET, FIELD_SET, BEHAVIOR, CONSTRUCTION,
+      EXECUTION, CALL, UNDEFINED}
+     
    
+   static final Collection<ASTAttribute> EMPTY_ATTRIBUTES = new ArrayList<ASTAttribute>(0);
+   static final Collection<ASTException> EMPTY_EXCEPTIONS = new ArrayList<ASTException>(0);
+
    /**
     * Defines the class search expression.
     * 
@@ -60,22 +57,121 @@
     *                        well.
     */
    abstract void setClassExpression(String classExpression, boolean instanceOf);
-   
+  
    /**
+    * Deifines the main searcher associated with this search key.
     * 
-    * @param classNodeSearcher
+    * @param classNodeSearcher the main searcher
     */
    abstract void setSearcher(Searcher<ClassNode> classNodeSearcher);
    
+   /**
+    * Indicates whether this parsed search key has a main searcher defined. If it has
+    * not, then this search key is partially filled, and has only filters and
+    * auxiliary searchers defined.
+    * 
+    * @return {@code true} if this parsed search key has a main searcher defined
+    */
+   abstract boolean hasSearcher();
    
-   abstract void addTypeFilter(TypeFilter typeFilter);
-   abstract void addCalleeSearcher(CalleeSearcher calleeSearcher);
+   /**
+    * Returns the type of joinpoints searchked by this key. Can be invoked only
+    * after {@link #finishParsing()}.
+    * 
+    * @return the type of joinpoints searched by this key
+    */
+   abstract SearchType getSearchType();
    
-   abstract void addNegativeSearchKey(SearchKey searchKey);
-   abstract Object getLastAddedElement();
-   abstract void replaceTypeFilter(TypeFilter typeFilter);
-   abstract void replaceCalleeSearcher(CalleeSearcher restriction);
-   abstract void replaceNegativeSearchKey(ParsedSearchKey searchKey);
-   abstract void merge(SimpleSearchKey simpleSearchKey);
-   abstract SearchKey finishParsing();
+   /**
+    * Adds the conjunctive {@code typeFilter} to this key.
+    * 
+    * @param typeFilter a filter to be applied as an additional rule to all
+    *                   joinpoints found this key
+    * @return a search key that represents the conjunction of this key with {@code
+    *         typeFilter}
+    */
+   abstract ParsedSearchKey addConjunctiveTypeFilter(TypeFilter typeFilter);
+   
+   /**
+    * Adds the disjunctive {@code typeFilter} to this key.
+    * 
+    * @param typeFilter a filter whose accepted types must be part of the result,
+    *                   in addition to the joinpoints found by this key
+    * @return a search key that represents the disjunction of this key with {@code
+    *         typeFilter}
+    */
+   abstract ParsedSearchKey addDisjunctiveTypeFilter(TypeFilter typeFilter);
+   
+   /**
+    * Adds the conjunctive {@code calleeRestriction} to this key.
+    * 
+    * @param calleeRestriction a callee restriction to be applied as an additional
+    *                          rule to all joinpoints found by this key
+    * @return a search key that represents the conjunction of this key with {@code
+    *         caleeRestriction}
+    */
+   abstract ParsedSearchKey addConjunctiveCalleeRestriction(CalleeSearcher calleeRestriction);
+   
+   /**
+    * Adds the disjunctive {@code calleeRestriction} to this key.
+    * 
+    * @param calleeRestriction a callee restriction whose accepted call joinpoints
+    *                          must be part of the result, in addition to the
+    *                          joinpoints found by this key
+    * @return a search key that represents the disjunction of this key with {@code
+    *         calleeRestriction}
+    */
+   abstract ParsedSearchKey addDisjunctiveCalleeRestriction(CalleeSearcher calleeRestriction);
+   
+   /**
+    * Adds the conjunctive {@code searchKey} to this key.
+    * 
+    * @param searchKey a search key to be applied as an additional rule to all
+    *                   joinpoints found this key
+    * @return a search key that represents the conjunction of this key with {@code
+    *         searchKey}
+    */
+   abstract ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey);
+   
+   /**
+    * Adds the disjunctive {@code searchKey} to this key.
+    * 
+    * @param searchKey a search key whose found joinpoints must be part of the
+    *                  result, in addition to the joinpoints found by this key
+    * @return a search key that represents the disjunction of this key with {@code
+    *         searchKey}
+    */
+   abstract ParsedSearchKey addDisjunctiveSearchKey(ParsedSearchKey searchKey);
+   
+   /**
+    * Adds the negative {@code searchKey} to this key.
+    * 
+    * @param searchKey a search key whose result must be excluded from the result
+    *                  of the search
+    * @return the search key that represents the result found by this search key
+    *         but not found by {@code searchKey}
+    */
+   abstract ParsedSearchKey addNegativeSearchKey(ParsedSearchKey searchKey);
+   
+   /**
+    * Called by the parser to signal that no more operations will be performed.
+    * Once this method is called, no other method of this class can be executed,
+    * except for the {@link Searcher#search(Object, Collection) search},
+    * {@link #requiresExclusiveResult()}, and {@link #getSearchType()} methods.
+    * This method must be executed before any search is performed with this key.
+    * 
+    * @return an optimized search key representing this search key
+    */
+   abstract ParsedSearchKey finishParsing();
+   
+   /**
+    * Indicates whether this search key requires an exclusive result collection to
+    * perform {@link Searcher#search(Object, Collection)}. If it does, a newly
+    * created, empty collection must be used to perform search.
+    * 
+    * @return {@code true} if this search key requires an exclusive result collection,
+    *         as consequence of the need to manipulate this collection before getting
+    *         to a final result.
+    */
+   abstract boolean requiresExclusiveResult();
 }
\ No newline at end of file

Deleted: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegateSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegateSearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegateSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -1,181 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.aop.joinpoint.graph;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.jboss.aop.ConByConInfo;
-import org.jboss.aop.ConByMethodInfo;
-import org.jboss.aop.ConstructorInfo;
-import org.jboss.aop.JoinPointInfo;
-import org.jboss.aop.MethodByConInfo;
-import org.jboss.aop.MethodByMethodInfo;
-import org.jboss.aop.MethodInfo;
-import org.jboss.aop.joinpoint.MethodCall;
-import org.jboss.aop.joinpoint.graph.tree.Tree;
-import org.jboss.aop.pointcut.Pointcut;
-
-/**
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-public class PointcutDelegateSearchKey extends SimpleSearchKey
-{
-   private Pointcut pointcut;
-   
-   public PointcutDelegateSearchKey(Pointcut pointcut)
-   {
-      this.pointcut = pointcut;
-   }
-   
-   public boolean hasSearcher()
-   {
-      throw new RuntimeException("UNEXPECTED");
-   }
-
-   /* (non-Javadoc)
-    * @see org.jboss.aop.joinpoint.graph.ParsedSearchKey#finishParsing()
-    */
-   @Override
-   ParsedSearchKey finishParsing()
-   {
-      throw new RuntimeException("UNEXPECTED");
-   }
-
-   /* (non-Javadoc)
-    * @see org.jboss.aop.joinpoint.graph.ParsedSearchKey#setClassExpression(java.lang.String, boolean)
-    */
-   @Override
-   void setClassExpression(String className, boolean instanceOf)
-   {
-      throw new RuntimeException("UNEXPECTED");
-   }
-
-   /* (non-Javadoc)
-    * @see org.jboss.aop.joinpoint.graph.ParsedSearchKey#setClassNodeSearcher(org.jboss.aop.joinpoint.graph.ClassNodeSearcher)
-    */
-   @Override
-   void setSearcher(Searcher<ClassNode> classNodeSearcher)
-   {
-      throw new RuntimeException("UNEXPECTED");
-   }
-
-   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
-   {
-      Collection<? extends ClassNode> allClasses = classTree.search("*");
-      for (ClassNode classNode: allClasses)
-      {
-         Collection<BehaviorNode> behaviourNodes = classNode.searchBehaviors("*");
-         for (BehaviorNode behaviourNode: behaviourNodes)
-         {
-            if (behaviourNode.hasConstruction() &&
-                  pointcut.matchesConstruction(
-                        behaviourNode.getConstruction().getAdvisor(),
-                        behaviourNode.getConstruction().getConstructor()))
-            {
-               result.add(behaviourNode.getConstruction());
-            }
-            if (behaviourNode.hasExecution())
-            {
-               JoinPointInfo executionInfo = behaviourNode.getExecution();
-               if (executionInfo instanceof MethodInfo)
-               {
-                  MethodInfo methodInfo = (MethodInfo) executionInfo;
-                  if (pointcut.matchesExecution(methodInfo.getAdvisor(),
-                        methodInfo.getMethod()).isMatch())
-                  {
-                     result.add(executionInfo);
-                  }
-               }
-               else
-               {
-                  ConstructorInfo constructorInfo = (ConstructorInfo) executionInfo;
-                  if (pointcut.matchesExecution(constructorInfo.getAdvisor(),
-                        constructorInfo.getConstructor()))
-                  {
-                     result.add(executionInfo);
-                  }
-               }
-            }
-            Collection<JoinPointInfo> callees = new ArrayList<JoinPointInfo> ();
-            behaviourNode.searchCallees("*", callees);
-            for (JoinPointInfo caller: callees)
-            {
-               boolean matches = false;
-               if (caller instanceof MethodCall)
-               {
-                  if (caller instanceof MethodByMethodInfo)
-                  {
-                     MethodByMethodInfo info = (MethodByMethodInfo) caller;
-                     matches = pointcut.matchesCall(info.getAdvisor(),
-                           info.getCallingMethod(), info.getCalledClass(),
-                           info.getMethod());
-                  }
-                  else
-                  {
-                     MethodByConInfo info = (MethodByConInfo) caller;
-                     matches = pointcut.matchesCall(info.getAdvisor(),
-                           info.getCallingConstructor(), info.getCalledClass(),
-                           info.getMethod());
-                  }
-               }
-               else
-               {
-                  if (caller instanceof ConByMethodInfo)
-                  {
-                     ConByMethodInfo info = (ConByMethodInfo) caller;
-                     matches = pointcut.matchesCall(info.getAdvisor(),
-                           info.getCallingMethod(), info.getCalledClass(),
-                           info.getConstructor());
-                  }
-                  else
-                  {
-                     ConByConInfo info = (ConByConInfo) caller;
-                     matches = pointcut.matchesCall(info.getAdvisor(),
-                           info.getCallingConstructor(), info.getCalledClass(),
-                           info.getConstructor());
-                  }
-               }
-               if (matches)
-               {
-                  result.add(caller);
-               }
-            }
-         }
-         Collection<FieldNode> fieldNodes = classNode.searchFields("*");
-         for (FieldNode fieldNode: fieldNodes)
-         {
-            if (fieldNode.hasFieldRead() && pointcut.matchesGet(
-                  fieldNode.getFieldRead().getAdvisor(), fieldNode.getField()))
-            {
-               result.add(fieldNode.getFieldRead());
-            }
-            if (fieldNode.hasFieldWrite() && pointcut.matchesSet(
-                  fieldNode.getFieldWrite().getAdvisor(), fieldNode.getField()))
-            {
-               result.add(fieldNode.getFieldWrite());
-            }
-         }
-      }
-   }
-}
\ No newline at end of file

Copied: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegator.java (from rev 75393, projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegateSearchKey.java)
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegator.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/PointcutDelegator.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,232 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.MethodInfo;
+import org.jboss.aop.joinpoint.MethodCall;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+import org.jboss.aop.pointcut.Pointcut;
+
+/**
+ * Search key that delegates the search to a sequence of steps in which the
+ * joinpoints in the graph are matched against a pointcut. 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class PointcutDelegator extends NegativeCompositeSearchKey
+{
+   private Pointcut pointcut;
+   
+   /**
+    * Constructor.
+    * 
+    * @param pointcut the pointcut to which search will be delegated in the form
+    *                 of a sequence of matches
+    */
+   public PointcutDelegator(Pointcut pointcut)
+   {
+      this.pointcut = pointcut;
+   }
+
+   @Override
+   void setClassExpression(String className, boolean instanceOf)
+   {
+      throw new IllegalStateException("HasSearcher returned true");
+   }
+
+   @Override
+   void setSearcher(Searcher<ClassNode> classNodeSearcher)
+   {
+      throw new IllegalStateException("HasSearcher returned true");
+   }
+   
+   @Override
+   public boolean hasSearcher()
+   {
+      return true;
+   }
+   
+   @Override
+   SearchType getSearchType()
+   {
+      return SearchType.UNDEFINED;
+   }
+
+   @Override
+   ParsedSearchKey addConjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addConjunctiveTypeFilter(typeFilter);
+      return new ConjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addConjunctiveTypeFilter(typeFilter);
+      return new DisjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey addConjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addConjunctiveCalleeRestriction(calleeRestriction);
+      return new ConjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveCalleeRestriction(CalleeSearcher calleeRestriction)
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addConjunctiveCalleeRestriction(calleeRestriction);
+      return new DisjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      return new ConjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey addDisjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      return new DisjunctiveSearchKey(this, searchKey);
+   }
+
+   @Override
+   ParsedSearchKey finishParsing()
+   {
+      return this;
+   }
+
+   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
+   {
+      Collection<? extends ClassNode> allClasses = classTree.search("*");
+      for (ClassNode classNode: allClasses)
+      {
+         Collection<BehaviorNode> behaviourNodes = classNode.searchBehaviors("*");
+         for (BehaviorNode behaviourNode: behaviourNodes)
+         {
+            if (behaviourNode.hasConstruction() &&
+                  pointcut.matchesConstruction(
+                        behaviourNode.getConstruction().getAdvisor(),
+                        behaviourNode.getConstruction().getConstructor()))
+            {
+               result.add(behaviourNode.getConstruction());
+            }
+            if (behaviourNode.hasExecution())
+            {
+               JoinPointInfo executionInfo = behaviourNode.getExecution();
+               if (executionInfo instanceof MethodInfo)
+               {
+                  MethodInfo methodInfo = (MethodInfo) executionInfo;
+                  if (pointcut.matchesExecution(methodInfo.getAdvisor(),
+                        methodInfo.getMethod()).isMatch())
+                  {
+                     result.add(executionInfo);
+                  }
+               }
+               else
+               {
+                  ConstructorInfo constructorInfo = (ConstructorInfo) executionInfo;
+                  if (pointcut.matchesExecution(constructorInfo.getAdvisor(),
+                        constructorInfo.getConstructor()))
+                  {
+                     result.add(executionInfo);
+                  }
+               }
+            }
+            Collection<JoinPointInfo> callees = new ArrayList<JoinPointInfo> ();
+            behaviourNode.searchCallees("*", callees);
+            for (JoinPointInfo caller: callees)
+            {
+               boolean matches = false;
+               if (caller instanceof MethodCall)
+               {
+                  if (caller instanceof MethodByMethodInfo)
+                  {
+                     MethodByMethodInfo info = (MethodByMethodInfo) caller;
+                     matches = pointcut.matchesCall(info.getAdvisor(),
+                           info.getCallingMethod(), info.getCalledClass(),
+                           info.getMethod());
+                  }
+                  else
+                  {
+                     MethodByConInfo info = (MethodByConInfo) caller;
+                     matches = pointcut.matchesCall(info.getAdvisor(),
+                           info.getCallingConstructor(), info.getCalledClass(),
+                           info.getMethod());
+                  }
+               }
+               else
+               {
+                  if (caller instanceof ConByMethodInfo)
+                  {
+                     ConByMethodInfo info = (ConByMethodInfo) caller;
+                     matches = pointcut.matchesCall(info.getAdvisor(),
+                           info.getCallingMethod(), info.getCalledClass(),
+                           info.getConstructor());
+                  }
+                  else
+                  {
+                     ConByConInfo info = (ConByConInfo) caller;
+                     matches = pointcut.matchesCall(info.getAdvisor(),
+                           info.getCallingConstructor(), info.getCalledClass(),
+                           info.getConstructor());
+                  }
+               }
+               if (matches)
+               {
+                  result.add(caller);
+               }
+            }
+         }
+         Collection<FieldNode> fieldNodes = classNode.searchFields("*");
+         for (FieldNode fieldNode: fieldNodes)
+         {
+            if (fieldNode.hasFieldRead() && pointcut.matchesGet(
+                  fieldNode.getFieldRead().getAdvisor(), fieldNode.getField()))
+            {
+               result.add(fieldNode.getFieldRead());
+            }
+            if (fieldNode.hasFieldWrite() && pointcut.matchesSet(
+                  fieldNode.getFieldWrite().getAdvisor(), fieldNode.getField()))
+            {
+               result.add(fieldNode.getFieldWrite());
+            }
+         }
+      }
+      super.applyNegativeResult(classTree, result);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -24,7 +24,7 @@
 import org.jboss.aop.joinpoint.graph.tree.Tree;
 
 /**
- * The {@JoinPointGraph} search key.
+ * The {@code JoinPointGraph} search key.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */

Deleted: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyImpl.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyImpl.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyImpl.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -1,125 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.aop.joinpoint.graph;
-
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.jboss.aop.JoinPointInfo;
-import org.jboss.aop.joinpoint.graph.tree.Tree;
-
-/**
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- *
- */
-class SearchKeyImpl extends SimpleSearchKey
-{
-   private String classExpression;
-   private Searcher<ClassNode> searcher;
-
-   public void search(Tree<? extends ClassNode> classTree, Collection<JoinPointInfo> result)
-   {
-      Collection<ClassNode> classes = new LinkedList<ClassNode>();
-      classTree.search(classExpression, classes);
-      outer: for (ClassNode classNode: classes)
-      {
-         for (TypeFilter restriction: typeFilters)
-         {
-            if (!restriction.accept(classNode))
-            {
-               continue outer;
-            }
-         }
-         searcher.search(classNode, result);
-      }
-   }
-   
-   public void setClassExpression(String className, boolean instanceOf)
-   {
-      this.classExpression = instanceOf? className + "+": className;
-   }
-   
-   public void setSearcher(Searcher<ClassNode> searcher)
-   {
-      super.lastElementAdded = searcher;
-      this.searcher = searcher;
-   }
-
-   public SearchKey finishParsing()
-   {
-      if (this.calleeSearchers != null)
-      {
-         if (this.classExpression == null)
-         {
-            this.classExpression = "*";
-            BehaviorSearcher behaviourSearcher =
-               new BehaviorSearcher("*", ParsedSearchKey.EMPTY_ATTRIBUTES,
-                     ParsedSearchKey.EMPTY_EXCEPTIONS, null, true);
-            behaviourSearcher.setSearchType(BehaviorSearcher.SearchType.CALL);
-            ((CallSearcher) behaviourSearcher.getInternalSearcher()).
-               setCalleeRestrictionList(this.calleeSearchers);
-            this.searcher = behaviourSearcher;
-            return this;
-         }
-         if (this.searcher instanceof BehaviorSearcher &&
-            ((BehaviorSearcher) this.searcher).getInternalSearcher()
-            instanceof CallSearcher)
-         {
-            CallSearcher callSearcher = (CallSearcher) ((BehaviorSearcher)
-                  this.searcher).getInternalSearcher();
-            callSearcher.setCalleeRestrictionList(this.calleeSearchers);
-            return this;
-         }
-         return new EmptySearchKey();
-      }
-      if (this.classExpression == null)
-      {
-         this.classExpression = "*";
-         BehaviorSearcher behaviourSearcher =
-            new BehaviorSearcher("*", ParsedSearchKey.EMPTY_ATTRIBUTES,
-                  ParsedSearchKey.EMPTY_EXCEPTIONS, null, true);
-         behaviourSearcher.setSearchType(BehaviorSearcher.SearchType.ALL);
-         this.searcher = behaviourSearcher;
-         SearchKeyImpl fieldSearchKey = new SearchKeyImpl();
-         fieldSearchKey.classExpression = "*";
-         FieldSearcher fieldSearcher = new FieldSearcher("*",
-               ParsedSearchKey.EMPTY_ATTRIBUTES, null);
-         fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
-         fieldSearchKey.searcher = fieldSearcher;
-         fieldSearchKey.typeFilters = this.typeFilters;
-         fieldSearchKey.negativeSearchKeys = this.negativeSearchKeys;
-         return new DisjunctiveSearchKey(this, fieldSearchKey);
-      }
-      if (this.classExpression.endsWith("+"))
-      {
-         this.classExpression = this.classExpression.substring(0,
-               classExpression.length() - 1);
-         this.searcher = new SubtypeSearcher(this.searcher);
-      }
-      return this;
-   }
-
-   boolean hasSearcher()
-   {
-      return this.searcher != null;
-   }
-}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -21,9 +21,6 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
-import java.util.Collection;
-import java.util.Iterator;
-
 import org.jboss.aop.AspectManager;
 import org.jboss.aop.pointcut.Pointcut;
 import org.jboss.aop.pointcut.PointcutExpression;
@@ -33,7 +30,6 @@
 import org.jboss.aop.pointcut.ast.ASTAnd;
 import org.jboss.aop.pointcut.ast.ASTAndCFlow;
 import org.jboss.aop.pointcut.ast.ASTAttribute;
-import org.jboss.aop.pointcut.ast.ASTBehavior;
 import org.jboss.aop.pointcut.ast.ASTBoolean;
 import org.jboss.aop.pointcut.ast.ASTCFlow;
 import org.jboss.aop.pointcut.ast.ASTCFlowBoolean;
@@ -69,10 +65,24 @@
 import org.jboss.aop.pointcut.ast.PointcutExpressionParserVisitor;
 import org.jboss.aop.pointcut.ast.SimpleNode;
 
+/**
+ * Parses a pointcut, transforming it into a search key.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ * @see JoinPointGraph#search(SearchKey)
+ */
 public class SearchKeyParser implements PointcutExpressionParserVisitor
 {
    private static SearchKeyParser INSTANCE = new SearchKeyParser();
+   private ParameterParser parameterParser = new ParameterParser();   
    
+   /**
+    * Parses the pointcut into a search key.
+    * 
+    * @param pointcut the pointcut expression to be parsed
+    * @return a search key that searchs for all joinpoints matched by
+    *         {@code pointcut}.
+    */
    public static SearchKey parse(Pointcut pointcut)
    {
       if (pointcut instanceof PointcutExpression)
@@ -80,7 +90,7 @@
          return INSTANCE.visit(((PointcutExpression) pointcut).getParsedExpression(),
                null);
       }
-      return new PointcutDelegateSearchKey(pointcut);
+      return new PointcutDelegator(pointcut);
    }
    
    private SearchKeyParser() {}
@@ -89,7 +99,7 @@
    
    public SearchKey visit(ASTStart node, Object data)
    {
-      ParsedSearchKey searchKey = new SearchKeyImpl();
+      ParsedSearchKey searchKey = new StandardSearchKey();
       searchKey = this.visitSubNode(node, searchKey);
       return searchKey.finishParsing();
    }
@@ -100,19 +110,14 @@
    {
       ParsedSearchKey searchKey = (ParsedSearchKey) data;
       ParsedSearchKey result = (ParsedSearchKey)
-         node.jjtGetChild(0).jjtAccept(this,  new SearchKeyImpl());
-      if (!result.hasSearcher() && result instanceof SearchKeyImpl)
-      {
-         searchKey.merge((SearchKeyImpl) result);
-         return searchKey;
-      }
-      return result;
+         node.jjtGetChild(0).jjtAccept(this,  new StandardSearchKey());
+      return searchKey.addConjunctiveSearchKey(result);
    }
 
    public Object visit(ASTNot node, Object data)
    {
       ParsedSearchKey searchKey = (ParsedSearchKey) data;
-      ParsedSearchKey negativeSearchKey = new SearchKeyImpl();
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
       Object result = node.jjtGetChild(0).jjtAccept(this, negativeSearchKey);
       if (result!= null)
       {
@@ -124,22 +129,19 @@
          {
             return new NegativeCalleeSearcher((CalleeSearcher) result);
          }
-         searchKey.addNegativeSearchKey(negativeSearchKey.finishParsing());
+         return searchKey.addNegativeSearchKey((ParsedSearchKey) result);
       }
-      return null;
+      else
+      {
+         throw new RuntimeException();
+      }
    }
 
    public Object visit(ASTSub node, Object data)
    {
       ParsedSearchKey searchKey = (ParsedSearchKey) data;
-      Object result = visitSubNode(node, searchKey);
-      if (result != null)
+      for (int i = 0; i < node.jjtGetNumChildren(); i++)
       {
-         searchKey = (ParsedSearchKey) result;
-      }
-      
-      for (int i = 1; i < node.jjtGetNumChildren(); i++)
-      {
          searchKey = (ParsedSearchKey) node.jjtGetChild(i).jjtAccept(this, searchKey);  
       }
       return searchKey;
@@ -152,68 +154,15 @@
       
    private ParsedSearchKey visitSubNode(SimpleNode node, ParsedSearchKey searchKey)
    {
-      Object result = node.jjtGetChild(0).jjtAccept(this, searchKey);
-      if (result!= null)
-      {
-         if (result instanceof TypeFilter)
-         {
-            searchKey.addTypeFilter((TypeFilter) result);
-         }
-         else if (result instanceof CalleeSearcher)
-         {
-            searchKey.addCalleeSearcher((CalleeSearcher) result);
-         }
-         else // result intanceof ParsedSearchKey
-         {
-            return new ConjunctiveSearchKey(searchKey.finishParsing(), (ParsedSearchKey) result);
-         }
-      }
-      return searchKey;
+      return (ParsedSearchKey) node.jjtGetChild(0).jjtAccept(this, searchKey);
    }
 
    public Object visit(ASTOr node, Object data)
    {
       ParsedSearchKey searchKey = (ParsedSearchKey) data;
-      ParsedSearchKey newSearchKey = new SearchKeyImpl();
-      Object result = node.jjtGetChild(0).jjtAccept(this, newSearchKey);
-      if (result!= null)
-      {
-         if (result instanceof TypeFilter && 
-               searchKey.getLastAddedElement() != null &&
-                  searchKey.getLastAddedElement() instanceof TypeFilter)
-         {
-            searchKey.replaceTypeFilter(new DisjunctiveTypeFilter(
-                  (TypeFilter) searchKey.getLastAddedElement(),
-                  (TypeFilter) result));
-            return searchKey;
-         }
-         else if (result instanceof CalleeSearcher && 
-               searchKey.getLastAddedElement() != null &&
-               searchKey.getLastAddedElement() instanceof CalleeSearcher)
-         {
-            searchKey.replaceCalleeSearcher(new DisjunctiveCalleeSearcher(
-                  (CalleeSearcher)  searchKey.getLastAddedElement(),
-                  (CalleeSearcher)  result));
-            return searchKey;
-         }
-         else if(result instanceof ParsedSearchKey)
-         {
-            return new DisjunctiveSearchKey(searchKey.finishParsing(), (ParsedSearchKey) result);
-         }
-         else // partially filled ParsedSearchKey
-         {
-            if (result instanceof TypeFilter)
-            {
-               newSearchKey.addTypeFilter((TypeFilter) result);
-            }
-            else
-            {
-               newSearchKey.addCalleeSearcher((CalleeSearcher) result);
-            }
-            return new DisjunctiveSearchKey(searchKey.finishParsing(), newSearchKey);
-         }
-      }
-      return new DisjunctiveSearchKey(searchKey.finishParsing(), newSearchKey);
+      ParsedSearchKey newSearchKey = new StandardSearchKey();
+      ParsedSearchKey result = (ParsedSearchKey) node.jjtGetChild(0).jjtAccept(this, newSearchKey);
+      return searchKey.addDisjunctiveSearchKey(result);
    }
 
 
@@ -222,107 +171,106 @@
    /**
     * @param data the search key
     */
-   public Object visit(ASTAll node, Object data)
+   public ParsedSearchKey visit(ASTAll node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       this.setClassExpression(key, node.getClazz());
       key.setSearcher(AllSearcher.getInstance());
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
 
-   public Object visit(ASTGet node, Object data)
+   public ParsedSearchKey visit(ASTGet node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       FieldSearcher searcher = (FieldSearcher) node.jjtGetChild(0).jjtAccept(this,
             key);
       searcher.setSearchType(FieldSearcher.SearchType.READ);
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
-   public Object visit(ASTSet node, Object data)
+   public ParsedSearchKey visit(ASTSet node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       FieldSearcher searcher = (FieldSearcher) node.jjtGetChild(0).jjtAccept(this,
             key);
       searcher.setSearchType(FieldSearcher.SearchType.WRITE);
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
-   public Object visit(ASTFieldExecution node, Object data)
+   public ParsedSearchKey visit(ASTFieldExecution node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       FieldSearcher searcher = (FieldSearcher) node.jjtGetChild(0).jjtAccept(this,
             key);
       searcher.setSearchType(FieldSearcher.SearchType.ALL);
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
    /**
     * @param data the search key
     */
-   public Object visit(ASTConstruction node, Object data)
+   public ParsedSearchKey visit(ASTConstruction node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       BehaviorSearcher searcher = (BehaviorSearcher) node.jjtGetChild(0)
             .jjtAccept(this, key);
       searcher.setSearchType(BehaviorSearcher.SearchType.CONSTRUCTION);
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
    
    /**
     * @param data the search key
     */
-   public Object visit(ASTExecution node, Object data)
+   public ParsedSearchKey visit(ASTExecution node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
       BehaviorSearcher searcher = (BehaviorSearcher) node.jjtGetChild(0)
             .jjtAccept(this, key);
       searcher.setSearchType(BehaviorSearcher.SearchType.EXECUTION);
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
-   /**
-    * @param data the search key
-    */
    public Object visit(ASTCall node, Object data)
    {
-      return node.jjtGetChild(0).jjtAccept(this, null);
+      CalleeSearcher callee = (CalleeSearcher) node.getBehavior().jjtAccept(this, null);
+      ParsedSearchKey key = (ParsedSearchKey) data;
+      return key.addConjunctiveCalleeRestriction(callee);
    }
    
    
@@ -330,60 +278,49 @@
    
    public Object visit(ASTWithin node, Object data)
    {
-      // set class expression
       ParsedSearchKey key = (ParsedSearchKey) data;
-      this.setClassExpression(key, node.getClazz());
-      // create behaviour searcher
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         key = new StandardSearchKey();
       }
+      // set class expression
+      this.setClassExpression(key, node.getClazz());
+      // create behaviour searcher
       BehaviorSearcher searcher = new BehaviorSearcher("*",
-            ParsedSearchKey.EMPTY_ATTRIBUTES, ParsedSearchKey.EMPTY_EXCEPTIONS, null,
-            // this attribute is ireelevant in this scenario
-            true);
+            ParsedSearchKey.EMPTY_ATTRIBUTES, ParsedSearchKey.EMPTY_EXCEPTIONS);
       searcher.setSearchType(BehaviorSearcher.SearchType.CALL);
       key.setSearcher(searcher);
-      return returnValue;
-      /*
-      StringBuffer callerExpression = new StringBuffer();
-      callerExpression.append("*");
-      ClassExpression restriction = appendType(node.getClazz(), callerExpression);
-      callerExpression.append(".*(*)");
-      if (restriction != null)
-      {
-         return CalleeSearcherFactory.create(callerExpression.toString(),
-                  ParsedSearchKey.EMPTY_ATTRIBUTES, ParsedSearchKey.EMPTY_EXCEPTIONS,
-                  new TargetTypeFilter(restriction));
-      }
-      return CalleeSearcherFactory.create(callerExpression.toString());*/
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
    public Object visit(ASTWithincode node, Object data)
    {
       ParsedSearchKey key = (ParsedSearchKey) data;
-      ParsedSearchKey returnValue = null;
+      ParsedSearchKey originalKey = key;
       if (key.hasSearcher())
       {
-         returnValue = key = new SearchKeyImpl();
+         originalKey = key;
+         key = new StandardSearchKey();
       }
       BehaviorSearcher searcher = (BehaviorSearcher) node.jjtGetChild(0)
             .jjtAccept(this, key);
       searcher.setSearchType(BehaviorSearcher.SearchType.CALL);
       
       key.setSearcher(searcher);
-      return returnValue;
+      return key == originalKey? key: originalKey.addConjunctiveSearchKey(key);
    }
 
-   public Object visit(ASTHas node, Object data)
+   public ParsedSearchKey visit(ASTHas node, Object data)
    {
-      return new HasBehaviorFilter((SimpleNode) node.jjtGetChild(0));
+      TypeFilter typeFilter = new HasBehaviorFilter((SimpleNode) node.jjtGetChild(0));
+      return ((ParsedSearchKey) data).addConjunctiveTypeFilter(typeFilter);
    }
 
-   public Object visit(ASTHasField node, Object data)
+   public ParsedSearchKey visit(ASTHasField node, Object data)
    {
-      return new HasFieldFilter((ASTField) node.jjtGetChild(0));
+      TypeFilter typeFilter = new HasFieldFilter((ASTField) node.jjtGetChild(0));
+      return ((ParsedSearchKey) data).addConjunctiveTypeFilter(typeFilter);
    }
 
    
@@ -413,43 +350,47 @@
    public Object visit(ASTConstructor node, Object data)
    {
       StringBuffer expression = new StringBuffer();
-      BehaviorFilter behaviourFilter = visit(node, expression, (ParsedSearchKey) data);
+      BehaviorFilter behaviorFilter = visit(node, expression, (ParsedSearchKey) data);
       if (data == null)
       {
-         if (behaviourFilter == null)
+         if (behaviorFilter == null)
          {
             return CalleeSearcherFactory.create(expression.toString(),
                   node.getAttributes(), node.getExceptions());
          }
-         else
-         {
-            return CalleeSearcherFactory.create(expression.toString(),
-                  node.getAttributes(), node.getExceptions(), behaviourFilter);
-         }
+         return CalleeSearcherFactory.create(expression.toString(),
+               node.getAttributes(), node.getExceptions(), behaviorFilter);
       }
+      if (behaviorFilter == null)
+      {
+         return new BehaviorSearcher(expression.toString(), node.getAttributes(),
+               node .getExceptions());
+      }
       return new BehaviorSearcher(expression.toString(), node.getAttributes(), node
-            .getExceptions(), behaviourFilter, false);   
+            .getExceptions(), behaviorFilter, false);   
    }
 
    public Object visit(ASTMethod node, Object data)
    {
       StringBuffer expression = new StringBuffer();
-      BehaviorFilter behaviourFilter = visit(node, expression, ((ParsedSearchKey) data));
+      BehaviorFilter behaviorFilter = visit(node, expression, ((ParsedSearchKey) data));
       if (data == null)
       {
-         if (behaviourFilter != null)
+         if (behaviorFilter == null)
          {
             return CalleeSearcherFactory.create(expression.toString(),
-                  node.getAttributes(), node.getExceptions(), behaviourFilter);
-         }
-         else
-         {
-            return CalleeSearcherFactory.create(expression.toString(),
                   node.getAttributes(), node.getExceptions());
          }
+         return CalleeSearcherFactory.create(expression.toString(),
+                  node.getAttributes(), node.getExceptions(), behaviorFilter);
       }
+      if (behaviorFilter == null)
+      {
+         return new BehaviorSearcher(expression.toString(), node.getAttributes(),
+               node .getExceptions());
+      }
       return new BehaviorSearcher(expression.toString(), node.getAttributes(), node
-            .getExceptions(), behaviourFilter, true);
+            .getExceptions(), behaviorFilter, true);
    }
 
    public Object visit(ASTException node, Object data)
@@ -464,21 +405,6 @@
 
    public Object visit(ASTParameter node, Object data)
    {
-      StringBuffer buffer = (StringBuffer) data;
-      ClassExpression expression = node.getType();
-      if (expression.isAnnotation() || expression.isInstanceOf()
-            || expression.isInstanceOfAnnotated())
-      {
-         buffer.append("* ");
-         return expression;
-      }
-      if (expression.isTypedef())
-      {
-         buffer.append(TypedefParser.parse(expression));
-         buffer.append(' ');
-         return expression;
-      }
-      buffer.append(node.getTypeExpression()).append(' ');
       return null;
    }
 
@@ -502,7 +428,7 @@
          {
             behaviourFilter = new TargetTypeFilter(typeFilter);
          }
-         expression.append('.');
+         expression.append(BehaviorNode.SEPARATOR);
       }
       else
       {
@@ -520,7 +446,7 @@
          expression.append(annotationExp.getOriginal());
       }
       
-      BehaviorFilter parameterFilter = printParameters(expression, node);
+      BehaviorFilter parameterFilter = parameterParser.parse(node, expression);
       if (parameterFilter != null)
       {
          if (behaviourFilter == null)
@@ -540,36 +466,36 @@
       // behaviour filter
       BehaviorFilter behaviourFilter = null;
       
-      // check return type
-      ClassExpression returnFilter = appendType(node.getReturnType(), expression);
-      if (returnFilter != null)
-      {
-         behaviourFilter = new ReturnTypeFilter(returnFilter);
-      }
-      expression.append(' ');
-      
       // check target type
       if(searchKey == null)
       {
          ClassExpression typeFilter = appendType(node.getClazz(), expression);
          if (typeFilter != null)
          {
-            if (behaviourFilter == null)
-            {
-               behaviourFilter = new TargetTypeFilter(typeFilter);
-            }
-            else
-            {
-               behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter, new TargetTypeFilter(typeFilter));
-            }
+            behaviourFilter = new TargetTypeFilter(typeFilter);
          }
-         expression.append('.');
+         expression.append(BehaviorNode.SEPARATOR);
       }
       else
       {
          this.setClassExpression(searchKey, node.getClazz());
       }
       
+      // check return type
+      ClassExpression returnFilter = appendType(node.getReturnType(), expression);
+      if (returnFilter != null)
+      {
+         if (behaviourFilter == null)
+         {
+            behaviourFilter = new ReturnTypeFilter(returnFilter);
+         }
+         else
+         {
+            behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter,
+                     new ReturnTypeFilter(returnFilter));
+         }
+      }
+      expression.append(BehaviorNode.SEPARATOR).append(' ');
       
       // check identifier
       IdentifierExpression identifier = node.getMethodIdentifier();
@@ -594,7 +520,7 @@
       }
       
       // check parameters
-      BehaviorFilter parameterFilter = printParameters(expression, node);
+      BehaviorFilter parameterFilter = parameterParser.parse(node, expression);
       if (parameterFilter != null)
       {
          if (behaviourFilter != null)
@@ -614,13 +540,9 @@
    private ClassExpression appendType(ClassExpression type, StringBuffer buffer)
    {
       // check return type
-      if (type.isPackage())
+      // should never be a package if it is a return type
+      if (type.isPackage() || type.isSimple())
       {
-         // TODO Flavia
-         throw new RuntimeException();
-      }
-      if (type.isSimple())
-      {
          buffer.append(type.getOriginal());
          return null;
       }
@@ -637,7 +559,8 @@
    
    private void setClassExpression(ParsedSearchKey searchKey, ClassExpression classExpression)
    {
-      if (classExpression.isSimple() || classExpression.isAnnotation())
+      if (classExpression.isSimple() || classExpression.isAnnotation() ||
+            classExpression.isPackage())
       {
          searchKey.setClassExpression(classExpression.getOriginal(), false);
       }
@@ -653,89 +576,13 @@
          Typedef typedef = TypedefParser.getTypedef(classExpression);
          String expression = TypedefParser.parse(typedef);
          searchKey.setClassExpression(expression, false);
-         searchKey.addTypeFilter(new TypedefFilter(typedef));
+         searchKey.addConjunctiveTypeFilter(new TypedefFilter(typedef));
       }
    }
-
-   private BehaviorFilter printParameters(StringBuffer expression,
-         ASTBehavior behaviour)
-   {
-      Collection<ASTParameter> parameters = behaviour.getParameters();
-      expression.append('(');
-      int startLength = expression.length();
-      boolean wildcardFound = false;
-      int currentIndex = 0;
-      PartialParameterFilter filter = null;
-      BehaviorFilter beforeWildcardFilter = null;
-      Iterator<ASTParameter> iterator = parameters.iterator();
-
-      for (ASTParameter parameter = iterator.next(); iterator.hasNext();
-            parameter = iterator.next(), currentIndex++)
-      {
-         // found wildcard
-         if (parameter.isAnyZeroOrMoreParameters())
-         {
-            // if there are restrictions to be filtered between two wildcards
-            // abort partial filter; use full parameter filter
-            if (wildcardFound && filter != null)
-            {
-               expression.setLength(startLength);
-               expression.append("*)");
-               return new FullParameterFilter(behaviour);
-            }
-            // set flag
-            wildcardFound = true;
-            // if there is a beforeWildcardFilter, save it and reset filter
-            if (filter != null)
-            {
-               beforeWildcardFilter = filter;
-               filter = null;
-            }
-            // add the wildcard to the expression
-            expression.append('*');
-         }
-         // no wildcard
-         else
-         {
-            // get the expression of a restriction to be filtered
-            ClassExpression classExpression = (ClassExpression) this.visit(
-                  parameter, expression);
-            // if there is a restriction, add it to the appropriate filter
-            if (classExpression != null)
-            {
-               if (filter == null)
-               {
-                  // initialize filter accordingly to wildcardFound value
-                  filter = wildcardFound ? new DescendingPartialParameterFilter(
-                        parameters.size()) : new AscendingPartialParameterFilter(
-                        parameters.size());
-               }
-               // add the restriction to the filter
-               filter.addParameterRestriction(classExpression, currentIndex);
-            }
-         }
-      }
-      // finish parameter list expression
-      expression.append(')');
-      // if there is a filter to be applied on parameters before wildcard
-      if (beforeWildcardFilter != null)
-      {
-         // and there is a filter to be applied on parameters after wildcard
-         if (filter != null)
-         {
-            // use composite filter
-            return new ConjunctiveBehaviorFilter(beforeWildcardFilter, filter);
-         }
-         // otherwise, use the beforeWildcardFilter
-         return beforeWildcardFilter;
-      }
-      // use current filter (may be null)
-      return filter;
-   }
-
    
-   /* OTHER METHODS ****************************************************************/
    
+   /* SIMPLE_PARAM METHODS ****************************************************************/
+   
    public Object visit(SimpleNode node, Object data)
    {
       throw new RuntimeException("This method should not be called");
@@ -748,7 +595,7 @@
 
    public Object visit(ASTBoolean node, Object data)
    {
-      throw new RuntimeException("This method should not be called");
+      return node.jjtGetChild(0).jjtAccept(this, data);
    }
 
    

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Searcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Searcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Searcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -40,7 +40,8 @@
     * 
     * @param target        the target of the search, may be a node or a tree in the
     *                      graph
-    * @param searchResult  collection to where the search result will be added.
+    * @param searchResult  collection to where the search result will be added. A
+    *                      joinpoint may be added to this list more than twice.
     */
    public void search(T target, Collection<JoinPointInfo> searchResult);
 }
\ No newline at end of file

Deleted: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SimpleSearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SimpleSearchKey.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SimpleSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -1,130 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.aop.joinpoint.graph;
-
-import java.util.ArrayList;
-
-/**
- * A search key that does not wrap an internal search key.
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-abstract class SimpleSearchKey extends ParsedSearchKey
-{
-   protected ArrayList<TypeFilter> typeFilters;
-   protected ArrayList<CalleeSearcher> calleeSearchers;
-   protected ArrayList<SearchKey> negativeSearchKeys;
-   protected Object lastElementAdded = null;
-   
-   
-   public void addTypeFilter(TypeFilter typeRestriction)
-   {
-      if (typeFilters == null)
-      {
-         typeFilters = new ArrayList<TypeFilter>(1);
-      }
-      typeFilters.add(typeRestriction);
-      lastElementAdded = typeRestriction;
-   }
-   
-   
-   public void addCalleeSearcher(CalleeSearcher calleeSearcher)
-   {
-      if (calleeSearchers == null)
-      {
-         calleeSearchers = new ArrayList<CalleeSearcher>(1);
-      }
-      calleeSearchers.add(calleeSearcher);
-      lastElementAdded = calleeSearcher;
-   }
-   
-   public void addNegativeSearchKey(SearchKey searchKey)
-   {
-      if (this.negativeSearchKeys != null)
-      {
-         this.negativeSearchKeys = new ArrayList<SearchKey>(1);
-      }
-      this.negativeSearchKeys.add(searchKey);
-      this.lastElementAdded = searchKey;
-   }
-
-   public Object getLastAddedElement()
-   {
-      return this.lastElementAdded;
-   }
-
-   public void replaceTypeFilter(TypeFilter typeFilter)
-   {
-      this.typeFilters.set(typeFilters.size() -1, typeFilter);
-      this.lastElementAdded = typeFilter;
-   }
-
-   public void replaceCalleeSearcher(CalleeSearcher calleeSearcher)
-   {
-      this.calleeSearchers.set(calleeSearchers.size() -1, calleeSearcher);
-      this.lastElementAdded = calleeSearcher;
-   }
-   
-   public void replaceNegativeSearchKey(ParsedSearchKey searchKey)
-   {
-      this.negativeSearchKeys.set(negativeSearchKeys.size() -1, searchKey);
-      this.lastElementAdded = searchKey;
-   }
-   
-   public void merge(SimpleSearchKey simpleSearchKey)
-   {
-      if (simpleSearchKey.typeFilters != null)
-      {
-         if (this.typeFilters == null)
-         {
-            this.typeFilters = simpleSearchKey.typeFilters;
-         }
-         else
-         {
-            this.typeFilters.addAll(simpleSearchKey.typeFilters);
-         }
-      }
-      if (simpleSearchKey.calleeSearchers != null)
-      {
-         if (this.calleeSearchers == null)
-         {
-            this.calleeSearchers = simpleSearchKey.calleeSearchers;
-         }
-         else
-         {
-            this.calleeSearchers.addAll(simpleSearchKey.calleeSearchers);
-         }
-      }
-      if (simpleSearchKey.negativeSearchKeys != null)
-      {
-         if (this.negativeSearchKeys == null)
-         {
-            this.negativeSearchKeys = simpleSearchKey.negativeSearchKeys;
-         }
-         else
-         {
-            this.negativeSearchKeys.addAll(simpleSearchKey.negativeSearchKeys);
-         }
-      }
-      lastElementAdded = null;
-   }
-}
\ No newline at end of file

Copied: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardSearchKey.java (from rev 75393, projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyImpl.java)
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardSearchKey.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardSearchKey.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,332 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+
+/**
+ * The standard parsed search key.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class StandardSearchKey extends NegativeCompositeSearchKey
+{
+   private String classExpression;
+   private Searcher<ClassNode> searcher;
+   protected TypeFilter typeFilter;
+   protected CalleeSearcher calleeRestriction;
+   
+   @Override
+   public void setClassExpression(String className, boolean instanceOf)
+   {
+      this.classExpression = instanceOf? className + "+": className;
+   }
+   
+   @Override
+   public void setSearcher(Searcher<ClassNode> searcher)
+   {
+      this.searcher = searcher;
+   }
+
+   @Override
+   boolean hasSearcher()
+   {
+      return this.searcher != null;
+   }
+   
+   @Override
+   SearchType getSearchType()
+   {
+      Searcher searcher = this.searcher;
+      if (searcher instanceof SubtypeSearcher)
+      {
+         searcher = ((SubtypeSearcher) searcher).internalSearcher; 
+      }
+      if (searcher instanceof FieldSearcher)
+      {
+         FieldSearcher fieldSearcher = (FieldSearcher) searcher;
+         switch(fieldSearcher.getSearchType())
+         {
+            case ALL:
+               return SearchType.FIELD;
+            case READ:
+               return SearchType.FIELD_GET;
+            case WRITE:
+               return SearchType.FIELD_SET;
+            default:
+               throw new RuntimeException("Unexpected search type");
+         }
+      }
+      if (searcher instanceof BehaviorSearcher)
+      {
+         switch(((BehaviorSearcher) searcher).getSearchType())
+         {
+            case ALL:
+               return SearchType.BEHAVIOR;
+            case CALL:
+               return SearchType.CALL;
+            case EXECUTION:
+               return SearchType.EXECUTION;
+            case CONSTRUCTION:
+               return SearchType.CONSTRUCTION;
+            default:
+               throw new RuntimeException("Unexpected search type");
+         }
+      }
+      return SearchType.ALL;
+   }
+   
+   @Override
+   public ParsedSearchKey addConjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      if (this.typeFilter == null)
+      {
+         this.typeFilter = typeFilter;
+      }
+      else
+      {
+         this.typeFilter = new ConjunctiveTypeFilter(this.typeFilter, typeFilter);
+      }
+      return this;
+   }
+   
+   @Override
+   public ParsedSearchKey addDisjunctiveTypeFilter(TypeFilter typeFilter)
+   {
+      if (this.calleeRestriction == null && this.classExpression == null &&
+            this.searcher == null)
+      {
+         // there is no such possibility
+         //if (this.typeFilter == null)
+         this.typeFilter = new DisjunctiveTypeFilter(this.typeFilter, typeFilter);
+         return this;
+      }
+      else
+      {
+         StandardSearchKey searchKey = new StandardSearchKey();
+         searchKey.typeFilter = typeFilter;
+         return new DisjunctiveSearchKey(this, searchKey);
+      }
+   }
+   
+   @Override
+   public ParsedSearchKey addConjunctiveCalleeRestriction(
+         CalleeSearcher calleeRestriction)
+   {
+      if (this.calleeRestriction == null)
+      {
+         this.calleeRestriction = calleeRestriction;
+      }
+      else
+      {
+         this.calleeRestriction = new ConjunctiveCalleeSearcher(this.calleeRestriction,
+               calleeRestriction);
+      }
+      return this;
+   }
+   
+   @Override
+   public ParsedSearchKey addDisjunctiveCalleeRestriction(
+         CalleeSearcher calleeRestriction)
+   {
+      if (this.typeFilter == null && this.classExpression == null &&
+            this.searcher == null)
+      {
+         // there is no such possibility
+         //if (this.calleeSearcher == null)
+         this.calleeRestriction = new DisjunctiveCalleeSearcher(this.calleeRestriction,
+               calleeRestriction);
+         return this;
+      }
+      else
+      {
+         StandardSearchKey searchKey = new StandardSearchKey();
+         searchKey.calleeRestriction = calleeRestriction;
+         return new DisjunctiveSearchKey(this, searchKey);
+      }
+   }
+   
+   @Override
+   // a searchKey without typefilters and callees?
+   public ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey)
+   {
+      return addConjunctiveSearchKey(searchKey, true);
+   }
+   
+   @Override
+   public ParsedSearchKey addDisjunctiveSearchKey(
+         ParsedSearchKey searchKey)
+   {
+      if (searchKey instanceof StandardSearchKey)
+      {
+         StandardSearchKey key = (StandardSearchKey) searchKey;
+         if (!key.hasSearcher())
+         {
+            if (key.typeFilter != null && key.calleeRestriction== null)
+            {
+               return this.addDisjunctiveTypeFilter(key.typeFilter);
+            }
+            if (key.calleeRestriction!= null && key.typeFilter == null)
+            {
+               return this.addDisjunctiveCalleeRestriction(key.calleeRestriction);
+            }
+         }
+      }
+      return new DisjunctiveSearchKey(this, searchKey);
+   }
+   
+   @Override
+   public ParsedSearchKey finishParsing()
+   {
+      // already finished
+      if (this.searcher != null && this.searcher instanceof SubtypeSearcher)
+      {
+         return this;
+      }
+      if (this.calleeRestriction != null)
+      {
+         if (this.classExpression == null)
+         {
+            this.classExpression = "*";
+            BehaviorSearcher behaviourSearcher =
+               new BehaviorSearcher("*", ParsedSearchKey.EMPTY_ATTRIBUTES,
+                     ParsedSearchKey.EMPTY_EXCEPTIONS);
+            behaviourSearcher.setSearchType(BehaviorSearcher.SearchType.CALL);
+            ((CallSearcher) behaviourSearcher.getInternalSearcher()).
+               setCalleeRestriction(this.calleeRestriction);
+            this.searcher = behaviourSearcher;
+         }
+         else if (this.searcher instanceof BehaviorSearcher &&
+            ((BehaviorSearcher) this.searcher).getInternalSearcher()
+            instanceof CallSearcher)
+         {
+            CallSearcher callSearcher = (CallSearcher) ((BehaviorSearcher)
+                  this.searcher).getInternalSearcher();
+            callSearcher.setCalleeRestriction(this.calleeRestriction);
+         }
+         else
+         {
+            return EmptySearchKey.getInstance();
+         }
+      }
+      if (this.classExpression!= null && this.classExpression.endsWith("+"))
+      {
+         this.classExpression = this.classExpression.substring(0,
+               classExpression.length() - 1);
+         this.searcher = new SubtypeSearcher(this.searcher, this.typeFilter);
+         this.typeFilter = null;
+         return this;
+      }
+      if (this.classExpression == null)
+      {
+         if (this.negativeSearchKeys == null|| this.negativeSearchKeys.isEmpty())
+         {
+            // in this case, definetly there are no type filters
+            return EmptySearchKey.getInstance();
+         }
+         this.classExpression = "*";
+         BehaviorSearcher behaviourSearcher =
+            new BehaviorSearcher("*", ParsedSearchKey.EMPTY_ATTRIBUTES,
+                  ParsedSearchKey.EMPTY_EXCEPTIONS);
+         behaviourSearcher.setSearchType(BehaviorSearcher.SearchType.ALL);
+         this.searcher = behaviourSearcher;
+         StandardSearchKey fieldSearchKey = new StandardSearchKey();
+         fieldSearchKey.classExpression = "*";
+         FieldSearcher fieldSearcher = new FieldSearcher("*",
+               ParsedSearchKey.EMPTY_ATTRIBUTES, null);
+         fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+         fieldSearchKey.searcher = fieldSearcher;
+         fieldSearchKey.typeFilter = this.typeFilter;
+         ParsedSearchKey searchKey = new DisjunctiveSearchKey(this, fieldSearchKey);
+         for (ParsedSearchKey negativeSearchKey: this.negativeSearchKeys)
+         {
+            searchKey.addNegativeSearchKey(negativeSearchKey);
+         }
+         this.negativeSearchKeys = null;
+         return searchKey;
+      }
+      return this;
+   }
+   
+   public void search(Tree<? extends ClassNode> classTree,
+         Collection<JoinPointInfo> result)
+   {
+      Collection<ClassNode> classes = new LinkedList<ClassNode>();
+      classTree.search(classExpression, classes);
+      for (ClassNode classNode: classes)
+      {
+         if (typeFilter == null || typeFilter.accept(classNode))
+         {
+            searcher.search(classNode, result);
+         }
+      }
+      super.applyNegativeResult(classTree, result);
+   }
+   
+   private ParsedSearchKey addConjunctiveSearchKey(ParsedSearchKey searchKey,
+         boolean recursionAllow)
+   {
+      if (this.classExpression == null && this.searcher == null &&
+            this.typeFilter == null && this.calleeRestriction == null &&
+            this.negativeSearchKeys == null)
+      {
+         return searchKey;
+      }
+      else if (this.classExpression == null && this.searcher == null)
+      {
+         if (searchKey instanceof StandardSearchKey)
+         {
+            StandardSearchKey key = (StandardSearchKey) searchKey;
+            if (key.hasSearcher())
+            {
+               this.classExpression = ((StandardSearchKey) searchKey).classExpression;
+               this.searcher = ((StandardSearchKey) searchKey).searcher;
+               return this;
+            }
+            if (key.typeFilter != null && key.calleeRestriction == null)
+            {
+               return this.addConjunctiveTypeFilter(key.typeFilter);
+            }
+            else// (key.calleeSearcher != null && key.typeFilter == null)
+            {
+               return this.addConjunctiveCalleeRestriction(key.calleeRestriction);
+            }
+         }
+         else
+         {
+            return searchKey.addConjunctiveSearchKey(this);
+         }
+      }
+      else if (searchKey instanceof StandardSearchKey && recursionAllow)
+      {
+         return ((StandardSearchKey) searchKey).addConjunctiveSearchKey(this, false);
+      }
+      else
+      {
+         return new ConjunctiveSearchKey(this, searchKey);
+      }
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SubtypeSearcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SubtypeSearcher.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SubtypeSearcher.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -34,7 +34,8 @@
 class SubtypeSearcher implements Searcher<ClassNode>
 {
    Searcher<ClassNode> internalSearcher;
-
+   TypeFilter typeFilter;
+   
    /**
     * Creates a subtype searcher that applies a search on all the subtypes of a
     * {@code ClassNode}.
@@ -42,17 +43,21 @@
     * @param searcher performs the search that will be applied to the subtypes of
     *                 a {@code ClassNode}.
     */
-   public SubtypeSearcher(Searcher<ClassNode> searcher)
+   public SubtypeSearcher(Searcher<ClassNode> searcher, TypeFilter typeFilter)
    {
       this.internalSearcher = searcher;
+      this.typeFilter = typeFilter;
    }
    
    public void search(ClassNode node, Collection<JoinPointInfo> searchResult)
    {
+      if (typeFilter == null || typeFilter.accept(node))
+      {
+         internalSearcher.search(node, searchResult);
+      }
       for (ClassNode classNode: node.getSubtypes())
       {
          this.search(classNode, searchResult);
-         internalSearcher.search(classNode, searchResult);
       }
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypeFilter.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypeFilter.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypeFilter.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -44,17 +44,57 @@
    public boolean accept(ClassNode type);
 }
 
+/**
+ * A composite filter, uses two internal filters to decided on acceptance for a type.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+abstract class CompositeTypeFilter implements TypeFilter
+{
+   protected TypeFilter typeFilter1;
+   protected TypeFilter typeFilter2;
+   
+   public CompositeTypeFilter(TypeFilter typeRestriction1,
+         TypeFilter typeRestriction2)
+   {
+      this.typeFilter1 = typeRestriction1;
+      this.typeFilter2 = typeRestriction2;
+   }
+}
 
 /**
+ * Checks if a type is accepted by two filters.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ConjunctiveTypeFilter extends CompositeTypeFilter
+{
+   /**
+    * Creates a conjunctive filter that will apply the restrictions represented by
+    * both {@code filter1} or {@code filter2}.
+    * Always pick as filter1 the most likely one to suceed for acception.
+    */
+   public ConjunctiveTypeFilter(TypeFilter typeRestriction1,
+         TypeFilter typeRestriction2)
+   {
+      super(typeRestriction1, typeRestriction2);
+   }
+   
+   public boolean accept(ClassNode type)
+   {
+      return typeFilter1.accept(type) &&
+         typeFilter2.accept(type);
+   }
+}
+
+
+/**
  * Checks if a type is accepted by one of two filters.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-class DisjunctiveTypeFilter implements TypeFilter
+class DisjunctiveTypeFilter extends CompositeTypeFilter
 {
-   private TypeFilter typeRestriction1;
-   private TypeFilter typeRestriction2;
-   
    /**
     * Creates a disjunctive filter that will apply the restrictions represented by
     * both {@code filter1} or {@code filter2}.
@@ -63,14 +103,13 @@
    public DisjunctiveTypeFilter(TypeFilter typeRestriction1,
          TypeFilter typeRestriction2)
    {
-      this.typeRestriction1 = typeRestriction1;
-      this.typeRestriction2 = typeRestriction2;
+      super(typeRestriction1, typeRestriction2);
    }
    
    public boolean accept(ClassNode type)
    {
-      return typeRestriction1.accept(type) ||
-         typeRestriction2.accept(type);
+      return typeFilter1.accept(type) ||
+         typeFilter2.accept(type);
    }
 }
 
@@ -102,7 +141,7 @@
 }
 
 /**
- * Checks if a type contain a specific behavior.
+ * Checks if a type contains a specific behavior.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -135,7 +174,7 @@
 
 
 /**
- * Checks if a type contain a specific field.
+ * Checks if a type contains a specific field.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypedefParser.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypedefParser.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/TypedefParser.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -49,54 +49,33 @@
 import org.jboss.aop.pointcut.ast.TypeExpressionParserVisitor;
 
 /**
- * Parses a {@link Typedef} returning a type search expression.
+ * Parses typedef expressions, transforming them into non-accurate non-typedef
+ * search expressions. The results are generated on a best effort basis, closest
+ * in meaning to the original typedef expression.
  *  
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
 class TypedefParser implements TypeExpressionParserVisitor
 {
-   private static ThreadLocal<TypedefParser> INSTANCE =
-         new ThreadLocal<TypedefParser>() {
-      protected synchronized TypedefParser initialValue() {
-         return  new TypedefParser();
-      }
-   };
-      
-   private Object OR_FOUND = new Object();
-   private enum State {INITIAL, TYPEDEF_REF, OTHER, PREFIX, PACKAGE, DEFINITIVE}; 
+   private static TypedefParser INSTANCE = new TypedefParser();
+   private static ClassExpression WILDCARD = new ClassExpression("*");   
+   private static ClassExpression OR_FOUND = new ClassExpression("");
+   
+   private enum State {INITIAL, OTHER, PREFIX, PACKAGE, DEFINITIVE}; 
    private State currentState;
+   private Collection<ClassExpression> subTypeDefs;
    
-   public static TypedefParser getInstance()
+   private TypedefParser()
    {
-      return INSTANCE.get();
+      subTypeDefs = new ArrayList<ClassExpression>();
    }
    
-   private TypedefParser() {}
-   
-   private static String parse(Collection<ClassExpression> classExpressions)
-   {
-      String bestCurrentResult = "*";
-      State bestState = State.INITIAL;
-      TypedefParser instance = INSTANCE.get();
-      for (ClassExpression classExpression: classExpressions)
-      {
-         String parsed = TypedefParser.parse(classExpression);
-         if (parsed.length() != 1)
-         {
-            if (instance.currentState == State.DEFINITIVE)
-            {
-               return parsed;
-            }
-            if (bestState.compareTo(instance.currentState) < 0)
-            {
-               bestCurrentResult = parsed;
-               bestState = instance.currentState;
-            }
-         }
-      }
-      return bestCurrentResult;
-   }
-   
+   /**
+    * Returns the typedef referred by {@code classExpression}.
+    * 
+    * @param classExpression a typedef expression
+    * @return the typedef referred by {@code classExpression}.
+    */
    public static Typedef getTypedef(ClassExpression classExpression)
    {
       String original = classExpression.getOriginal();
@@ -106,36 +85,95 @@
       return manager.getTypedef(typedefName);
    }
    
+   /**
+    * On a best effort basis, creates an expression that searches
+    * for the types identified by {@code classExpression}.
+    * 
+    * @param classExpression a typedef expression
+    * @return a not-accurate expression that searches for the types identified by
+    *         {@code classExpression}
+    */
    public static String parse(ClassExpression classExpression)
    {
       Typedef typedef = getTypedef(classExpression);
       return parse(typedef);
    }
    
+   /**
+    * On a best effort basis, creates an expression that searches
+    * for the types identified by {@code typedef}.
+    * 
+    * @param typedef a typedef
+    * @return a not-accurate expression that searches for the types identified by
+    *         {@code typedef}
+    */
    public static String parse(Typedef typedef)
    {
       if (typedef != null && typedef instanceof TypedefExpression)
       {
-         return TypedefParser.getInstance().parseSearchExpression(typedef);
+         return INSTANCE.parseSearchExpression(typedef);
       }
       return "*";
    }
    
-   public String parseSearchExpression(Typedef typedef)
+   /**
+    * On a best effort basis, extracts the non-typedef class expression that best
+    * matches classes identified by {@code classExpression}.
+    *  
+    * @param classExpression a typedef expression
+    * @return the non-typedef class expression that best matches classes identified
+    *         by {@code classExpression}.
+    */
+   public static ClassExpression extractClassExpression(ClassExpression classExpression)
    {
+      Typedef typedef = getTypedef(classExpression);
+      if (typedef != null && typedef instanceof TypedefExpression)
+      {
+         ClassExpression exp = INSTANCE.extractBestClassExpression(typedef);
+         return (exp == null)? WILDCARD: exp;
+      }
+      return WILDCARD;
+   }
+   
+   @SuppressWarnings("all")
+   private synchronized String parseSearchExpression(Typedef typedef)
+   {
+      ClassExpression result = extractBestClassExpression(typedef);
+       return (result == null)? "*": result.getOriginal();
+   }
+   
+   private synchronized ClassExpression extractBestClassExpression(Typedef typedef)
+   {
+      this.subTypeDefs.clear();
       this.currentState = State.INITIAL;
       TypedefExpression typedefExpression = (TypedefExpression) typedef;
       ASTStart parsed = typedefExpression.getParsedExpression();
-      Object parsedResult = visit(parsed, null);
-      if (currentState.compareTo(State.OTHER) >= 0)
+      ClassExpression result = (ClassExpression) visit(parsed, null);
+      if (currentState == State.DEFINITIVE)
       {
-         return (String) parsedResult;   
+         return result;
       }
-      if (currentState == State.TYPEDEF_REF)
+      if (!subTypeDefs.isEmpty())
       {
-         return TypedefParser.parse((Collection<ClassExpression>) parsedResult);
+         for (ClassExpression classExpression: subTypeDefs)
+         {
+            TypedefParser parser = new TypedefParser();
+            ClassExpression subResult = parser.extractBestClassExpression(getTypedef(classExpression));
+            if (subResult != null)
+            {
+               if (parser.currentState == State.DEFINITIVE)
+               {
+                  return subResult;
+               }
+               if (currentState.compareTo(parser.currentState) < 0)
+               {
+                  result = subResult;
+                  this.currentState = parser.currentState;
+               }
+            }
+         }
       }
-      return "*";
+      return result;  
    }
 
    public Object visit(ASTStart node, Object data)
@@ -158,13 +196,14 @@
       return null;
    }
 
+   @SuppressWarnings("all")
    public Object visit(ASTSub node, Object data)
    {
       State oldState = currentState;
-      Object currentResult = null;
+      ClassExpression currentResult = null;
       for (int i = 0; i < node.jjtGetNumChildren(); i++)
       {
-         Object result = node.jjtGetChild(i).jjtAccept(this, data);
+         ClassExpression result = (ClassExpression) node.jjtGetChild(i).jjtAccept(this, data);
          if (result == null)
          {
             continue;
@@ -174,25 +213,6 @@
             currentState = oldState;
             return null;
          }
-         if (currentState == State.TYPEDEF_REF)
-         {
-            if (result instanceof ClassExpression)
-            {
-               if (currentResult == null)
-               {
-                  currentResult = new ArrayList();
-               }
-               ((Collection) currentResult).add(result);
-            }
-            else if (currentResult == null)
-            {
-               currentResult = result;
-            }
-            else
-            {
-               ((Collection) currentResult).addAll((Collection<ClassExpression>) result);
-            }
-         }
          else
          {
             currentResult = result;
@@ -211,7 +231,6 @@
       return OR_FOUND;
    }
 
-
    public Object visit(SimpleNode node, Object data)
    {
       return null;
@@ -247,7 +266,7 @@
          {
             this.currentState = State.DEFINITIVE;
          }
-         if (index == 0)
+         else if (index == 0)
          {
             if (currentState.compareTo(State.OTHER) >= 0)
             {
@@ -263,12 +282,11 @@
             }
             currentState = State.PREFIX;
          }
-         return expression;
+         return classExpression;
       }
-      if (classExpression.isTypedef() && currentState.compareTo(State.TYPEDEF_REF) <= 0)
+      if (classExpression.isTypedef() && this.currentState != State.DEFINITIVE)
       {
-         currentState = State.TYPEDEF_REF;
-         return classExpression;
+         this.subTypeDefs.add(classExpression);
       }
       return null;
    }

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/todo.txt
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/todo.txt	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/todo.txt	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,33 @@
+DONE -> add multiple keys on the tree for the same method, to deal with annotated parameters
+so, for instance:
+public void method(@Arg int arg1, @JoinPoint JoinPointInfo arg2)
+should be mapped by the three following keys:
+void method(int, JoinPointInfo)
+void method(@org.jboss.aop.Arg, JoinPointInfo)
+void method(int, @org.jboss.aop.JoinPoint)
+void method(@org.jboss.aop.Arg, @org.jboss.aop.JoinPoint)
+
+If method is annotated, we would have other four keys with the annotation instead of
+"method:
+void @Annotation(int, JoinPointInfo)
+.
+-> replace reference to Advisors by a reference to something else, like an interface.
+.
+
+Notice that this forces us to support multiple keys to a single element on the tree,
+i.e., the tree result should be in HashSets, and not ArrayLists, to avoid repetition
+
+Alternatively, we could write an intelligent mechanism that notices when two nodes are equal,
+aborting the search on branches whose equal leaf nodes have already been matched during the search.
+
+-> in future, when the generics pointcut matching is allowed, (ie, we can have
+a pointcut expression like call(int java.util.List<String>->size()), we will
+need to add the keys equivalent to generics types
+
+DONE -> add a search method to Tree that returns a single element, the first one to be found on the tree
+
+DONE -> deal with per instance joinpoints
+
+->transform everything in weak references
+  There is no need for that. Keeping ClassNodes as weak references and
+  componentAdvisedData as weak references should do.
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AbstractSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AbstractSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AbstractSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,591 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTBehavior;
+import org.jboss.aop.pointcut.ast.ASTException;
+import org.jboss.aop.pointcut.ast.ASTParameter;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+
+/**
+ * Contains all the infrastructure necessary for testing {@link SearchKeyParser}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public abstract class AbstractSearchKeyParserTest extends TestCase
+{
+   Field classExpressionField;
+   Field typeFilterField;
+   Field searcherField;
+   Field negativeSearchKeyField;
+   Field searchKey1Field;
+   Field searchKey2Field;
+   
+   Field typedefFilterTypedefField;
+   Field compFilter1Field;
+   Field compFilter2Field;
+   Field negFilterField;
+
+   Field subtypeSearcherInternalSearcherField;
+   Field subtypeSearcherTypeFilterField;
+   
+   Field fieldSearcherInternalField;
+   Field fieldSearcherExpressionField;
+   Field fieldSearcherAttField;
+   Field fieldSearcherFilterField;
+   
+   Field behaviorSearcherExpressionField;
+   Field behaviorSearcherAttField;
+   Field behaviorSearcherExcField;
+   Field behaviorSearcherFilterField;
+   Field behaviorSearcherActualFilterField;
+
+   Field callSearcherCalleeRestriction;
+   
+   Field fieldTypeFilterClassExpField;
+   Field returnTypeFilterClassExpField;
+   
+   Field partialParamFilterClassExpsField;
+   Field fullParamFilterBehaviorField;
+   Field implementMetFilterExactSuperField;
+   Field implementMetFilterExpField;
+   Field conjFilterFilter1Field;
+   Field conjFilterFilter2Field;
+   
+   Field calleeRestrictionExpField;
+   Field negCalleeRestrictionField;
+   Field compCalleeRestr1Field;
+   Field compCalleeRestr2Field;
+   
+   public void setUp() throws Exception
+   {
+      AspectManager.instance().addTypedef(new TypedefExpression("typedef", "class(TypedefClass)"));
+      classExpressionField = StandardSearchKey.class.getDeclaredField("classExpression");
+      classExpressionField.setAccessible(true);
+      typeFilterField = StandardSearchKey.class.getDeclaredField("typeFilter");
+      typeFilterField.setAccessible(true);
+      negativeSearchKeyField = NegativeCompositeSearchKey.class.getDeclaredField("negativeSearchKeys");
+      negativeSearchKeyField.setAccessible(true);
+      searchKey1Field = CompositeSearchKey.class.getDeclaredField("searchKey1");
+      searchKey1Field.setAccessible(true);
+      searchKey2Field = CompositeSearchKey.class.getDeclaredField("searchKey2");
+      searchKey2Field.setAccessible(true);
+      subtypeSearcherInternalSearcherField = SubtypeSearcher.class.getDeclaredField("internalSearcher");
+      subtypeSearcherInternalSearcherField.setAccessible(true);
+      subtypeSearcherTypeFilterField = SubtypeSearcher.class.getDeclaredField("typeFilter");
+      subtypeSearcherTypeFilterField.setAccessible(true);
+      searcherField = StandardSearchKey.class.getDeclaredField("searcher");
+      searcherField.setAccessible(true);
+      typedefFilterTypedefField = TypedefFilter.class.getDeclaredField("typedef");
+      typedefFilterTypedefField.setAccessible(true);
+      compFilter1Field = CompositeTypeFilter.class.getDeclaredField("typeFilter1");
+      compFilter1Field.setAccessible(true);
+      compFilter2Field = CompositeTypeFilter.class.getDeclaredField("typeFilter2");
+      compFilter2Field.setAccessible(true);
+      negFilterField = NegativeTypeFilter.class.getDeclaredField("typeFilter");
+      negFilterField.setAccessible(true);
+      fieldSearcherInternalField = FieldSearcher.class.getDeclaredField("internalSearcher");
+      fieldSearcherInternalField.setAccessible(true);
+      fieldSearcherExpressionField = FieldSearcher.class.getDeclaredField("fieldExpression");
+      fieldSearcherExpressionField.setAccessible(true);
+      fieldSearcherAttField = FieldSearcher.class.getDeclaredField("attributes");
+      fieldSearcherAttField.setAccessible(true);
+      fieldSearcherFilterField = FieldSearcher.class.getDeclaredField("fieldFilter");
+      fieldSearcherFilterField.setAccessible(true);
+      fieldTypeFilterClassExpField = FieldTypeFilter.class.getDeclaredField("classExpression");
+      fieldTypeFilterClassExpField.setAccessible(true);
+      
+      behaviorSearcherExpressionField = BehaviorSearcher.class.getDeclaredField("behaviorExpression");
+      behaviorSearcherExpressionField.setAccessible(true);
+      behaviorSearcherAttField = BehaviorSearcher.class.getDeclaredField("attributes");
+      behaviorSearcherAttField.setAccessible(true);
+      behaviorSearcherExcField = BehaviorSearcher.class.getDeclaredField("exceptions");
+      behaviorSearcherExcField.setAccessible(true);
+      behaviorSearcherFilterField = BehaviorSearcher.class.getDeclaredField("filter");
+      behaviorSearcherFilterField.setAccessible(true);
+      Class<?> filterClass = BehaviorSearcher.class.getClassLoader().loadClass(
+            BehaviorSearcher.class.getName() + "$Filter");
+      behaviorSearcherActualFilterField = filterClass.getDeclaredField("internalFilter");
+      behaviorSearcherActualFilterField.setAccessible(true);
+      
+      callSearcherCalleeRestriction = CallSearcher.class.getDeclaredField("calleeRestriction");
+      callSearcherCalleeRestriction.setAccessible(true);
+      
+      returnTypeFilterClassExpField = ReturnTypeFilter.class.getDeclaredField(
+            "classExpression");
+      returnTypeFilterClassExpField.setAccessible(true);
+      
+      partialParamFilterClassExpsField = PartialParameterFilter.class.
+         getDeclaredField("classExpressions");
+      fullParamFilterBehaviorField = FullParameterFilter.class.
+         getDeclaredField("astBehavior");
+      fullParamFilterBehaviorField.setAccessible(true);
+      implementMetFilterExactSuperField = ImplementedMethodFilter.class.
+            getDeclaredField("exactSuper");
+      implementMetFilterExactSuperField.setAccessible(true);
+      implementMetFilterExpField = ImplementedMethodFilter.class.
+         getDeclaredField("expression");
+      implementMetFilterExpField.setAccessible(true);
+      
+      conjFilterFilter1Field = ConjunctiveBehaviorFilter.class.getDeclaredField("filter1");
+      conjFilterFilter1Field.setAccessible(true);
+      conjFilterFilter2Field = ConjunctiveBehaviorFilter.class.getDeclaredField("filter2");
+      conjFilterFilter2Field.setAccessible(true);
+      
+      calleeRestrictionExpField = SimpleCalleeSearcher.class.
+         getDeclaredField("calleeExpression");
+      calleeRestrictionExpField.setAccessible(true);
+      negCalleeRestrictionField = NegativeCalleeSearcher.class.getDeclaredField("calleeRestriction");
+      negCalleeRestrictionField.setAccessible(true);
+      compCalleeRestr1Field = CompositeCalleeSearcher.class.getDeclaredField("restriction1");
+      compCalleeRestr1Field.setAccessible(true);
+      compCalleeRestr2Field = CompositeCalleeSearcher.class.getDeclaredField("restriction2");
+      compCalleeRestr2Field.setAccessible(true);
+   }
+   
+   protected void assertTypedefFilter(TypeFilter filter, String typedefName) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof TypedefFilter);
+      Typedef typedef = (Typedef) typedefFilterTypedefField.get(filter);
+      assertEquals(typedefName, typedef.getName());
+   }
+   
+   protected void assertHasFieldFilter(TypeFilter filter) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof HasFieldFilter);
+   }
+   
+   protected void assertHasBehaviorFilter(TypeFilter filter) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof HasBehaviorFilter);
+   }
+   
+   protected TypeFilter assertNegativeTypeFilter(TypeFilter typeFilter) throws Exception
+   {
+      assertNotNull(typeFilter);
+      assertTrue(typeFilter instanceof NegativeTypeFilter);
+      return (TypeFilter) negFilterField.get(typeFilter);
+   }
+   
+   protected SearchKey getSearchKey1(SearchKey searchKey, boolean conjunctive) throws Exception
+   {
+      assertNotNull(searchKey);
+      if (conjunctive)
+      {
+         assertTrue(searchKey instanceof ConjunctiveSearchKey);
+      }
+      else
+      {
+         assertTrue(searchKey instanceof DisjunctiveSearchKey);
+      }
+      return (SearchKey) searchKey1Field.get(searchKey);
+   }
+   
+   protected SearchKey getSearchKey2(SearchKey searchKey, boolean conjunctive) throws Exception
+   {
+      assertNotNull(searchKey);
+      if (conjunctive)
+      {
+         assertTrue(searchKey instanceof ConjunctiveSearchKey);
+      }
+      else
+      {
+         assertTrue(searchKey instanceof DisjunctiveSearchKey);
+      }
+      return (SearchKey) searchKey2Field.get(searchKey);
+   }
+   
+   @SuppressWarnings("all")
+   protected void assertFieldSearchKey(SearchKey searchKey, String classExp,
+         String fieldExp, String filterExp, FieldSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      assertTrue(searchKey instanceof StandardSearchKey);
+      assertEquals(classExp, classExpressionField.get(searchKey));
+      Searcher<ClassNode> searcher = (Searcher<ClassNode>) searcherField.get(searchKey);
+      this.assertFieldSearcher(searcher, fieldExp, filterExp, searchType, attributes);
+   }
+   
+   @SuppressWarnings("all")
+   protected TypeFilter assertSubtypeFieldSearchKey(SearchKey searchKey,
+         String classExp, String fieldExp, String filterExp,
+         FieldSearcher.SearchType searchType, ASTAttribute... attributes) throws Exception
+   {
+      SubtypeSearcher subtypeSearcher = assertSubtypeSearchKey(searchKey, classExp);
+      Searcher<ClassNode> searcher = (Searcher<ClassNode>)
+         subtypeSearcherInternalSearcherField.get(subtypeSearcher);
+      this.assertFieldSearcher(searcher, fieldExp, filterExp, searchType, attributes);
+      return (TypeFilter) subtypeSearcherTypeFilterField.get(subtypeSearcher);
+   }
+   
+   @SuppressWarnings("all")
+   private void assertFieldSearcher(Searcher<ClassNode> searcher, String fieldExp,
+         String filterExp, FieldSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      assertTrue(searcher instanceof FieldSearcher);
+      assertEquals(fieldExp, fieldSearcherExpressionField.get(searcher));
+      assertSame(searchType, fieldSearcherInternalField.get(searcher));
+      Util.assertCollection((Collection<ASTAttribute>)
+            fieldSearcherAttField.get(searcher), attributes);
+      if (filterExp == null)
+      {
+         assertNull(fieldSearcherFilterField.get(searcher));
+      }
+      else
+      {
+         FieldFilter filter = (FieldFilter) fieldSearcherFilterField.get(searcher);
+         assertNotNull(filter);
+         assertTrue(filter instanceof FieldTypeFilter);
+         ClassExpression filterActualExp =
+            (ClassExpression) fieldTypeFilterClassExpField.get(filter);
+         assertEquals(filterExp, filterActualExp.getOriginal());
+      }
+   }
+   
+   protected BehaviorFilter assertBehaviorSearchKey(SearchKey searchKey, String classExp,
+         String behaviorExp, BehaviorSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      BehaviorSearcher searcher = assertBehaviorSK(searchKey, classExp, behaviorExp,
+            searchType,
+            attributes);
+      return getBehaviorFilter(searcher);
+   }
+   
+   @SuppressWarnings("all")
+   protected BehaviorFilter assertBehaviorSearchKey(SearchKey searchKey, String classExp,
+         String behaviorExp, BehaviorSearcher.SearchType searchType,
+         ASTException[] exceptions, ASTAttribute... attributes) throws Exception
+   {
+      BehaviorSearcher searcher = assertBehaviorSK(searchKey, classExp, behaviorExp,
+            searchType,
+            attributes);
+      Util.assertCollection((Collection<ASTException>)
+         behaviorSearcherExcField.get(searcher), exceptions);
+      return getBehaviorFilter(searcher);
+   }
+
+   @SuppressWarnings("all")
+   protected TypeFilter assertSubtypeBehaviorSearchKey(SearchKey searchKey,
+         String classExp, String behaviorExp, BehaviorSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      SubtypeSearcher subtypeSearcher = assertSubtypeSearchKey(searchKey, classExp);
+      Searcher<ClassNode> searcher = (Searcher<ClassNode>)
+         subtypeSearcherInternalSearcherField.get(subtypeSearcher);
+      assertBehaviorSearcher(searcher, behaviorExp, searchType, attributes);
+      assertNull(getBehaviorFilter((BehaviorSearcher) searcher));
+      return (TypeFilter) subtypeSearcherTypeFilterField.get(subtypeSearcher);
+   }
+   
+   protected CalleeSearcher assertBehaviorCallSearchKey(SearchKey searchKey,
+         String classExp, String behaviorExp,  ASTAttribute... attributes) throws Exception
+   {
+      BehaviorSearcher searcher = assertBehaviorSK(searchKey, classExp, behaviorExp,
+            BehaviorSearcher.SearchType.CALL, attributes);
+      return assertBehaviorCallSearcher(searcher, behaviorExp);
+   }
+
+   @SuppressWarnings("all")
+   protected CalleeSearcher assertSubtypeBehaviorCallSearchKey(SearchKey searchKey,
+         String classExp, String behaviorExp, ASTAttribute... attributes) throws Exception
+   {
+      SubtypeSearcher subtypeSearcher = assertSubtypeSearchKey(searchKey, classExp);
+      Searcher<ClassNode> searcher = (Searcher<ClassNode>)
+         subtypeSearcherInternalSearcherField.get(subtypeSearcher);
+      assertNull(getBehaviorFilter((BehaviorSearcher) searcher));
+      return assertBehaviorCallSearcher((BehaviorSearcher) searcher, behaviorExp, attributes);
+   }
+   
+   @SuppressWarnings("all")
+   protected CalleeSearcher assertBehaviorCallSearcher(BehaviorSearcher searcher,
+         String behaviorExp, ASTAttribute... attributes) throws Exception
+   {
+      Util.assertCollection((Collection<ASTException>)
+            behaviorSearcherExcField.get(searcher));
+      Util.assertCollection((Collection<ASTAttribute>)
+            behaviorSearcherAttField.get(searcher), attributes);
+      assertNull(getBehaviorFilter(searcher));
+      Object callSearcher = searcher.getInternalSearcher();
+      assertTrue(callSearcher instanceof CallSearcher);
+      return (CalleeSearcher) callSearcherCalleeRestriction.get(callSearcher); 
+   }
+   
+   @SuppressWarnings("all")
+   protected BehaviorSearcher assertBehaviorSK(SearchKey searchKey, String classExp,
+         String behaviorExp, BehaviorSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      assertTrue(searchKey instanceof StandardSearchKey);
+      assertEquals(classExp, classExpressionField.get(searchKey));
+      Searcher<ClassNode> searcher = (Searcher<ClassNode>) searcherField.get(searchKey);
+      return assertBehaviorSearcher(searcher, behaviorExp, searchType,
+            attributes);
+   }
+   
+   @SuppressWarnings("all")
+   protected BehaviorSearcher assertBehaviorSearcher(Searcher<ClassNode> searcher,
+         String behaviorExp, BehaviorSearcher.SearchType searchType,
+         ASTAttribute... attributes) throws Exception
+   {
+      assertTrue(searcher instanceof BehaviorSearcher);
+      assertEquals(behaviorExp, behaviorSearcherExpressionField.get(searcher));
+      switch(searchType)
+      {
+         case CONSTRUCTION:
+            assertSame(ConstructionSearcher.getInstance(),
+                  ((BehaviorSearcher) searcher).getInternalSearcher());
+            break;
+         case EXECUTION:
+            assertSame(ExecutionSearcher.getInstance(),
+                  ((BehaviorSearcher) searcher).getInternalSearcher());
+            break;
+      }
+      
+      Util.assertCollection((Collection<ASTAttribute>)
+         behaviorSearcherAttField.get(searcher), attributes);
+      return (BehaviorSearcher) searcher;
+   }
+   
+   protected SubtypeSearcher assertSubtypeSearchKey(SearchKey searchKey, String classExp) throws Exception
+   {
+      assertTrue(searchKey instanceof StandardSearchKey);
+      assertEquals(classExp, classExpressionField.get(searchKey));
+      Object searcher = searcherField.get(searchKey);
+      assertTrue(searcher instanceof SubtypeSearcher);
+      assertNull((TypeFilter) typeFilterField.get(searchKey));
+      return (SubtypeSearcher) searcher;
+   }
+   
+   protected TypeFilter assertAllSearchKey(SearchKey searchKey, String classExp) throws Exception
+   {
+      assertTrue(searchKey instanceof StandardSearchKey);
+      assertEquals(classExp, classExpressionField.get(searchKey));
+      assertTrue(searcherField.get(searchKey) instanceof AllSearcher);
+      return (TypeFilter) typeFilterField.get(searchKey);
+   }
+   
+   protected TypeFilter assertSubtypeAllSearchKey(SearchKey searchKey, String classExp) throws Exception
+   {
+      SubtypeSearcher searcher = assertSubtypeSearchKey(searchKey, classExp);
+      Object allSearcher = subtypeSearcherInternalSearcherField.get(searcher);
+      assertNotNull(allSearcher);
+      assertTrue(allSearcher instanceof AllSearcher);
+      return (TypeFilter) subtypeSearcherTypeFilterField.get(searcher);
+   }
+   
+   protected TypeFilter assertWithinSearchKey(SearchKey searchKey, String classExp) throws Exception
+   {
+      BehaviorFilter behaviorFilter = assertBehaviorSearchKey(searchKey, classExp,
+            "*", BehaviorSearcher.SearchType.CALL);
+      assertNull(behaviorFilter);
+      return (TypeFilter) typeFilterField.get(searchKey);
+   }
+   
+   protected TypeFilter assertSubtypeWithinSearchKey(SearchKey searchKey, String classExp) throws Exception
+   {
+      return assertSubtypeBehaviorSearchKey(searchKey, classExp,
+            "*", BehaviorSearcher.SearchType.CALL);
+   }
+   
+   private BehaviorFilter getBehaviorFilter(BehaviorSearcher searcher) throws Exception
+   {
+      Object filter = behaviorSearcherFilterField.get(searcher);
+      if (filter == null)
+      {
+         return null;
+      }
+      return (BehaviorFilter) behaviorSearcherActualFilterField.get(filter);
+   }
+      
+   public void assertAscParamFilter(Object filter, String... exps) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof AscendingPartialParameterFilter);
+      assertPartialParamFilter(filter, exps);
+   }
+   
+   public void assertDescParamFilter(Object filter, String... exps) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof DescendingPartialParameterFilter);
+      assertPartialParamFilter(filter, exps);
+   }
+   
+   private void assertPartialParamFilter(Object filter, String... exps) throws Exception
+   {
+      ClassExpression[] expressions = (ClassExpression[])
+         partialParamFilterClassExpsField.get(filter);
+      assertEquals(exps.length, expressions.length);
+      for (int i = 0; i < exps.length; i++)
+      {
+         if (exps[i] == null)
+         {
+            assertNull(expressions[i]);
+         }
+         else
+         {
+            assertNotNull(expressions[i]);
+            assertEquals(exps[i], expressions[i].getOriginal());
+         }
+      }
+   }
+   
+   protected void assertFullParamFilter(Object filter, String... exps) throws Exception
+   {
+     assertNotNull(filter);
+     assertTrue(filter instanceof FullParameterFilter);
+     ASTBehavior behavior = (ASTBehavior) fullParamFilterBehaviorField.get(filter);
+     Collection<ASTParameter> parameters = behavior.getParameters();
+     assertEquals(exps.length, parameters.size());
+     int i = 0;
+     for (ASTParameter parameter: parameters)
+     {
+        if (exps[i].equals(".."))
+        {
+           assertTrue(parameter.isAnyZeroOrMoreParameters());
+           i++;
+        }
+        else
+        {
+           assertEquals(exps[i++], parameter.getType().getOriginal());
+        }
+     }
+   }
+   
+   protected void assertReturnTypeFilter(Object filter, String expression) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof ReturnTypeFilter);
+      assertEquals(expression, ((ClassExpression)
+            returnTypeFilterClassExpField.get(filter)).getOriginal());
+   }
+   
+   protected void assertImplementFilter(Object filter, boolean exactSuper, String expression) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof ImplementedMethodFilter);
+      assertEquals(exactSuper, implementMetFilterExactSuperField.get(filter));
+      assertEquals(expression, ((ClassExpression)
+               implementMetFilterExpField.get(filter)).getOriginal());
+   }
+   
+   protected BehaviorFilter getConjSubFilter1(BehaviorFilter filter) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof ConjunctiveBehaviorFilter);
+      return (BehaviorFilter) conjFilterFilter1Field.get(filter);
+   }
+   
+   protected BehaviorFilter getConjSubFilter2(BehaviorFilter filter) throws Exception
+   {
+      assertNotNull(filter);
+      assertTrue(filter instanceof ConjunctiveBehaviorFilter);
+      return (BehaviorFilter) conjFilterFilter2Field.get(filter);
+   }
+   
+   protected void assertSimpleCalleeRestriction(CalleeSearcher calleeSearcher,
+         String expression) throws Exception
+   {
+      assertNotNull(calleeSearcher);
+      assertTrue(calleeSearcher instanceof SimpleCalleeSearcher);
+      assertEquals(expression, calleeRestrictionExpField.get(calleeSearcher));
+   }
+   
+   protected CalleeSearcher getRestriction1(CalleeSearcher restriction, boolean conjunctive) throws Exception
+   {
+      assertCompositeCalleeRestriction(restriction, conjunctive);
+      return (CalleeSearcher) compCalleeRestr1Field.get(restriction);
+   }
+   
+   protected CalleeSearcher getRestriction2(CalleeSearcher restriction, boolean conjunctive) throws Exception
+   {
+      assertCompositeCalleeRestriction(restriction, conjunctive);
+      return (CalleeSearcher) compCalleeRestr2Field.get(restriction);
+   }
+   
+   private void assertCompositeCalleeRestriction(CalleeSearcher restriction, boolean conjunctive)
+   {
+      assertNotNull(restriction);
+      if (conjunctive)
+      {
+         assertTrue(restriction instanceof ConjunctiveCalleeSearcher);
+      }
+      else
+      {
+         assertTrue(restriction instanceof DisjunctiveCalleeSearcher);
+      }
+   }
+   
+   protected TypeFilter getTypeFilter1(TypeFilter typeFilter, boolean conjunctive) throws Exception
+   {
+      assertCompositeTypeFilter(typeFilter, conjunctive);
+      return  (TypeFilter) compFilter1Field.get(typeFilter);
+   }
+
+   protected TypeFilter getTypeFilter2(TypeFilter typeFilter, boolean conjunctive) throws Exception
+   {
+      assertCompositeTypeFilter(typeFilter, conjunctive);
+      return  (TypeFilter) compFilter2Field.get(typeFilter);
+   }
+
+   private void assertCompositeTypeFilter(TypeFilter typeFilter, boolean conjunctive)
+   {
+      assertNotNull(typeFilter);
+      if (conjunctive)
+      {
+         assertTrue(typeFilter instanceof ConjunctiveTypeFilter);
+      }
+      else
+      {
+         assertTrue(typeFilter instanceof DisjunctiveTypeFilter);
+      }
+   }
+
+   public CalleeSearcher assertNegativeCalleeRestriction(CalleeSearcher restriction) throws Exception
+   {
+      assertNotNull(restriction);
+      assertTrue(restriction instanceof NegativeCalleeSearcher);
+      return (CalleeSearcher) negCalleeRestrictionField.get(restriction);
+   }
+   
+   public ParsedSearchKey getNegativeSearchKey(SearchKey searchKey, int index, int length) throws Exception
+   {
+      ArrayList negativeSearchKeys = (ArrayList) negativeSearchKeyField.get(searchKey);
+      assertEquals(length, negativeSearchKeys.size());
+      return (ParsedSearchKey) negativeSearchKeys.get(index);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisedDataTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisedDataTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisedDataTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -93,7 +93,7 @@
       Method method = Pojo1.class.getDeclaredMethod("method1", String.class, String.class);
       BehaviorNode behaviorNode = advisedData.getBehavior(method);
       BehaviorNodeTest.assertBehaviorNode(method, behaviorNode,
-            "void method1(java.lang.String java.lang.String )");
+            "void| method1#| java.lang.String | java.lang.String  ");
       
       Util.assertCollection(advisedData.searchFields("*"));
       Util.assertCollection(advisedData.searchBehaviors("*"), behaviorNode);
@@ -106,7 +106,7 @@
             new AdvisorMock("Pojo1Advisor", Pojo1.class));
       Constructor constructor = Pojo1.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = advisedData.getBehavior(constructor);
-      BehaviorNodeTest.assertBehaviorNode(constructor, behaviorNode, "new()");
+      BehaviorNodeTest.assertBehaviorNode(constructor, behaviorNode, "new#");
       
       Util.assertCollection(advisedData.searchFields("*"));
       Util.assertCollection(advisedData.searchBehaviors("*"),behaviorNode);
@@ -119,21 +119,21 @@
             new AdvisorMock("Pojo3Advisor", Pojo3.class));
       Method method1 = Pojo3.class.getDeclaredMethod("voidMethod");
       BehaviorNode behaviorNode1 = advisedData.getBehavior(method1);
-      BehaviorNodeTest.assertBehaviorNode(method1, behaviorNode1, "void voidMethod()");
+      BehaviorNodeTest.assertBehaviorNode(method1, behaviorNode1, "void| voidMethod#");
       
       Method method2 = Pojo3.class.getDeclaredMethod("stringMethod");
       BehaviorNode behaviorNode2 = advisedData.getBehavior(method2);
       BehaviorNodeTest.assertBehaviorNode(method2, behaviorNode2,
-            "java.lang.String stringMethod()");
+            "java.lang.String| stringMethod#");
       
       Constructor constructor1 = Pojo3.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode3 = advisedData.getBehavior(constructor1);
-      BehaviorNodeTest.assertBehaviorNode(constructor1, behaviorNode3, "new()");
+      BehaviorNodeTest.assertBehaviorNode(constructor1, behaviorNode3, "new#");
       
       Constructor constructor2 = Pojo3.class.getDeclaredConstructors()[1];
       BehaviorNode behaviorNode4 = advisedData.getBehavior(constructor2);
       BehaviorNodeTest.assertBehaviorNode(constructor2, behaviorNode4,
-            "new(int long )");
+            "new#| int | long  ");
       
       Util.assertCollection(advisedData.searchFields("*"));
       Util.assertCollection(advisedData.searchBehaviors("*"), behaviorNode1,
@@ -147,7 +147,7 @@
       Method method = Pojo1.class.getDeclaredMethod("privateMethod");
       BehaviorNode behaviorNode = advisedData.getBehavior(method);
       BehaviorNodeTest.assertBehaviorNode(method, behaviorNode,
-            "void privateMethod()", "void @" + Arg.class.getName() + "()");
+            "void| privateMethod#", "void| @" + Arg.class.getName() + "#");
       
       Util.assertCollection(advisedData.searchFields("*"));
       Util.assertCollection(advisedData.searchBehaviors("*"), behaviorNode);
@@ -167,16 +167,16 @@
       Constructor constructor = Pojo2.class.getDeclaredConstructor(String.class);
       BehaviorNode behaviorNode1 = advisedData.getBehavior(constructor);
       BehaviorNodeTest.assertBehaviorNode(constructor, behaviorNode1,
-            "new(java.lang.String )",
-            "@" + Thrown.class.getName() + "(java.lang.String )");
+            "new#| java.lang.String  ",
+            "@" + Thrown.class.getName() + "#| java.lang.String  ");
       
       Method method = Pojo2.class.getDeclaredMethod("doSomething", int.class,
             long.class, Collection.class);
       BehaviorNode behaviorNode2 = advisedData.getBehavior(method);
       BehaviorNodeTest.assertBehaviorNode(method, behaviorNode2,
-            Pojo1.class.getName() + " doSomething(int long java.util.Collection )",
-            Pojo1.class.getName() + " @" + Thrown.class.getName() +
-            "(int long java.util.Collection )");
+            Pojo1.class.getName() + "| doSomething#| int | long | java.util.Collection  ",
+            Pojo1.class.getName() + "| @" + Thrown.class.getName() +
+            "#| int | long | java.util.Collection  ");
       
       Util.assertCollection(advisedData.searchFields("*"), fieldNode);
       Util.assertCollection(advisedData.searchBehaviors("*"), behaviorNode1,

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisorMock.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisorMock.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AdvisorMock.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -65,21 +65,37 @@
    
    public Collection<String> getMetaDataTags()
    {
-      return this.metaDataTags;
+      if (!this.metaDataTags.isEmpty())
+      {
+         return this.metaDataTags;
+      }
+      return super.getMetaDataTags();
    }
    
    public Collection<String> getMetaDataTags(Field field)
    {
-      return this.metaDataTags;
+      if (!this.metaDataTags.isEmpty())
+      {
+         return this.metaDataTags;
+      }
+      return super.getMetaDataTags(field);
    }
 
    public Collection<String> getMetaDataTags(Constructor constructor)
    {
-      return this.metaDataTags;
+      if (!this.metaDataTags.isEmpty())
+      {
+         return this.metaDataTags;
+      }
+      return super.getMetaDataTags(constructor);
    }
    
    public Collection<String> getMetaDataTags(Method method)
    {
-      return this.metaDataTags;
+      if (!this.metaDataTags.isEmpty())
+      {
+         return this.metaDataTags;
+      }
+      return super.getMetaDataTags(method);
    }
 }
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,131 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.FieldInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.MethodInfo;
+
+/**
+ * Tests {@link AllSearcher}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class AllSearcherTest extends TestCase
+{
+   private Collection<JoinPointInfo> result;
+   
+   public void setUp()
+   {
+      result = new ArrayList<JoinPointInfo>();
+   }
+
+   public void test() throws Exception
+   {
+      StandardClassNode classNode = new StandardClassNode(Pojo1.class);
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result);
+      
+      Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      AdvisedData advisedData = classNode.getAdvisedData(advisor);
+      Constructor defaultConstructor = Pojo1.class.getDeclaredConstructor();
+      ConstructionInfo defaultConstruction = new ConstructionInfo(advisor, defaultConstructor, 0);
+      advisedData.getBehavior(defaultConstructor).setConstruction(defaultConstruction);
+      
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result);
+      
+      Method privateMethod = Pojo1.class.getDeclaredMethod("privateMethod");
+      JoinPointInfo privateMethodExec = new MethodInfo(advisor, 0l, privateMethod, null);
+      advisedData.getBehavior(privateMethod).setExecution(privateMethodExec);
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, privateMethodExec);
+      
+      Field field = Pojo1.class.getDeclaredField("field");
+      FieldInfo fieldRead = new FieldInfo(advisor, field, 0, true);
+      advisedData.getField(field).setFieldRead(fieldRead);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, privateMethodExec, fieldRead);
+      
+      FieldInfo fieldWrite = new FieldInfo(advisor, field, 0, false);
+      advisedData.getField(field).setFieldWrite(fieldWrite);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, privateMethodExec, fieldRead, fieldWrite);
+      
+      
+      ConstructorInfo defaultConstructorExec = new ConstructorInfo(advisor, defaultConstructor, 0);
+      advisedData.getBehavior(defaultConstructor).setExecution(defaultConstructorExec);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, defaultConstructorExec, privateMethodExec,
+            fieldRead, fieldWrite);
+      
+      MethodByMethodInfo methodByMethod = new MethodByMethodInfo(advisor,
+            Pojo1.class, privateMethod, privateMethod, 0l, 0l, null);
+      advisedData.getBehavior(privateMethod).addCallee(methodByMethod);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, defaultConstructorExec, privateMethodExec,
+            fieldRead, fieldWrite);
+      
+      ConByMethodInfo conByMethod = new ConByMethodInfo(advisor, Pojo1.class,
+            privateMethod, 0l, defaultConstructor, 0l,null, null); 
+      advisedData.getBehavior(privateMethod).addCallee(conByMethod);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, defaultConstructorExec, privateMethodExec,
+           fieldRead, fieldWrite);
+      
+      MethodByConInfo methodByCon = new MethodByConInfo(advisor, Pojo1.class,
+            Pojo1.class, 0, privateMethod, 0l, null);
+      advisedData.getBehavior(defaultConstructor).addCallee(methodByCon);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, defaultConstructorExec, privateMethodExec,
+            fieldRead, fieldWrite);
+      
+      ConByConInfo conByCon = new ConByConInfo(advisor, Pojo1.class, Pojo1.class, 0,
+            defaultConstructor, 0l, null, null); 
+      advisedData.getBehavior(defaultConstructor).addCallee(conByCon);
+      result.clear();
+      AllSearcher.getInstance().search(classNode, result);
+      Util.assertCollection(result, defaultConstructorExec, privateMethodExec,
+            fieldRead, fieldWrite);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllTests.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllTests.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AllTests.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -25,17 +25,29 @@
 import junit.framework.TestSuite;
 
 /**
- * Test suite that contains all test cases of this package.
+ * Test suite that contains all test cases of this package and subpackages.
  * 
- * @author Flavia Rainone
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
 public class AllTests
 {
-
    public static Test suite()
    {
-      TestSuite suite = new TestSuite("Test for org.jboss.aop.joinpoint.graph.tree");
+      TestSuite suite = new TestSuite("Test for org.jboss.aop.joinpoint.graph");
       //$JUnit-BEGIN$
+      suite.addTest(SearchKeyParserTest.suite());
+      suite.addTestSuite(TypedefParserTest.class);
+      suite.addTestSuite(EmptySearchKeyTest.class);
+      suite.addTestSuite(StandardSearchKeyTest.class);
+      suite.addTestSuite(PointcutDelegatorTest.class);
+      suite.addTestSuite(ConjunctiveSearchKeyTest.class);
+      suite.addTestSuite(DisjunctiveSearchKeyTest.class);
+      suite.addTestSuite(SubtypeSearcherTest.class);
+      suite.addTestSuite(FieldSearcherTest.class);
+      suite.addTestSuite(BehaviorSearcherTest.class);
+      suite.addTestSuite(AllSearcherTest.class);
+      suite.addTestSuite(BehaviorJoinPointSearcherTest.class);
+      suite.addTestSuite(CalleeSearcherTest.class);
       suite.addTestSuite(FieldNodeTest.class);
       suite.addTestSuite(BehaviorNodeTest.class);
       suite.addTestSuite(AdvisedDataTest.class);
@@ -46,7 +58,7 @@
       suite.addTestSuite(FieldFilterTest.class);
       suite.addTestSuite(BehaviorFilterTest.class);
       suite.addTestSuite(TypeFilterTest.class);
-      //suite.addTest(org.jboss.aop.joinpoint.graph.tree.AllTests.suite());
+      suite.addTest(org.jboss.aop.joinpoint.graph.tree.AllTests.suite());
       //$JUnit-END$
       return suite;
    }

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AnnPojo.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AnnPojo.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/AnnPojo.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -21,6 +21,8 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
+import org.jboss.util.NotImplementedException;
+
 /**
  * Test scenario.
  * 
@@ -34,7 +36,10 @@
    
    public AnnPojo(int arg1, Pojo2 arg2, long arg3, DummyAnnotationPojo arg4) {}
    
-   public AnnPojo(Pojo2 arg1, DummyAnnotationPojo arg2, long arg3) {}
+   public AnnPojo(Pojo2 arg1, DummyAnnotationPojo arg2, long arg3)
+   {
+      new Pojo1(1);
+   }
    
    public AnnPojo(Pojo2 arg1, int arg2, long arg3) {}
    
@@ -58,7 +63,7 @@
       return null;
    }
    
-   public void method4(Pojo2 arg1, int arg2, long arg3) {}
+   public void method4(Pojo2 arg1, int arg2, long arg3) throws IllegalArgumentException, IllegalStateException {}
    
    public String method5(String arg1, int arg2, long arg3, DummyAnnotationPojo arg4,
          AnyAnnotationPojo arg5)
@@ -96,8 +101,8 @@
 class DummyAnnotationPojo implements DummyInterface
 {
    public void method() {}
-   public void interfaceMethod() {}
-   public DummyAnnotationPojo interfaceMethod2()
+   public void interfaceMethod() throws NotImplementedException {}
+   public DummyAnnotationPojo interfaceMethod2() throws IllegalArgumentException, IllegalStateException
    {
       return null;
    }

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorJoinPointSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorJoinPointSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorJoinPointSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,308 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTException;
+
+/**
+ * Tests searchers that look for joinpoints at behavior nodes.  
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class BehaviorJoinPointSearcherTest extends TestCase
+{
+   private Advisor advisor;
+   private Constructor constructor;
+   private ConstructionInfo constructionInfo;
+   private ConstructorInfo constructorInfo;
+   private ConByConInfo conByConInfo;
+   private MethodByConInfo methodByConInfo;
+   
+   public void setUp() throws Exception
+   {
+      // no need to test with method since the searcher should perform the same
+      advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      constructor = Pojo1.class.getDeclaredConstructor();
+      methodByConInfo = new MethodByConInfo(advisor, Pojo1.class, Pojo1.class,
+            0, Pojo1.class.getDeclaredMethod("privateMethod"), 0l, null);
+      conByConInfo = new ConByConInfo(advisor, Pojo1.class, Pojo1.class, 0,
+            Pojo1.class.getDeclaredConstructor(int.class), 0l, null, null);
+      constructorInfo = new ConstructorInfo(advisor, constructor, 0);
+      constructionInfo = new ConstructionInfo(advisor, constructor, 0);
+   }
+   
+   public void testConstructionSearcher1() throws Exception
+   {
+      assertScenario1(ConstructionSearcher.getInstance(), new JoinPointInfo[][]{
+         {constructionInfo}, {constructionInfo}, {constructionInfo},
+         {constructionInfo}
+      });
+   }
+   
+   public void testConstructionSearcher2() throws Exception
+   {
+      assertScenario2(ConstructionSearcher.getInstance(), new JoinPointInfo[][]{
+         {}, {}, {}, {constructionInfo}
+      });
+   }
+   
+   public void testConstructionSearcher3() throws Exception
+   {
+      assertScenario3(ConstructionSearcher.getInstance(), new JoinPointInfo[][]{
+         {}, {}, {constructionInfo}, {constructionInfo}
+      });
+   }
+   
+   public void testExecutionSearcher1() throws Exception
+   {
+      assertScenario1(ExecutionSearcher.getInstance(), new JoinPointInfo[][]{
+         {}, {constructorInfo}, {constructorInfo}, {constructorInfo}
+      });
+   }
+   
+   public void testExecutionSearcher2() throws Exception
+   {
+      assertScenario2(ExecutionSearcher.getInstance(), new JoinPointInfo[][]{
+         {}, {}, {constructorInfo}, {constructorInfo}
+      });
+   }
+   
+   public void testExecutionSearcher3() throws Exception
+   {
+      assertScenario3(ExecutionSearcher.getInstance(), new JoinPointInfo[][]{
+         {constructorInfo}, {constructorInfo}, {constructorInfo}, {constructorInfo}
+      });
+   }
+   
+   public void testCallSearcher1() throws Exception
+   {
+      Searcher<BehaviorNode> searcher = new CallSearcher();
+      assertScenario1(searcher, new JoinPointInfo[][]{
+         {}, {}, {conByConInfo}, {conByConInfo, methodByConInfo}
+      });
+   }
+   
+   public void testCallSearcher2() throws Exception
+   {
+      Searcher<BehaviorNode> searcher = new CallSearcher();
+      assertScenario2(searcher, new JoinPointInfo[][]{{methodByConInfo},
+            {conByConInfo, methodByConInfo},   {conByConInfo, methodByConInfo},
+            {conByConInfo, methodByConInfo}
+      });
+   }
+   
+   public void testCallSearcher3() throws Exception
+   {
+      Searcher<BehaviorNode> searcher = new CallSearcher();
+      assertScenario3(searcher, new JoinPointInfo[][]{
+         {}, {methodByConInfo}, {methodByConInfo}, {conByConInfo, methodByConInfo}
+      });
+   }
+   
+   public void testCallSearcher4() throws Exception
+   {
+      CallSearcher searcher = new CallSearcher();
+      CalleeSearcher subSearcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setCalleeRestriction(subSearcher);
+      assertScenario1(searcher, new JoinPointInfo[][]{
+         {}, {}, {}, {methodByConInfo}
+      });
+   }
+   
+   public void testCallSearcher5() throws Exception
+   {
+      CallSearcher searcher = new CallSearcher();
+      CalleeSearcher subSearcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setCalleeRestriction(subSearcher);
+      assertScenario2(searcher, new JoinPointInfo[][]{{methodByConInfo},
+            {methodByConInfo}, {methodByConInfo}, {methodByConInfo}
+      });
+   }
+   
+   public void testCallSearcher6() throws Exception
+   {
+      CallSearcher searcher = new CallSearcher();
+      CalleeSearcher subSearcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setCalleeRestriction(subSearcher);
+      assertScenario3(searcher, new JoinPointInfo[][]{
+         {}, {methodByConInfo}, {methodByConInfo}, {methodByConInfo}
+      });
+   }
+   
+   public void testAllBehaviorSearcher1() throws Exception
+   {
+      assertScenario1(AllBehaviorSearcher.getInstance(), new JoinPointInfo[][]{
+         {constructionInfo}, {constructionInfo, constructorInfo},
+         {constructionInfo, constructorInfo, conByConInfo},
+         {constructionInfo, constructorInfo, conByConInfo, methodByConInfo}
+      });
+   }
+   
+   public void testAllBehaviorSearcher2() throws Exception
+   {
+      assertScenario2(AllBehaviorSearcher.getInstance(), new JoinPointInfo[][]{
+         {methodByConInfo}, {methodByConInfo, conByConInfo},
+         {methodByConInfo, conByConInfo, constructorInfo},
+         {methodByConInfo, conByConInfo, constructorInfo, constructionInfo}
+      });
+   }
+   
+   public void testAllBehaviorSearcher3() throws Exception
+   {
+      assertScenario3(AllBehaviorSearcher.getInstance(), new JoinPointInfo[][]{
+         {constructorInfo}, {constructorInfo, methodByConInfo},
+         {constructorInfo, methodByConInfo, constructionInfo},
+         {constructorInfo, methodByConInfo, constructionInfo, conByConInfo}
+      });
+   }
+   
+   // Scenario 1, composed of 4 stages, in each one an info is added. The infos
+   // are added in the following order: constructionInfo, constructorInfo,
+   // conByConInfo, and methodByConInfo 
+   public void assertScenario1(Searcher<BehaviorNode> searcher,
+         JoinPointInfo[][] results) throws Exception
+   {
+      assertEquals(4, results.length);
+      BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
+      // search
+      Collection<JoinPointInfo> result = new HashSet<JoinPointInfo>();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result);
+      // add construction
+      behaviorNode.setConstruction(constructionInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[0]);
+      // add execution
+      behaviorNode.setExecution(constructorInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[1]);
+      // add callee1
+      behaviorNode.addCallee(conByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[2]);
+      // add callee2
+      behaviorNode.addCallee(methodByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[3]);
+   }
+   
+   // Scenario 2, composed of 4 stages, in each one an info is added. The infos
+   // are added in the following order: methodByConInfo, conByConInfo,
+   // constructorInfo and constructionInfo
+   public void assertScenario2(Searcher<BehaviorNode> searcher,
+         JoinPointInfo[][] results) throws Exception
+   {
+      assertEquals(4, results.length);
+      BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
+      // search
+      Collection<JoinPointInfo> result = new HashSet<JoinPointInfo>();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result);
+      // add callee1
+      behaviorNode.addCallee(methodByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[0]);
+      // add callee2
+      behaviorNode.addCallee(conByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[1]);
+      // add execution
+      behaviorNode.setExecution(constructorInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[2]);
+      // add construction
+      behaviorNode.setConstruction(constructionInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[3]);
+   }
+   
+   // Scenario 3, composed of 4 stages, in each one an info is added. The infos
+   // are added in the following order: constructorInfo, methodByConInfo,
+   // constructionInfo, and conByConInfo
+   public void assertScenario3(Searcher<BehaviorNode> searcher,
+         JoinPointInfo[][] results) throws Exception
+   {
+      assertEquals(4, results.length);
+      BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
+      // search
+      Collection<JoinPointInfo> result = new HashSet<JoinPointInfo>();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result);
+      // add execution
+      behaviorNode.setExecution(constructorInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[0]);
+      // add callee1
+      behaviorNode.addCallee(methodByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[1]);
+      // add construction
+      behaviorNode.setConstruction(constructionInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[2]);
+      // add callee2
+      behaviorNode.addCallee(conByConInfo);
+      // search
+      result.clear();
+      searcher.search(behaviorNode, result);
+      Util.assertCollection(result, results[3]);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorNodeTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorNodeTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorNodeTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -45,7 +45,7 @@
 import org.jboss.aop.advice.Interceptor;
 
 /**
- * Tests {@code BehaviorNode}..
+ * Tests {@code BehaviorNode}.
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
@@ -71,7 +71,7 @@
       Constructor constructor = Pojo1.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo1Advisor", Pojo1.class), constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
    }
    
    public void testConstructorNodeCreation2() throws Exception
@@ -79,7 +79,7 @@
       Constructor constructor = Pojo3.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
    }
    
    public void testConstructorNodeCreation3() throws Exception
@@ -87,7 +87,7 @@
       Constructor constructor = Pojo3.class.getDeclaredConstructors()[1];
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new(int long )");
+      assertBehaviorNode(constructor, behaviorNode, "new#| int | long  ");
    }
    
    public void testConstructorNodeCreation4() throws Exception
@@ -95,7 +95,7 @@
       Constructor constructor = Pojo3.class.getDeclaredConstructors()[2];
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new(int java.lang.String )");
+      assertBehaviorNode(constructor, behaviorNode, "new#| int | java.lang.String  ");
    }
    
    public void testConstructorNodeCreationWithMetaData1() throws Exception
@@ -104,9 +104,9 @@
       BehaviorNode behaviorNode = new BehaviorNode(new AdvisorMock("Pojo1Advisor",
             Pojo1.class, "one.package.with.Annotation", "markup.Ann",
             "your.package.Secure"), constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()",
-            "@one.package.with.Annotation()", "@markup.Ann()",
-            "@your.package.Secure()");
+      assertBehaviorNode(constructor, behaviorNode, "new#",
+            "@one.package.with.Annotation#", "@markup.Ann#",
+            "@your.package.Secure#");
    }
    
    public void testConstructorNodeCreationWithMetaData2() throws Exception
@@ -115,10 +115,10 @@
       BehaviorNode behaviorNode = new BehaviorNode(new AdvisorMock("Pojo1Advisor",
             Pojo1.class, "JustAnnotation", "any.Ann", "your.markup.Secure"),
             constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new(int java.lang.String )",
-            "@JustAnnotation(int java.lang.String )",
-            "@any.Ann(int java.lang.String )",
-            "@your.markup.Secure(int java.lang.String )");
+      assertBehaviorNode(constructor, behaviorNode, "new#| int | java.lang.String  ",
+            "@JustAnnotation#| int | java.lang.String  ",
+            "@any.Ann#| int | java.lang.String  ",
+            "@your.markup.Secure#| int | java.lang.String  ");
    }
    
    public void testConstructorNodeWithExecution() throws Exception
@@ -126,7 +126,7 @@
       Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
       Constructor constructor = Pojo1.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
       ConstructorInfo info = new ConstructorInfo(advisor, constructor, 0);
       behaviorNode.setExecution(info);
       assertTrue(behaviorNode.hasExecution());
@@ -139,7 +139,7 @@
       Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
       Constructor constructor = Pojo1.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
       ConstructionInfo info = new ConstructionInfo(advisor, constructor, 0);
       behaviorNode.setConstruction(info);
       assertTrue(behaviorNode.hasConstruction());
@@ -152,7 +152,7 @@
       Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
       Constructor constructor = Pojo1.class.getDeclaredConstructors()[0];
       BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
       ConstructorInfo executionInfo = new ConstructorInfo(advisor, constructor, 0);
       ConstructionInfo constructionInfo = new ConstructionInfo(advisor, constructor, 0);
       behaviorNode.setExecution(executionInfo);
@@ -168,7 +168,7 @@
       Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
       Constructor constructor = Pojo1.class.getDeclaredConstructor();
       BehaviorNode behaviorNode = new BehaviorNode(advisor, constructor);
-      assertBehaviorNode(constructor, behaviorNode, "new()");
+      assertBehaviorNode(constructor, behaviorNode, "new#");
       
       Method calleeMethod = Pojo1.class.getDeclaredMethod("privateMethod");
       // callee
@@ -177,7 +177,7 @@
             0, calleeMethod, 0L, new Interceptor[0]);
       behaviorNode.addCallee(info1);
       Collection<JoinPointInfo> calleesFound = new ArrayList<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo1.class.getName() + ".void privateMethod()",
+      behaviorNode.searchCallees(Pojo1.class.getName() + "|void| privateMethod#",
             calleesFound);
       Util.assertCollection(calleesFound, info1);
       
@@ -192,13 +192,13 @@
             calleeConstructor, 0L, null, new Interceptor[0]);
       behaviorNode.addCallee(info2);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo1.class.getName() + ".new(int )", calleesFound);
+      behaviorNode.searchCallees(Pojo1.class.getName() + "|new#| int  ", calleesFound);
       Util.assertCollection(calleesFound, info2);
       calleesFound.clear();
       behaviorNode.searchCallees("*", calleesFound);
       Util.assertCollection(calleesFound, info1, info2);
       calleesFound.clear();
-      behaviorNode.searchCallees("*Pojo1.*", calleesFound);
+      behaviorNode.searchCallees("*Pojo1|*", calleesFound);
       Util.assertCollection(calleesFound, info1, info2);
    }
    
@@ -207,7 +207,7 @@
       Advisor advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
       Constructor callerConstructor = Pojo4.class.getDeclaredConstructor();
       BehaviorNode behaviorNode = new BehaviorNode(advisor, callerConstructor);
-      assertBehaviorNode(callerConstructor, behaviorNode, "new()");
+      assertBehaviorNode(callerConstructor, behaviorNode, "new#");
       // insert callee
       Constructor callee= Pojo5.class.getDeclaredConstructor(Collection.class);
       ConByConInfo info = new ConByConInfo(advisor,
@@ -216,8 +216,8 @@
       behaviorNode.addCallee(info);
       // assert search
       Collection<JoinPointInfo> calleesFound = new HashSet<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".new(" + 
-            Collection.class.getName() + " )", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|new#| " + 
+            Collection.class.getName() + "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
       behaviorNode.searchCallees("*", calleesFound);
@@ -226,18 +226,18 @@
       behaviorNode.searchCallees("*@*", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".new(" + 
-            Collection.class.getName() + " )", calleesFound);
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|new#| " + 
+            Collection.class.getName() + "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".@" +
-            AnyAnnotation.class.getName() + '(' + Collection.class.getName() +
-            " )", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|@" +
+            AnyAnnotation.class.getName() + "#| " + Collection.class.getName() +
+            "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".@" +
-            AnyAnnotation.class.getName() + '(' + Collection.class.getName() +
-            " )", calleesFound);
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|@" +
+            AnyAnnotation.class.getName() + "#| " + Collection.class.getName() +
+            "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
    }
    
@@ -246,7 +246,7 @@
       Advisor advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
       Constructor callerConstructor= Pojo4.class.getDeclaredConstructor(int.class);
       BehaviorNode behaviorNode = new BehaviorNode(advisor, callerConstructor);
-      assertBehaviorNode(callerConstructor, behaviorNode, "new(int )");
+      assertBehaviorNode(callerConstructor, behaviorNode, "new#| int  ");
       Method callee = Pojo5.class.getDeclaredMethod("calledByCon");
       // insert callee
       MethodByConInfo info = new MethodByConInfo(advisor,
@@ -255,7 +255,7 @@
       behaviorNode.addCallee(info);
       // assert search
       Collection<JoinPointInfo> calleesFound = new HashSet<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".void calledByCon()",
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|void| calledByCon#",
             calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
@@ -263,15 +263,15 @@
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
       behaviorNode.searchCallees('@' + Aspect.class.getName() +
-            ".void calledByCon()", calleesFound);
+            "|void| calledByCon#", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".void @" +
-            Bind.class.getName() + "()", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|void| @" +
+            Bind.class.getName() + "#", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".void @" +
-            Bind.class.getName() + "()", calleesFound);
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|void| @" +
+            Bind.class.getName() + "#", calleesFound);
       Util.assertCollection(calleesFound, info);
    }
    
@@ -283,73 +283,73 @@
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo1Advisor", Pojo1.class), method);
       assertBehaviorNode(method, behaviorNode,
-            "void method1(java.lang.String java.lang.String )");
+            "void| method1#| java.lang.String | java.lang.String  ");
    }
    
    public void testMethodNodeCreation2() throws Exception
    {
-      Method method = Pojo3.class.getMethod("voidMethod", new Class[]{});
+      Method method = Pojo3.class.getMethod("voidMethod");
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), method);
-      assertBehaviorNode(method, behaviorNode, "void voidMethod()");
+      assertBehaviorNode(method, behaviorNode, "void| voidMethod#");
    }
    
    public void testMethodNodeCreation3() throws Exception
    {
-      Method method = Pojo3.class.getMethod("stringMethod", new Class[]{});
+      Method method = Pojo3.class.getMethod("stringMethod");
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), method);
-      assertBehaviorNode(method, behaviorNode, "java.lang.String stringMethod()");
+      assertBehaviorNode(method, behaviorNode, "java.lang.String| stringMethod#");
    }
    
    public void testMethodNodeCreation4() throws Exception
    {
-      Method method = Pojo3.class.getMethod("someMethod", new Class[]{int.class, long.class});
+      Method method = Pojo3.class.getMethod("someMethod", int.class, long.class);
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), method);
-      assertBehaviorNode(method, behaviorNode, "void someMethod(int long )");
+      assertBehaviorNode(method, behaviorNode, "void| someMethod#| int | long  ");
    }
    
    public void testMethodNodeCreation5() throws Exception
    {
-      Method method = Pojo3.class.getMethod("someMethod", new Class[]{String.class, long.class});
+      Method method = Pojo3.class.getMethod("someMethod", String.class, long.class);
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class), method);
       assertBehaviorNode(method, behaviorNode,
-            "java.lang.String someMethod(java.lang.String long )");
+            "java.lang.String| someMethod#| java.lang.String | long  ");
    }
    
    public void testMethodNodeCreationWithMetaData1() throws Exception
    {
-      Method method = Pojo1.class.getMethod("method1", new Class[]{String.class, String.class});
+      Method method = Pojo1.class.getMethod("method1", String.class, String.class);
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo1Advisor", Pojo1.class, "java.lang.Annotation",
                   "other.MetaData", "your.package.Secure"), method);
       assertBehaviorNode(method, behaviorNode,
-            "void method1(java.lang.String java.lang.String )",
-            "void @java.lang.Annotation(java.lang.String java.lang.String )",
-            "void @other.MetaData(java.lang.String java.lang.String )",
-            "void @your.package.Secure(java.lang.String java.lang.String )");
+            "void| method1#| java.lang.String | java.lang.String  ",
+            "void| @java.lang.Annotation#| java.lang.String | java.lang.String  ",
+            "void| @other.MetaData#| java.lang.String | java.lang.String  ",
+            "void| @your.package.Secure#| java.lang.String | java.lang.String  ");
    }
    
    public void testMethodNodeCreationWithMetaData2() throws Exception
    {
-      Method method = Pojo3.class.getMethod("stringMethod", new Class[]{});
+      Method method = Pojo3.class.getMethod("stringMethod");
       BehaviorNode behaviorNode = new BehaviorNode(
             new AdvisorMock("Pojo3Advisor", Pojo3.class, "java.lang.AnyAnnotation",
                   "other.MetaData", "your.markup.Secure"), method);
-      assertBehaviorNode(method, behaviorNode, "java.lang.String stringMethod()",
-            "java.lang.String @java.lang.AnyAnnotation()",
-            "java.lang.String @other.MetaData()",
-            "java.lang.String @your.markup.Secure()");
+      assertBehaviorNode(method, behaviorNode, "java.lang.String| stringMethod#",
+            "java.lang.String| @java.lang.AnyAnnotation#",
+            "java.lang.String| @other.MetaData#",
+            "java.lang.String| @your.markup.Secure#");
    }
    
    public void testMethodNodeWithExecution() throws Exception
    {
       Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
-      Method method = Pojo1.class.getDeclaredMethod("privateMethod", new Class[0]);
+      Method method = Pojo1.class.getDeclaredMethod("privateMethod");
       BehaviorNode behaviorNode = new BehaviorNode(advisor, method);
-      assertBehaviorNode(method, behaviorNode, "void privateMethod()");
+      assertBehaviorNode(method, behaviorNode, "void| privateMethod#");
       MethodInfo methodInfo = new MethodInfo(advisor, 0L, method, method);
       behaviorNode.setExecution(methodInfo);
       assertTrue(behaviorNode.hasExecution());
@@ -364,15 +364,15 @@
             String.class);
       BehaviorNode behaviorNode = new BehaviorNode(advisor, callerMethod);
       assertBehaviorNode(callerMethod, behaviorNode,
-            "void method1(java.lang.String java.lang.String )");
-      Method calleeMethod = Pojo1.class.getDeclaredMethod("privateMethod", new Class[0]);
+            "void| method1#| java.lang.String | java.lang.String  ");
+      Method calleeMethod = Pojo1.class.getDeclaredMethod("privateMethod");
       // callee
       MethodByMethodInfo info1 = new MethodByMethodInfo(advisor,
             calleeMethod.getDeclaringClass(), calleeMethod, callerMethod, 0L, 0L,
             new Interceptor[0]);
       behaviorNode.addCallee(info1);
       Collection<JoinPointInfo> calleesFound = new ArrayList<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo1.class.getName() + ".void privateMethod()",
+      behaviorNode.searchCallees(Pojo1.class.getName() + "|void| privateMethod#",
             calleesFound);
       Util.assertCollection(calleesFound, info1);
       calleesFound.clear();
@@ -386,7 +386,7 @@
             new Interceptor[0]);
       behaviorNode.addCallee(info2);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo1.class.getName() + ".new(int )", calleesFound);
+      behaviorNode.searchCallees(Pojo1.class.getName() + "|new#| int  ", calleesFound);
       Util.assertCollection(calleesFound, info2);
       calleesFound.clear();
       behaviorNode.searchCallees("*", calleesFound);
@@ -401,7 +401,7 @@
       Advisor advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
       Method callerMethod = Pojo4.class.getMethod("callConstructor");
       BehaviorNode behaviorNode = new BehaviorNode(advisor, callerMethod);
-      assertBehaviorNode(callerMethod, behaviorNode, "void callConstructor()");
+      assertBehaviorNode(callerMethod, behaviorNode, "void| callConstructor#");
       // insert callee
       Constructor callee= Pojo5.class.getDeclaredConstructor(Pojo3.class);
       ConByMethodInfo info = new ConByMethodInfo(advisor,
@@ -410,8 +410,8 @@
       behaviorNode.addCallee(info);
       // assert search
       Collection<JoinPointInfo> calleesFound = new HashSet<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".new(" + 
-            Pojo3.class.getName() + " )", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|new#| " + 
+            Pojo3.class.getName() + "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
       behaviorNode.searchCallees("*", calleesFound);
@@ -420,16 +420,16 @@
       behaviorNode.searchCallees("*@*", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".new(" + 
-            Pojo3.class.getName() + " )", calleesFound);
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|new#| " + 
+            Pojo3.class.getName() + "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".new(" +
-            Pojo3.class.getName() + " )", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|new#| " +
+            Pojo3.class.getName() + "  ", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".@" +
-            Deprecated.class.getName() + '(' + Pojo3.class.getName() + " )",
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|@" +
+            Deprecated.class.getName() + "#| " + Pojo3.class.getName() + "  ",
             calleesFound);
       Util.assertCollection(calleesFound, info);
    }
@@ -439,7 +439,7 @@
       Advisor advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
       Method callerMethod = Pojo4.class.getMethod("callMethod");
       BehaviorNode behaviorNode = new BehaviorNode(advisor, callerMethod);
-      assertBehaviorNode(callerMethod, behaviorNode, "void callMethod()");
+      assertBehaviorNode(callerMethod, behaviorNode, "void| callMethod#");
       Method callee = Pojo5.class.getDeclaredMethod("calledByMethod");
       // insert callee
       MethodByMethodInfo info = new MethodByMethodInfo(advisor,
@@ -448,7 +448,7 @@
       behaviorNode.addCallee(info);
       // assert search
       Collection<JoinPointInfo> calleesFound = new HashSet<JoinPointInfo>();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".void calledByMethod()",
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|void| calledByMethod#",
             calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
@@ -456,15 +456,15 @@
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
       behaviorNode.searchCallees('@' + Aspect.class.getName() +
-            ".void calledByMethod()", calleesFound);
+            "|void| calledByMethod#", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees(Pojo5.class.getName() + ".void @" +
-            Mixin.class.getName() + "()", calleesFound);
+      behaviorNode.searchCallees(Pojo5.class.getName() + "|void| @" +
+            Mixin.class.getName() + "#", calleesFound);
       Util.assertCollection(calleesFound, info);
       calleesFound.clear();
-      behaviorNode.searchCallees('@' + Aspect.class.getName() + ".void @" +
-            Mixin.class.getName() + "()", calleesFound);
+      behaviorNode.searchCallees('@' + Aspect.class.getName() + "|void| @" +
+            Mixin.class.getName() + "#", calleesFound);
       Util.assertCollection(calleesFound, info);
    }
    

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,742 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Modifier;
+
+import org.jboss.aop.joinpoint.graph.BehaviorSearcher.SearchType;
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+
+/**
+ * Tests {@link SearchKeyParser} on behavior pointcut expressions.
+ * Behaviors with complex parameter lists are tested on
+ * {@link ParamSearchKeyParserTest}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class BehaviorSearchKeyParserTest extends AbstractSearchKeyParserTest
+{
+   public void testSimpleConstruction() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "construction(Pojo->new())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo", "new#",
+            SearchType.CONSTRUCTION);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredConstruction() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "construction(Pojo->new(.., @TestAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo", "new#*||",
+            SearchType.CONSTRUCTION);
+      assertDescParamFilter(filter, null, "@TestAnnotation");
+   }
+   
+   
+   public void testAnnotatedConstruction() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "construction(Pojo->@TestAnnotation())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "@TestAnnotation#", SearchType.CONSTRUCTION);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredAnnotatedConstruction() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "construction(Pojo->@TestAnnotation($instanceof{@Pojo}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "@TestAnnotation#||", SearchType.CONSTRUCTION);
+      assertAscParamFilter(filter, "$instanceof{@Pojo}");
+   }
+   
+   public void testSimpleConsExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(Pojo->new(*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo", "new#||",
+            SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredConsExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(Pojo->new(*, int, @TestAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "new#||| int ||", SearchType.EXECUTION);
+      assertAscParamFilter(filter, null, null, "@TestAnnotation");
+   }
+   
+   public void testAnnotatedConsExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(Pojo->@AnyAnnotation(*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "@AnyAnnotation#||", SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testSimpleMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(public void Pojo->method(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int  ", SearchType.EXECUTION, attribute);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(public void Pojo->method(int, org.jboss.*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||", SearchType.EXECUTION, attribute);
+      assertAscParamFilter(filter, null, "org.jboss.*");
+   }
+   
+   public void testImplementedMethodExecution1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(public void Pojo->$implements{Interface}(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| *#| int  ", SearchType.EXECUTION, attribute);
+      assertImplementFilter(filter, true, "Interface");
+   }
+   
+   public void testImplementedMethodExecution2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(public void Pojo->$implementing{Interface}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| *#", SearchType.EXECUTION, attribute);
+      assertImplementFilter(filter, false, "Interface");
+   }
+   
+   public void testParamFilteredImplementedMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(public void Pojo->$implementing{Interface}(a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| *#||", SearchType.EXECUTION, attribute);
+      assertImplementFilter(getConjSubFilter1(filter), false, "Interface");
+      assertAscParamFilter(getConjSubFilter2(filter), "a*");
+   }
+
+   public void testAnnotatedMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(public void Pojo->@TestAnnotation(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| @TestAnnotation#| int  ", SearchType.EXECUTION, attribute);
+      assertNull(filter);
+   }
+   
+   public void testAnnotatedMethodExecution2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(void Pojo->@org.MyAnnotation())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| @org.MyAnnotation#", SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredAnnotatedMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(public void Pojo->@TestAnnotation($instanceof{java.lang.Object}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| @TestAnnotation#||", SearchType.EXECUTION, attribute);
+      assertAscParamFilter(filter, "$instanceof{java.lang.Object}");
+   }
+   
+   public void testTypedefMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->method(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| method#| int  ", SearchType.EXECUTION);
+      assertReturnTypeFilter(filter, "$typedef{typedef}");
+   }
+   
+   public void testTypedefImplementedMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->$implementing{org.jboss.Interface}" +
+            "(java.lang.String, java.lang.String))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| *#| java.lang.String | java.lang.String  ",
+            SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$typedef{typedef}");
+      assertImplementFilter(getConjSubFilter2(filter), false, "org.jboss.Interface");
+   }
+   
+   public void testParamFilteredTypedefMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->method(int*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| method#||", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$typedef{typedef}");
+      assertAscParamFilter(getConjSubFilter2(filter), "int*");
+   }
+   
+   public void testParamFilteredTypedefImplementedMethodExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->$implements{P*}(int*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| *#||", SearchType.EXECUTION);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "$typedef{typedef}");
+      assertImplementFilter(getConjSubFilter2(subFilter), true, "P*");
+      assertAscParamFilter(getConjSubFilter2(filter), "int*");
+   }
+   
+   public void testInstanceOfMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution($instanceof{package.MyInterface} Pojo->method(java.lang.String, long))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#| java.lang.String | long  ", SearchType.EXECUTION);
+      assertReturnTypeFilter(filter, "$instanceof{package.MyInterface}");
+   }
+   
+   public void testInstanceOfImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution($instanceof{package.MyInterface} Pojo->$implementing{P*}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{package.MyInterface}");
+      assertImplementFilter(getConjSubFilter2(filter), false, "P*");
+   }
+   
+   public void testParamFilteredInstanceOfMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution($instanceof{package.MyInterface} Pojo->method(.., java.lang.String, $typedef{typedef}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#|* java.lang.String | TypedefClass  ", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter),
+            "$instanceof{package.MyInterface}");
+      assertDescParamFilter(getConjSubFilter2(filter), null, null, "$typedef{typedef}");
+   }
+   
+   public void testParamFilteredInstanceOfImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution($instanceof{package.MyInterface} Pojo->$implements{*}(.., java.lang.String, $typedef{typedef}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#|* java.lang.String | TypedefClass  ", SearchType.EXECUTION);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter),
+            "$instanceof{package.MyInterface}");
+      assertImplementFilter(getConjSubFilter2(subFilter), true, "*");
+      assertDescParamFilter(getConjSubFilter2(filter), null, null, "$typedef{typedef}");
+   }
+   
+   public void testAnnotatedTypeMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.MyAnnotation Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#", SearchType.EXECUTION);
+      assertReturnTypeFilter(filter, "@org.MyAnnotation");
+   }
+   
+   public void testAnnotatedTypeImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.MyAnnotation Pojo->$implementing{@AnyAnnotation}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.MyAnnotation");
+      assertImplementFilter(getConjSubFilter2(filter), false, "@AnyAnnotation");
+   }
+   
+   public void testParamFilteredAnnotatedTypeMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.MyAnnotation Pojo->method(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#||*||", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.MyAnnotation");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testParamFilteredAnnotatedTypeImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.MyAnnotation Pojo->$implements{@AnyAnnotation}(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#||*||", SearchType.EXECUTION);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "@org.MyAnnotation");
+      assertImplementFilter(getConjSubFilter2(subFilter), true, "@AnyAnnotation");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testInstanceOfAnnotatedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution($instanceof{@org.MyAnnotation} Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| method#", SearchType.EXECUTION);
+      assertReturnTypeFilter(filter, "$instanceof{@org.MyAnnotation}");
+   }
+   
+   public void testInstanceOfAnnotatedImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution($instanceof{@org.MyAnnotation} Pojo->$implementing{Interface}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| *#", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{@org.MyAnnotation}");
+      assertImplementFilter(getConjSubFilter2(filter), false, "Interface");
+   }
+   
+   public void testParamFilteredInstanceOfAnnotatedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution($instanceof{@org.MyAnnotation} Pojo->method(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| method#||*||", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{@org.MyAnnotation}");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testParamFilteredInstanceOfAnnotatedImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution($instanceof{@org.MyAnnotation} Pojo->$implements{*}(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| *#||*||", SearchType.EXECUTION);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "$instanceof{@org.MyAnnotation}");
+      assertImplementFilter(getConjSubFilter2(subFilter), true, "*");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testParamFilteredAnnotatedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.PojoAnnotation Pojo->method(.., a*, .., a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#*||*||*||", SearchType.EXECUTION);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.PojoAnnotation");
+      assertFullParamFilter(getConjSubFilter2(filter), "..", "a*", "..", "a*", "..",
+            "a*");
+   }
+   
+   public void testParamFilteredAnnotatedImplementedMethod() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(@org.PojoAnnotation Pojo->$implementing{AnyInterface}(.., a*, .., a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#*||*||*||", SearchType.EXECUTION);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "@org.PojoAnnotation");
+      assertImplementFilter(getConjSubFilter2(subFilter), false, "AnyInterface");
+      assertFullParamFilter(getConjSubFilter2(filter), "..", "a*", "..", "a*", "..",
+            "a*");
+   }
+   
+   public void testSimpleConsCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(Pojo->new(*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo", "new#||",
+            SearchType.CALL);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredConsCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(Pojo->new(*, .., int, @TestAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "new#||* int ||", SearchType.CALL);
+      assertDescParamFilter(filter, null, null, null, "@TestAnnotation");
+   }
+   
+   public void testAnnotatedConsCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(Pojo->@AnyAnnotation(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "@AnyAnnotation#| int  ", SearchType.CALL);
+      assertNull(filter);
+   }
+   
+   public void testSimpleMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(private !static void Pojo->method(org.jboss.aop.Pojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute1 = new ASTAttribute(0);
+      attribute1.setValue(Modifier.PRIVATE);
+      ASTAttribute attribute2 = new ASTAttribute(0);
+      attribute2.setValue(Modifier.STATIC);
+      attribute2.not = true;
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| org.jboss.aop.Pojo  ",
+            SearchType.CALL, attribute1, attribute2);
+      assertNull(filter);
+   }
+   
+   public void testImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(protected !final void Pojo->$implements{java.io.Serializable}(org.jboss.aop.Pojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute1 = new ASTAttribute(0);
+      attribute1.setValue(Modifier.PROTECTED);
+      ASTAttribute attribute2 = new ASTAttribute(0);
+      attribute2.setValue(Modifier.FINAL);
+      attribute2.not = true;
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| *#| org.jboss.aop.Pojo  ",
+            SearchType.CALL, attribute1, attribute2);
+      assertImplementFilter(filter,true, "java.io.Serializable");
+   }
+   
+   public void testParamFilteredMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void Pojo->method(int, org.jboss.*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||", SearchType.CALL);
+      assertAscParamFilter(filter, null, "org.jboss.*");
+   }
+   
+   public void testParamFilteredImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void Pojo->$implementing{java.util.Comparable}(int, org.jboss.*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| *#| int ||", SearchType.CALL);
+      assertImplementFilter(getConjSubFilter1(filter), false, "java.util.Comparable");
+      assertAscParamFilter(getConjSubFilter2(filter), null, "org.jboss.*");
+   }
+
+   public void testAnnotatedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void Pojo->@TestAnnotation(int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| @TestAnnotation#| int  ", SearchType.CALL);
+      assertNull(filter);
+   }
+   
+   public void testParamFilteredAnnotatedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(int Pojo->@TestAnnotation($instanceof{@Annotation}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "int| @TestAnnotation#||", SearchType.CALL);
+      assertAscParamFilter(filter, "$instanceof{@Annotation}");
+   }
+   
+   public void testTypedefMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode($typedef{typedef} Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| method#", SearchType.CALL);
+      assertReturnTypeFilter(filter, "$typedef{typedef}");
+   }
+   
+   public void testTypedefImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode($typedef{typedef} Pojo->$implements{java.*}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| *#", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$typedef{typedef}");
+      assertImplementFilter(getConjSubFilter2(filter), true, "java.*");
+   }
+   
+   public void testParamFilteredTypedefMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->method(@Annotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| method#||", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$typedef{typedef}");
+      assertAscParamFilter(getConjSubFilter2(filter), "@Annotation");
+   }
+   
+   public void testParamFilteredTypedefImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution($typedef{typedef} Pojo->$implementing{*}(@Annotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "TypedefClass| *#||", SearchType.CALL);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "$typedef{typedef}");
+      assertImplementFilter(getConjSubFilter2(subFilter), false, "*");
+      assertAscParamFilter(getConjSubFilter2(filter), "@Annotation");
+   }
+   
+   public void testInstanceOfMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "withincode(" +
+            "$instanceof{package.MyInterface} Pojo->method(java.util.Collection))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#| java.util.Collection  ", SearchType.CALL);
+      assertReturnTypeFilter(filter, "$instanceof{package.MyInterface}");
+   }
+   
+   public void testInstanceOfImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "withincode(" +
+            "$instanceof{package.MyInterface} Pojo->$implements{DummyInterface}(java.util.Collection))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#| java.util.Collection  ", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{package.MyInterface}");
+      assertImplementFilter(getConjSubFilter2(filter), true, "DummyInterface");
+   }
+   
+   public void testParamFilteredInstanceOfMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "withincode(" +
+            "$instanceof{package.MyInterface} Pojo->method(.., int, $typedef{typedef}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#|* int | TypedefClass  ", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter),
+            "$instanceof{package.MyInterface}");
+      assertDescParamFilter(getConjSubFilter2(filter), null, null, "$typedef{typedef}");
+   }
+   
+   public void testParamFilteredInstanceOfImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "withincode(" +
+            "$instanceof{package.MyInterface} Pojo->$implementing{Dummy*}(.., int, $typedef{typedef}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#|* int | TypedefClass  ", SearchType.CALL);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter),
+            "$instanceof{package.MyInterface}");
+      assertImplementFilter(getConjSubFilter2(subFilter), false, "Dummy*");
+      assertDescParamFilter(getConjSubFilter2(filter), null, null, "$typedef{typedef}");
+   }
+   
+   public void testAnnotatedTypeMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.MyAnnotation Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#", SearchType.CALL);
+      assertReturnTypeFilter(filter, "@org.MyAnnotation");
+   }
+   
+   public void testAnnotatedTypeImplemnetedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.MyAnnotation Pojo->$implements{java.security.Principal}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.MyAnnotation");
+      assertImplementFilter(getConjSubFilter2(filter), true, "java.security.Principal");
+   }
+   
+   public void testParamFilteredAnnotatedTypeMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.MyAnnotation Pojo->method(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#||*||", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.MyAnnotation");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testParamFilteredAnnotatedTypeImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.MyAnnotation Pojo->$implementing{java.security.*}(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#||*||", SearchType.CALL);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "@org.MyAnnotation");
+      assertImplementFilter(getConjSubFilter2(subFilter), false, "java.security.*");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testInstanceOfAnnotatedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode($instanceof{@org.MyAnnotation} Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| method#", SearchType.CALL);
+      assertReturnTypeFilter(filter, "$instanceof{@org.MyAnnotation}");
+   }
+   
+   public void testInstanceOfAnnotatedImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode($instanceof{@org.MyAnnotation} Pojo->$implements{Interface*}())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| *#", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{@org.MyAnnotation}");
+      assertImplementFilter(getConjSubFilter2(filter), true, "Interface*");
+   }
+   
+   public void testParamFilteredInstanceOfAnnotatedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode($instanceof{@org.MyAnnotation} Pojo->method(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| method#||*||", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "$instanceof{@org.MyAnnotation}");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testParamFilteredInstanceOfAnnotatedImplementedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode($instanceof{@org.MyAnnotation} Pojo->$implementing{org.*Interface}(a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+         "*| *#||*||", SearchType.CALL);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "$instanceof{@org.MyAnnotation}");
+      assertImplementFilter(getConjSubFilter2(subFilter), false, "org.*Interface");
+      BehaviorFilter paramFilter = getConjSubFilter2(filter);
+      assertAscParamFilter(getConjSubFilter1(paramFilter), "a*", null, null);
+      assertDescParamFilter(getConjSubFilter2(paramFilter), null, null, "a*");
+   }
+   
+   public void testFullParamFilteredAnnotatedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.PojoAnnotation Pojo->method(.., a*, .., a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| method#*||*||*||", SearchType.CALL);
+      assertReturnTypeFilter(getConjSubFilter1(filter), "@org.PojoAnnotation");
+      assertFullParamFilter(getConjSubFilter2(filter), "..", "a*", "..", "a*", "..",
+            "a*");
+   }
+   
+   public void testFullParamFilteredAnnotatedImplemenetedMethodCaller() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "withincode(@org.PojoAnnotation Pojo->$implements{java.rmi.Remote}(.., a*, .., a*, .., a*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "*| *#*||*||*||", SearchType.CALL);
+      BehaviorFilter subFilter = getConjSubFilter1(filter);
+      assertReturnTypeFilter(getConjSubFilter1(subFilter), "@org.PojoAnnotation");
+      assertImplementFilter(getConjSubFilter2(subFilter), true, "java.rmi.Remote");
+      assertFullParamFilter(getConjSubFilter2(filter), "..", "a*", "..", "a*", "..",
+            "a*");
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,1699 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.CallerConstructorInfo;
+import org.jboss.aop.CallerMethodInfo;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.MethodInfo;
+import org.jboss.aop.joinpoint.graph.BehaviorSearcher.SearchType;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTConstructor;
+import org.jboss.aop.pointcut.ast.ASTException;
+import org.jboss.aop.pointcut.ast.ASTMethod;
+import org.jboss.aop.pointcut.ast.ASTParameter;
+import org.jboss.aop.pointcut.ast.IdentifierExpression;
+
+/**
+ * Tests {@link BehaviorSearcher}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+ at SuppressWarnings("deprecation")
+public class BehaviorSearcherTest extends TestCase
+{
+   public StandardClassNode classNode;
+   
+   ConstructionInfo defaultConstruction;
+   JoinPointInfo intConstructorExec;
+   JoinPointInfo multiArgConstructor1Exec;
+   JoinPointInfo multiArgConstructor2Exec;
+   JoinPointInfo multiArgConstructor3Exec;
+   JoinPointInfo method1StringStringExec;
+   JoinPointInfo getPojo2MethodExec;
+   JoinPointInfo doSomethingMethodExec;
+   JoinPointInfo getPojo3MethodExec;
+   JoinPointInfo stringMethodExec;
+   JoinPointInfo interfaceMethod1Exec;
+   JoinPointInfo interfaceMethod2Exec;
+   JoinPointInfo calledByMethodExec;
+   
+   CallerMethodInfo defaultConstructor_calledByCon;
+   CallerMethodInfo defaultConstructor_calledByMethod;
+   CallerConstructorInfo stringConstructor_intConstructor;
+   CallerConstructorInfo stringConstructor_stringConstructor;
+   CallerMethodInfo stringConstructor_calledByCon;
+   CallerMethodInfo stringConstructor_calledByMethod;
+   CallerConstructorInfo getPojo3_intConstructor;
+   CallerConstructorInfo getPojo3_stringConstructor;
+   CallerMethodInfo getPojo3_calledByCon;
+   CallerMethodInfo getPojo3_calledByMethod;
+   CallerConstructorInfo getPojo2_intConstructor;
+   CallerMethodInfo getPojo2_calledByCon;
+   
+   ConstructionInfo defaultConstruction1;
+   JoinPointInfo pojo3ConstructorExec1;
+   JoinPointInfo multiArgConstructor3Exec1;
+   JoinPointInfo multiArgConstructor6Exec1;
+   JoinPointInfo privateMethodExec1;
+   JoinPointInfo getPojo2MethodExec1;
+   JoinPointInfo doSomethingMethodExec1;
+   JoinPointInfo method1Exec1;
+   JoinPointInfo method2Exec1;
+   JoinPointInfo method3Exec1;
+   JoinPointInfo method4Exec1;
+   JoinPointInfo method5Exec1;
+   JoinPointInfo interfaceMethod2Exec1;
+   
+   CallerConstructorInfo collectionConstructor_intConstructor1;
+   CallerConstructorInfo collectionConstructor_stringConstructor1;
+   CallerMethodInfo collectionConstructor_calledByCon1;
+   CallerMethodInfo collectionConstructor_calledByMethod1;
+   CallerConstructorInfo getPojo2_stringConstructor1;
+   CallerMethodInfo getPojo2_calledByMethod1;
+   
+   ConstructionInfo multiArgConstruction5_2;
+   ConstructionInfo multiArgConstruction6_2;
+   JoinPointInfo intConstructorExec2;
+   JoinPointInfo stringConstructorExec2;
+   JoinPointInfo multiArgConstructor4Exec2;
+   JoinPointInfo multiArgConstructor5Exec2;
+   JoinPointInfo privateMethodExec2;
+   JoinPointInfo someMethod1Exec2;
+   JoinPointInfo someMethod2Exec2;
+   JoinPointInfo interfaceMethod1Exec2;
+   JoinPointInfo interfaceMethod2Exec2;
+   
+   CallerConstructorInfo multiArgConstructor2_intConstructor2;
+   CallerConstructorInfo multiArgConstructor2_stringConstructor2;
+   CallerConstructorInfo stringMethod_intConstructor2;
+   CallerConstructorInfo stringMethod_stringConstructor2;
+   
+   ConstructionInfo defaultConstruction3;
+   JoinPointInfo stringConstructorExec3;
+   JoinPointInfo multiArgConstructor6Exec3;
+   JoinPointInfo privateMethodExec3;
+   JoinPointInfo method1Exec3;
+   JoinPointInfo method3Exec3;
+   JoinPointInfo method5Exec3;
+   JoinPointInfo method6Exec3;
+   JoinPointInfo method7Exec3;
+   JoinPointInfo calledByConExec3;
+   
+   CallerMethodInfo callConMethod_calledByConMethod3;
+   CallerMethodInfo callMethodMethod_calledByMethodMethod3;
+   CallerMethodInfo method4_calledByCon3;
+   CallerMethodInfo method4_calledByMethod3;
+   
+   private Collection<JoinPointInfo> result;
+   
+   @SuppressWarnings("deprecation")
+   public void setUp() throws Exception
+   {
+      // create advisors
+      Advisor advisor = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      Advisor instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      Advisor instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      Advisor instanceAdvisor3 = new InstanceAdvisorMock(advisor);
+      
+      // get constructors and methods
+      // private new()
+      Constructor defaultConstructor = Pojo1.class.getDeclaredConstructor();
+      // public new(int value)
+      Constructor intConstructor = Pojo1.class.getDeclaredConstructor(int.class);
+      // public new(String)
+      Constructor stringConstructor = Pojo2.class.getDeclaredConstructor(String.class);
+      // @AnyAnnotation
+      // protected Pojo5(Collection arg)
+      Constructor collectionConstructor = Pojo5.class.getDeclaredConstructor(
+            Collection.class);
+      // @Deprecated
+      // public Pojo5(Pojo3 pojo3) throws Exception
+      Constructor pojo3Constructor = Pojo5.class.getDeclaredConstructor(Pojo3.class);
+      // public AnnPojo(Pojo2 arg1, AnyAnnotationPojo arg2, DummyAnnotationPojo arg3)
+      Constructor multiArgConstructor1 = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, AnyAnnotationPojo.class, DummyAnnotationPojo.class);
+      // public AnnPojo(int arg1, Pojo2 arg2, long arg3, DummyAnnotationPojo arg4)
+      Constructor multiArgConstructor2 = AnnPojo.class.getDeclaredConstructor(
+            int.class, Pojo2.class, long.class, DummyAnnotationPojo.class);
+      // public AnnPojo(Pojo2 arg1, DummyAnnotationPojo arg2, long arg3)
+      Constructor multiArgConstructor3 = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, DummyAnnotationPojo.class, long.class);
+      // public AnnPojo(Pojo2 arg1, int arg2, long arg3)
+      Constructor multiArgConstructor4 = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, int.class, long.class);
+      // public AnnPojo(String arg1, int arg2, long arg3, DummyAnnotationPojo arg4,
+      //      AnyAnnotationPojo arg5)
+      Constructor multiArgConstructor5 = AnnPojo.class.getDeclaredConstructor(
+            String.class, int.class, long.class, DummyAnnotationPojo.class,
+            AnyAnnotationPojo.class);
+      // public AnnPojo(DummyAnnotationPojo arg1, AnyAnnotationPojo arg2)
+      Constructor multiArgConstructor6 = AnnPojo.class.getDeclaredConstructor(
+            DummyAnnotationPojo.class, AnyAnnotationPojo.class);
+      
+      // public void method1(String arg1, String arg2)
+      Method method1StringString = Pojo1.class.getDeclaredMethod("method1",
+            String.class, String.class);
+      // privateMethod()
+      Method privateMethod = Pojo1.class.getDeclaredMethod("privateMethod");
+      // public static final Pojo2 getPojo2()
+      Method getPojo2Method = Pojo2.class.getDeclaredMethod("getPojo2");
+      // public Pojo1 doSomething(int arg1, long arg2, Collection<Pojo1> arg3)
+      Method doSomethingMethod = Pojo2.class.getDeclaredMethod("doSomething",
+            int.class, long.class, Collection.class);
+      // public Pojo3 getPojo3()
+      Method getPojo3Method = Pojo2.class.getDeclaredMethod("getPojo3");
+      // public String stringMethod() throws ArrayIndexOutOfBoundsException, NullPointerException
+      Method stringMethod = Pojo3.class.getDeclaredMethod("stringMethod");
+      // public void someMethod(int arg1, long arg2)
+      Method someMethod1 = Pojo3.class.getDeclaredMethod("someMethod", int.class,
+            long.class);
+      // public String someMethod(String arg1, long arg2)
+      Method someMethod2 = Pojo3.class.getDeclaredMethod("someMethod", String.class,
+            long.class);
+      // public void callConstructor() throws Exception
+      Method callConstructorMethod = Pojo4.class.getDeclaredMethod("callConstructor");
+      // public void callMethod()
+      Method callMethodMethod = Pojo4.class.getDeclaredMethod("callMethod");
+      // @Bind(pointcut="all(Pojo5)")
+      // public void calledByCon() throws NullPointerException, IllegalStateException
+      Method calledByConMethod = Pojo5.class.getDeclaredMethod("calledByCon");
+      // @Mixin(interfaces={MetaDataKeyLoader.class})
+      // void calledByMethod() {}
+      Method calledByMethodMethod = Pojo5.class.getDeclaredMethod("calledByMethod");
+      // public void method1(Pojo2, AnyAnnotationPojo, DummyAnnotationPojo arg3)
+      Method method1 = AnnPojo.class.getDeclaredMethod("method1", Pojo2.class,
+            AnyAnnotationPojo.class, DummyAnnotationPojo.class);
+      // public Pojo2 method2(int, Pojo2, long, DummyAnnotationPojo)
+      Method method2 = AnnPojo.class.getDeclaredMethod("method2", int.class,
+            Pojo2.class, long.class, DummyAnnotationPojo.class);
+      // public DummyAnnotationPojo method3(Pojo2, DummyAnnotationPojo, long)
+      Method method3 = AnnPojo.class.getDeclaredMethod("method3", Pojo2.class,
+            DummyAnnotationPojo.class, long.class);
+      // public void method4(Pojo2, int, long) throws IllegalArgumentException, IllegalStateException {}
+      Method method4 = AnnPojo.class.getDeclaredMethod("method4", Pojo2.class,
+            int.class, long.class);
+      // public String method5(String, int, long, DummyAnnotationPojo, AnyAnnotationPojo)
+      Method method5 = AnnPojo.class.getDeclaredMethod("method5", String.class,
+            int.class, long.class, DummyAnnotationPojo.class, AnyAnnotationPojo.class);
+      // public void method6(DummyAnnotationPojo, AnyAnnotationPojo)
+      Method method6 = AnnPojo.class.getDeclaredMethod("method6",
+            DummyAnnotationPojo.class, AnyAnnotationPojo.class);
+      // public AnyAnnotationPojo method7(AnyAnnotationPojo arg1)
+      Method method7 = AnnPojo.class.getDeclaredMethod("method7",
+            AnyAnnotationPojo.class);
+      // public void interfaceMethod() throws NotImplementedException
+      Method interfaceMethod1 = DummyAnnotationPojo.class.
+         getDeclaredMethod("interfaceMethod");
+      // public DummyAnnotationPojo interfaceMethod2() throws IllegalArgumentException, IllegalStateException
+      Method interfaceMethod2 = DummyAnnotationPojo.class.getDeclaredMethod("interfaceMethod2");
+      
+      // create infos
+      defaultConstruction = new ConstructionInfo(advisor, defaultConstructor, 0);
+      intConstructorExec = new ConstructorInfo(advisor, intConstructor, 1);
+      multiArgConstructor1Exec = new ConstructorInfo(advisor, multiArgConstructor1, 2);
+      multiArgConstructor2Exec = new ConstructorInfo(advisor, multiArgConstructor2, 3);
+      multiArgConstructor3Exec = new ConstructorInfo(advisor, multiArgConstructor3, 4);
+      method1StringStringExec = new MethodInfo(advisor, 0l, method1StringString, null);
+      getPojo2MethodExec = new MethodInfo(advisor, 0l, getPojo2Method, null);
+      doSomethingMethodExec = new MethodInfo(advisor, 0l, doSomethingMethod, null);
+      getPojo3MethodExec = new MethodInfo(advisor, 0l, getPojo3Method, null);
+      stringMethodExec = new MethodInfo(advisor, 0l, stringMethod, null);
+      interfaceMethod1Exec = new MethodInfo(advisor, 0l, interfaceMethod1, null);
+      interfaceMethod2Exec = new MethodInfo(advisor, 0l, interfaceMethod2, null);
+      calledByMethodExec = new MethodInfo(advisor, 0l, calledByMethodMethod, null);
+      defaultConstructor_calledByCon = new MethodByConInfo(advisor, Pojo3.class,
+            Pojo1.class, 0, calledByConMethod, 0l, null);
+      defaultConstructor_calledByMethod = new MethodByConInfo(advisor, Pojo3.class,
+            Pojo1.class, 0, calledByMethodMethod, 0l, null);
+      stringConstructor_intConstructor = new ConByConInfo(advisor, Pojo1.class,
+            Pojo2.class, 2, intConstructor, 0l, null, null);
+      stringConstructor_stringConstructor = new ConByConInfo(advisor, Pojo2.class,
+            Pojo2.class, 2, stringConstructor, 0l, null, null);
+      stringConstructor_calledByCon = new MethodByConInfo(advisor, Pojo5.class,
+            Pojo2.class, 2, calledByConMethod, 0l, null);
+      stringConstructor_calledByMethod = new MethodByConInfo(advisor, Pojo5.class,
+            Pojo2.class, 2, calledByConMethod, 0l, null);
+      getPojo3_intConstructor = new ConByMethodInfo(advisor, Pojo1.class,
+            getPojo3Method, 0l, intConstructor, 0l, null, null);
+      getPojo3_stringConstructor = new ConByMethodInfo(advisor, Pojo2.class,
+            getPojo3Method, 0l, stringConstructor, 0l, null, null);
+      getPojo3_calledByCon = new MethodByMethodInfo(advisor, Pojo5.class,
+            calledByConMethod, getPojo3Method, 0l, 0l, null);
+      getPojo3_calledByMethod = new MethodByMethodInfo(advisor, Pojo5.class,
+            calledByMethodMethod, getPojo3Method, 0l, 0l, null);
+      getPojo2_intConstructor = new ConByMethodInfo(advisor, Pojo1.class,
+            getPojo2Method, 0l, intConstructor, 0l, null, null);
+      getPojo2_calledByCon = new MethodByMethodInfo(advisor, Pojo5.class,
+            calledByConMethod, getPojo2Method, 0l, 0l, null);
+      
+      defaultConstruction1 = new ConstructionInfo(instanceAdvisor1, defaultConstructor, 0);
+      pojo3ConstructorExec1 = new ConstructorInfo(instanceAdvisor1, pojo3Constructor, 2);
+      multiArgConstructor3Exec1 = new ConstructorInfo(instanceAdvisor1, multiArgConstructor3, 2);
+      multiArgConstructor6Exec1 = new ConstructorInfo(instanceAdvisor1, multiArgConstructor6, 5);
+      privateMethodExec1 = new MethodInfo(instanceAdvisor1, 0l, privateMethod, null);
+      getPojo2MethodExec1 = new MethodInfo(instanceAdvisor1, 0l, getPojo2Method, null);
+      doSomethingMethodExec1 = new MethodInfo(instanceAdvisor1, 0l, doSomethingMethod, null);
+      method1Exec1 = new MethodInfo(instanceAdvisor1, 0l, method1, null);
+      method2Exec1 = new MethodInfo(instanceAdvisor1, 0l, method2, null);
+      method3Exec1 = new MethodInfo(instanceAdvisor1, 0l, method3, null);
+      method4Exec1 = new MethodInfo(instanceAdvisor1, 0l, method4, null);
+      method5Exec1 = new MethodInfo(instanceAdvisor1, 0l, method5, null);
+      interfaceMethod2Exec1 = new MethodInfo(instanceAdvisor1, 0l, interfaceMethod1, null);
+      collectionConstructor_intConstructor1 = new ConByConInfo(instanceAdvisor1, Pojo1.class,
+            Pojo5.class, 1, intConstructor, 0l, null, null);
+      collectionConstructor_stringConstructor1 = new ConByConInfo(instanceAdvisor1, Pojo2.class,
+            Pojo5.class, 1, stringConstructor, 0l, null, null);
+      collectionConstructor_calledByCon1 = new MethodByConInfo(instanceAdvisor1, Pojo5.class,
+            Pojo5.class, 1, calledByConMethod, 0l, null);
+      collectionConstructor_calledByMethod1 = new MethodByConInfo(instanceAdvisor1, Pojo5.class,
+            Pojo5.class, 1, calledByMethodMethod, 0l, null);
+      getPojo2_stringConstructor1 = new ConByMethodInfo(instanceAdvisor1, Pojo2.class,
+            getPojo2Method, 0l, stringConstructor, 0l, null, null);
+      getPojo2_calledByMethod1 = new MethodByMethodInfo(instanceAdvisor1, Pojo5.class,
+            calledByMethodMethod, getPojo2Method, 0l, 0l, null);
+      
+      multiArgConstruction5_2 = new ConstructionInfo(instanceAdvisor2, multiArgConstructor5, 4);
+      multiArgConstruction6_2 = new ConstructionInfo(instanceAdvisor2, multiArgConstructor6, 5);
+      intConstructorExec2 = new ConstructorInfo(instanceAdvisor2, intConstructor, 1);
+      stringConstructorExec2 = new ConstructorInfo(instanceAdvisor2, stringConstructor, 2);
+      multiArgConstructor4Exec2 = new ConstructorInfo(instanceAdvisor2, multiArgConstructor4, 3);
+      multiArgConstructor5Exec2 = new ConstructorInfo(instanceAdvisor2, multiArgConstructor5, 4);
+      privateMethodExec2 = new MethodInfo(instanceAdvisor2, 0l, privateMethod, null);
+      someMethod1Exec2 = new MethodInfo(instanceAdvisor2, 0l, someMethod1, null);
+      someMethod2Exec2 = new MethodInfo(instanceAdvisor2, 0l, someMethod2, null);
+      interfaceMethod1Exec2 = new MethodInfo(instanceAdvisor2, 0l, interfaceMethod1, null);
+      interfaceMethod2Exec2 = new MethodInfo(instanceAdvisor2, 0l, interfaceMethod2, null);
+      multiArgConstructor2_intConstructor2 = new ConByConInfo(instanceAdvisor2,
+            Pojo1.class, AnnPojo.class, 1, intConstructor, 0l, null, null);
+      multiArgConstructor2_stringConstructor2 = new ConByConInfo(instanceAdvisor2,
+            Pojo2.class, AnnPojo.class, 1, stringConstructor, 0l, null, null);
+      stringMethod_intConstructor2 = new ConByMethodInfo(instanceAdvisor1, Pojo1.class,
+            stringMethod, 0l, intConstructor, 0l, null, null);
+      stringMethod_stringConstructor2 = new ConByMethodInfo(instanceAdvisor2,
+            Pojo2.class, stringMethod, 0l, stringConstructor, 0l, null, null);
+      
+      defaultConstruction3 = new ConstructionInfo(instanceAdvisor3, defaultConstructor, 0);
+      stringConstructorExec3 = new ConstructorInfo(instanceAdvisor3, stringConstructor, 0);
+      multiArgConstructor6Exec3 = new ConstructorInfo(instanceAdvisor3, multiArgConstructor6, 0);
+      privateMethodExec3 = new MethodInfo(instanceAdvisor3, 0l, privateMethod, null);
+      method1Exec3 = new MethodInfo(instanceAdvisor3, 0l, method1, null);
+      method3Exec3 = new MethodInfo(instanceAdvisor3, 0l, method3, null);
+      method5Exec3 = new MethodInfo(instanceAdvisor3, 0l, method5, null);
+      method6Exec3 = new MethodInfo(instanceAdvisor3, 0l, method6, null);
+      method7Exec3 = new MethodInfo(instanceAdvisor3, 0l, method7, null);
+      calledByConExec3 = new MethodInfo(instanceAdvisor3, 0l, calledByConMethod, null);
+      callConMethod_calledByConMethod3 = new MethodByMethodInfo(instanceAdvisor3,
+            Pojo5.class, calledByConMethod, callConstructorMethod, 0l, 0l, null);
+      callMethodMethod_calledByMethodMethod3 = new MethodByMethodInfo(instanceAdvisor3,
+            Pojo5.class, calledByMethodMethod, callMethodMethod, 0l, 0l, null);
+      method4_calledByCon3 = new MethodByMethodInfo(instanceAdvisor3,
+            Pojo5.class, calledByConMethod, method4, 0l, 0l, null);
+      method4_calledByMethod3 = new MethodByMethodInfo(instanceAdvisor3,
+            Pojo5.class, calledByMethodMethod, method4, 0l, 0l, null);
+      
+      // mount class node structure
+      classNode = new StandardClassNode(Pojo3.class);
+      AdvisedData advisedData = classNode.getAdvisedData(advisor);
+      advisedData.getBehavior(defaultConstructor).setConstruction(defaultConstruction);
+      advisedData.getBehavior(intConstructor).setExecution(intConstructorExec);
+      advisedData.getBehavior(multiArgConstructor1).setExecution(multiArgConstructor1Exec);
+      advisedData.getBehavior(multiArgConstructor2).setExecution(multiArgConstructor2Exec);
+      advisedData.getBehavior(multiArgConstructor3).setExecution(multiArgConstructor3Exec);
+      advisedData.getBehavior(method1StringString).setExecution(method1StringStringExec);
+      advisedData.getBehavior(getPojo2Method).setExecution(getPojo2MethodExec);
+      advisedData.getBehavior(doSomethingMethod).setExecution(doSomethingMethodExec);
+      advisedData.getBehavior(getPojo3Method).setExecution(getPojo3MethodExec);
+      advisedData.getBehavior(stringMethod).setExecution(stringMethodExec);
+      advisedData.getBehavior(interfaceMethod1).setExecution(interfaceMethod1Exec);
+      advisedData.getBehavior(interfaceMethod2).setExecution(interfaceMethod2Exec);
+      advisedData.getBehavior(calledByMethodMethod).setExecution(calledByMethodExec);
+      advisedData.getBehavior(defaultConstructor).addCallee(defaultConstructor_calledByCon);
+      advisedData.getBehavior(defaultConstructor).addCallee(defaultConstructor_calledByMethod);
+      advisedData.getBehavior(stringConstructor).addCallee(stringConstructor_intConstructor);
+      advisedData.getBehavior(stringConstructor).addCallee(stringConstructor_stringConstructor);
+      advisedData.getBehavior(stringConstructor).addCallee(stringConstructor_calledByCon);
+      advisedData.getBehavior(stringConstructor).addCallee(stringConstructor_calledByMethod);
+      advisedData.getBehavior(getPojo3Method).addCallee(getPojo3_intConstructor);
+      advisedData.getBehavior(getPojo3Method).addCallee(getPojo3_stringConstructor);
+      advisedData.getBehavior(getPojo3Method).addCallee(getPojo3_calledByCon);
+      advisedData.getBehavior(getPojo3Method).addCallee(getPojo3_calledByMethod);
+      advisedData.getBehavior(getPojo2Method).addCallee(getPojo2_intConstructor);
+      advisedData.getBehavior(getPojo2Method).addCallee(getPojo2_calledByCon);
+      
+      advisedData = classNode.getAdvisedData(instanceAdvisor1);
+      advisedData.getBehavior(defaultConstructor).setConstruction(defaultConstruction1);
+      advisedData.getBehavior(pojo3Constructor).setExecution(pojo3ConstructorExec1);
+      advisedData.getBehavior(multiArgConstructor3).setExecution(multiArgConstructor3Exec1);
+      advisedData.getBehavior(multiArgConstructor6).setExecution(multiArgConstructor6Exec1);
+      advisedData.getBehavior(privateMethod).setExecution(privateMethodExec1);
+      advisedData.getBehavior(getPojo2Method).setExecution(getPojo2MethodExec1);
+      advisedData.getBehavior(doSomethingMethod).setExecution(doSomethingMethodExec1);
+      advisedData.getBehavior(method1).setExecution(method1Exec1);
+      advisedData.getBehavior(method2).setExecution(method2Exec1);
+      advisedData.getBehavior(method3).setExecution(method3Exec1);
+      advisedData.getBehavior(method4).setExecution(method4Exec1);
+      advisedData.getBehavior(method5).setExecution(method5Exec1);
+      advisedData.getBehavior(interfaceMethod2).setExecution(interfaceMethod2Exec1);
+      advisedData.getBehavior(collectionConstructor).addCallee(collectionConstructor_intConstructor1);
+      advisedData.getBehavior(collectionConstructor).addCallee(collectionConstructor_stringConstructor1);
+      advisedData.getBehavior(collectionConstructor).addCallee(collectionConstructor_calledByCon1);
+      advisedData.getBehavior(collectionConstructor).addCallee(collectionConstructor_calledByMethod1);
+      advisedData.getBehavior(getPojo2Method).addCallee(getPojo2_stringConstructor1);
+      advisedData.getBehavior(getPojo2Method).addCallee(getPojo2_calledByMethod1);
+      
+      advisedData = classNode.getAdvisedData(instanceAdvisor2);
+      advisedData.getBehavior(multiArgConstructor5).setConstruction(multiArgConstruction5_2);
+      advisedData.getBehavior(multiArgConstructor6).setConstruction(multiArgConstruction6_2);
+      advisedData.getBehavior(intConstructor).setExecution(intConstructorExec2);
+      advisedData.getBehavior(stringConstructor).setExecution(stringConstructorExec2);
+      advisedData.getBehavior(multiArgConstructor4).setExecution(multiArgConstructor4Exec2);
+      advisedData.getBehavior(multiArgConstructor5).setExecution(multiArgConstructor5Exec2);
+      advisedData.getBehavior(privateMethod).setExecution(privateMethodExec2);
+      advisedData.getBehavior(someMethod1).setExecution(someMethod1Exec2);
+      advisedData.getBehavior(someMethod2).setExecution(someMethod2Exec2);
+      advisedData.getBehavior(interfaceMethod1).setExecution(interfaceMethod1Exec2);
+      advisedData.getBehavior(interfaceMethod2).setExecution(interfaceMethod2Exec2);
+      advisedData.getBehavior(multiArgConstructor2).addCallee(multiArgConstructor2_intConstructor2);
+      advisedData.getBehavior(multiArgConstructor2).addCallee(multiArgConstructor2_stringConstructor2);
+      advisedData.getBehavior(stringMethod).addCallee(stringMethod_intConstructor2);
+      advisedData.getBehavior(stringMethod).addCallee(stringMethod_stringConstructor2);
+      
+      advisedData = classNode.getAdvisedData(instanceAdvisor3);
+      advisedData.getBehavior(defaultConstructor).setConstruction(defaultConstruction3);
+      advisedData.getBehavior(stringConstructor).setExecution(stringConstructorExec3);
+      advisedData.getBehavior(multiArgConstructor6).setExecution(multiArgConstructor6Exec3);
+      advisedData.getBehavior(privateMethod).setExecution(privateMethodExec3);
+      advisedData.getBehavior(method1).setExecution(method1Exec3);
+      advisedData.getBehavior(method3).setExecution(method3Exec3);
+      advisedData.getBehavior(method5).setExecution(method5Exec3);
+      advisedData.getBehavior(method6).setExecution(method6Exec3);
+      advisedData.getBehavior(method7).setExecution(method7Exec3);
+      advisedData.getBehavior(calledByConMethod).setExecution(calledByConExec3);
+      advisedData.getBehavior(callConstructorMethod).addCallee(callConMethod_calledByConMethod3);
+      advisedData.getBehavior(callMethodMethod).addCallee(callMethodMethod_calledByMethodMethod3);
+      advisedData.getBehavior(method4).addCallee(method4_calledByCon3);
+      advisedData.getBehavior(method4).addCallee(method4_calledByMethod3);
+      
+      // result collection
+      result = new HashSet<JoinPointInfo>();
+   }
+   
+   public void testAllConstruction()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstruction, defaultConstruction1,
+            multiArgConstruction5_2, multiArgConstruction6_2, defaultConstruction3);
+   }
+   
+   public void testAllExecution()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, intConstructorExec, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            method1StringStringExec, getPojo2MethodExec, doSomethingMethodExec,
+            getPojo3MethodExec, stringMethodExec, interfaceMethod1Exec,
+            interfaceMethod2Exec, calledByMethodExec, pojo3ConstructorExec1,
+            multiArgConstructor3Exec1, multiArgConstructor6Exec1, privateMethodExec1,
+            getPojo2MethodExec1, doSomethingMethodExec1,method1Exec1,method2Exec1,
+            method3Exec1, method4Exec1, method5Exec1, interfaceMethod2Exec1,
+            intConstructorExec2, stringConstructorExec2, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, privateMethodExec2, someMethod1Exec2,
+            someMethod2Exec2, interfaceMethod1Exec2, interfaceMethod2Exec2,
+            stringConstructorExec3, multiArgConstructor6Exec3, privateMethodExec3,
+            method1Exec3, method3Exec3, method5Exec3, method6Exec3, method7Exec3,
+            calledByConExec3);
+   }
+   
+   public void testAllCall()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstructor_calledByCon,
+            defaultConstructor_calledByMethod, stringConstructor_intConstructor,
+            stringConstructor_stringConstructor, stringConstructor_calledByCon,
+            stringConstructor_calledByMethod, getPojo3_intConstructor,
+            getPojo3_stringConstructor, getPojo3_calledByCon,
+            getPojo3_calledByMethod, getPojo2_intConstructor, getPojo2_calledByCon,
+            collectionConstructor_intConstructor1,
+            collectionConstructor_stringConstructor1,
+            collectionConstructor_calledByCon1,
+            collectionConstructor_calledByMethod1, getPojo2_stringConstructor1,
+            getPojo2_calledByMethod1, multiArgConstructor2_intConstructor2,
+            multiArgConstructor2_stringConstructor2, stringMethod_intConstructor2,
+            stringMethod_stringConstructor2, callConMethod_calledByConMethod3,
+            callMethodMethod_calledByMethodMethod3, method4_calledByCon3,
+            method4_calledByMethod3);
+   }
+   
+   public void testAttributeConstruction()
+   {
+      BehaviorSearcher searcher = getAttributeSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstruction, defaultConstruction1,
+            defaultConstruction3);
+   }
+   
+   public void testAttributeExecution()
+   {
+      BehaviorSearcher searcher = getAttributeSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, privateMethodExec1, privateMethodExec2,
+            privateMethodExec3, calledByMethodExec);
+   }
+   
+   public void testAttributeCall()
+   {
+      BehaviorSearcher searcher = getAttributeSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      CalleeSearcher calleeSearcher = new OptimizedCalleeSearcher("*|*| *#*");
+      ((CallSearcher)searcher.getInternalSearcher()).setCalleeRestriction(calleeSearcher);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstructor_calledByCon,
+            defaultConstructor_calledByMethod, collectionConstructor_calledByCon1,
+            collectionConstructor_calledByMethod1);
+   }
+   
+   private BehaviorSearcher getAttributeSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      return new BehaviorSearcher("*", attributes, new ArrayList<ASTException>());
+   }
+   
+   public void testExceptionConstruction()
+   {
+      BehaviorSearcher searcher = getExceptionSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testExceptionExecution()
+   {
+      BehaviorSearcher searcher = getExceptionSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, pojo3ConstructorExec1, stringMethodExec,
+            calledByConExec3, method4Exec1,interfaceMethod1Exec,
+            interfaceMethod1Exec2, interfaceMethod2Exec, interfaceMethod2Exec1,
+            interfaceMethod2Exec2);
+   }
+   
+   public void testExceptionCall()
+   {
+      BehaviorSearcher searcher = getExceptionSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, callConMethod_calledByConMethod3,
+            stringMethod_intConstructor2, stringMethod_stringConstructor2,
+            method4_calledByCon3, method4_calledByMethod3);
+   }
+   
+   private BehaviorSearcher getExceptionSearcher()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*");
+      exceptions.add(exception);
+      return new BehaviorSearcher("*", new ArrayList<ASTAttribute>(), exceptions);
+   }
+   
+   public void testAttributeExceptionConstruction()
+   {
+      BehaviorSearcher searcher = getAttributeExceptionSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttributeExceptionExecution()
+   {
+      BehaviorSearcher searcher = getAttributeExceptionSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, method4Exec1, calledByConExec3,
+            interfaceMethod2Exec, interfaceMethod2Exec1, interfaceMethod2Exec2);
+   }
+   
+   public void testAttributeExceptionCall()
+   {
+      BehaviorSearcher searcher = getAttributeExceptionSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, method4_calledByCon3, method4_calledByMethod3);
+   }
+   
+   private BehaviorSearcher getAttributeExceptionSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.FINAL);
+      attribute.not = true;
+      attributes.add(attribute);
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*Illegal*");
+      exceptions.add(exception);
+      return new BehaviorSearcher("*", attributes, exceptions);
+   }
+   
+   public void testExpressionConstruction()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("new#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstruction, defaultConstruction1,
+            multiArgConstruction5_2, multiArgConstruction6_2, defaultConstruction3);
+   }
+   
+   public void testExpressionExecution()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("new#|*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, intConstructorExec, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            pojo3ConstructorExec1, multiArgConstructor3Exec1,
+            multiArgConstructor6Exec1, intConstructorExec2, stringConstructorExec2,
+            multiArgConstructor4Exec2, multiArgConstructor5Exec2,
+            stringConstructorExec3, multiArgConstructor6Exec3);
+   }
+   
+   public void testExpressionCall()
+   {
+      BehaviorSearcher searcher = new BehaviorSearcher("new#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, defaultConstructor_calledByCon,
+            defaultConstructor_calledByMethod, stringConstructor_intConstructor,
+            stringConstructor_stringConstructor, stringConstructor_calledByCon,
+            stringConstructor_calledByMethod, collectionConstructor_intConstructor1,
+            collectionConstructor_stringConstructor1,
+            collectionConstructor_calledByCon1,
+            collectionConstructor_calledByMethod1,
+            multiArgConstructor2_intConstructor2,
+            multiArgConstructor2_stringConstructor2);
+   }
+   
+   public void testAttExpConstruction()
+   {
+      BehaviorSearcher searcher = getAttExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttExpExecution()
+   {
+      BehaviorSearcher searcher = getAttExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttExpCall()
+   {
+      BehaviorSearcher searcher = getAttExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, collectionConstructor_intConstructor1,
+            collectionConstructor_stringConstructor1,
+            collectionConstructor_calledByCon1,
+            collectionConstructor_calledByMethod1);
+   }
+   
+   private BehaviorSearcher getAttExpSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      return new BehaviorSearcher("*#||", attributes, new ArrayList<ASTException>());
+   }
+   
+   public void testExcExpConstruction()
+   {
+      BehaviorSearcher searcher = getExcExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testExcExpExecution()
+   {
+      BehaviorSearcher searcher = getExcExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, stringMethodExec, method4Exec1,
+            interfaceMethod1Exec, interfaceMethod1Exec2,
+            interfaceMethod2Exec, interfaceMethod2Exec1, interfaceMethod2Exec2);
+   }
+   
+   public void testExcExpCall()
+   {
+      BehaviorSearcher searcher = getExcExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, stringMethod_intConstructor2,
+            stringMethod_stringConstructor2, method4_calledByCon3,
+            method4_calledByMethod3);
+   }
+   
+   private BehaviorSearcher getExcExpSearcher()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*");
+      exceptions.add(exception);
+      return new BehaviorSearcher("*| *ethod*#*", new ArrayList<ASTAttribute>(), exceptions);
+   }
+   
+   public void testAttExcExpConstruction()
+   {
+      BehaviorSearcher searcher = getAttExcExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttExcExpExecution()
+   {
+      BehaviorSearcher searcher = getAttExcExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);  
+      Util.assertCollection(result, stringMethodExec, calledByConExec3,
+            method4Exec1,interfaceMethod1Exec, interfaceMethod1Exec2,
+            interfaceMethod2Exec, interfaceMethod2Exec1, interfaceMethod2Exec2);
+   }
+   
+   public void testAttExcExpCall()
+   {
+      BehaviorSearcher searcher = getAttExcExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, callConMethod_calledByConMethod3,
+            stringMethod_intConstructor2, stringMethod_stringConstructor2,
+            method4_calledByCon3, method4_calledByMethod3);
+   }
+   
+   private BehaviorSearcher getAttExcExpSearcher()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*");
+      exceptions.add(exception);
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attributes.add(attribute);
+      return new BehaviorSearcher("*| *#*", attributes, exceptions);
+   }
+   
+   public void testConsFilterExpSearcherConstruction()
+   {
+      BehaviorSearcher searcher = getConsFilterExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstruction5_2,
+            multiArgConstruction6_2);
+   }
+   
+   public void testConsFilterExpSearcherExecution()
+   {
+      BehaviorSearcher searcher = getConsFilterExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor5Exec2,
+            multiArgConstructor6Exec1, multiArgConstructor6Exec3,
+            pojo3ConstructorExec1);
+   }
+   
+   public void testConsFilterExpSearcherCall()
+   {
+      BehaviorSearcher searcher = getConsFilterExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2_intConstructor2,
+            multiArgConstructor2_stringConstructor2);
+   }
+   
+   private BehaviorSearcher getConsFilterExpSearcher()
+   {
+      ASTParameter parameter1 = new ASTParameter(1001);
+      ASTParameter parameter2 = new ASTParameter(1001);
+      ASTParameter parameter3 = new ASTParameter(1001);
+      parameter1.setTypeExpression("..");
+      parameter2.setTypeExpression('@' + DummyAnnotation.class.getName());
+      parameter3.setTypeExpression("..");
+      // constructor
+      ASTConstructor constructor = new ASTConstructor(null, 1000);
+      constructor.jjtAddChild(parameter3, 0);
+      constructor.jjtAddChild(parameter2, 0);
+      constructor.jjtAddChild(parameter1, 1);
+      
+      BehaviorFilter filter = new FullParameterFilter(constructor);
+      return new BehaviorSearcher("*new#|*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>(), filter, false);
+   }
+   
+   public void testAttMetFilterExpSearcherConstruction()
+   {
+      BehaviorSearcher searcher = getAttMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttMetFilterExpSearcherExecution()
+   {
+      BehaviorSearcher searcher = getAttMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, method1Exec1, method1Exec3, method2Exec1,
+            method3Exec1, method3Exec3, method5Exec1, method5Exec3, method6Exec3);
+   }
+   
+   public void testAttMetFilterExpSearcherCall()
+   {
+      BehaviorSearcher searcher = getAttMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getAttMetFilterExpSearcher()
+   {
+      ASTParameter parameter1 = new ASTParameter(1001);
+      ASTParameter parameter2 = new ASTParameter(1001);
+      ASTParameter parameter3 = new ASTParameter(1001);
+      parameter1.setTypeExpression("..");
+      parameter2.setTypeExpression('@' + DummyAnnotation.class.getName());
+      parameter3.setTypeExpression("..");
+      // method
+      ASTMethod method = new ASTMethod(null, 1000);
+      method.jjtAddChild(parameter3, 0);
+      method.jjtAddChild(parameter2, 1);
+      method.jjtAddChild(parameter1, 2);
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      BehaviorFilter filter = new FullParameterFilter(method);
+      return new BehaviorSearcher("*| *#|*", attributes,
+            new ArrayList<ASTException>(), filter, true);
+   }
+   
+   public void testAttExcMetFilterExpSearcherConstruction()
+   {
+      BehaviorSearcher searcher = getAttExcMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttExcMetFilterExpSearcherExecution()
+   {
+      BehaviorSearcher searcher = getAttExcMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, interfaceMethod1Exec, interfaceMethod1Exec2);
+   }
+   
+   public void testAttExcMetFilterExpSearcherCall()
+   {
+      BehaviorSearcher searcher = getAttExcMetFilterExpSearcher();
+      searcher.setSearchType(SearchType.CALL);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getAttExcMetFilterExpSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*");
+      exceptions.add(exception);
+      IdentifierExpression exp = new IdentifierExpression("$implements{" +
+            DummyInterface.class.getName() + "}");
+      BehaviorFilter filter = new ImplementedMethodFilter(exp);
+      return new BehaviorSearcher("void| *#*", attributes,
+            exceptions, filter, true);
+   }
+   
+   public void testTwoParamBehavior()
+   {
+      BehaviorSearcher searcher = getTwoParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec, someMethod1Exec2,
+            someMethod2Exec2, method6Exec3);
+   }
+   
+   public BehaviorSearcher getTwoParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testThreeParamBehavior()
+   {
+      BehaviorSearcher searcher = getThreeParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor3Exec, multiArgConstructor3Exec1,
+            multiArgConstructor4Exec2, doSomethingMethodExec, doSomethingMethodExec1,
+            method1Exec1, method1Exec3, method3Exec1, method3Exec3, method4Exec1);
+   }
+   
+   public BehaviorSearcher getThreeParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedThreeParamBehavior1()
+   {
+      BehaviorSearcher searcher = getMixedThreeParamBehavior1();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor3Exec, multiArgConstructor3Exec1,
+            multiArgConstructor4Exec2, method1Exec1, method1Exec3, method3Exec1,
+            method3Exec3, method4Exec1);
+   }
+   
+   public BehaviorSearcher getMixedThreeParamBehavior1()
+   {
+      return new BehaviorSearcher("*#| " + Pojo2.class.getName() + " ||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedThreeParamBehavior2()
+   {
+      BehaviorSearcher searcher = getMixedThreeParamBehavior2();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, method3Exec1, method3Exec3);
+   }
+   
+   public BehaviorSearcher getMixedThreeParamBehavior2()
+   {
+      return new BehaviorSearcher("*#||| " + DummyAnnotationPojo.class.getName() + " ||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedThreeParamBehavior3()
+   {
+      BehaviorSearcher searcher = getMixedThreeParamBehavior3();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2, method3Exec1,
+            method3Exec3, method4Exec1);
+   }
+   
+   public BehaviorSearcher getMixedThreeParamBehavior3()
+   {
+      return new BehaviorSearcher("*#||||| long  ", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testFourParamBehavior()
+   {
+      BehaviorSearcher searcher = getFourParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getFourParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior1()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior1();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior1()
+   {
+      return new BehaviorSearcher("*#| int ||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior2()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior2();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior2()
+   {
+      return new BehaviorSearcher("*#||||||| int  ", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior3()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior3();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior3()
+   {
+      return new BehaviorSearcher("*#||||||| " + DummyAnnotationPojo.class.getName()
+            + "  ", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior4()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior4();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior4()
+   {
+      return new BehaviorSearcher("*#||||| long ||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior5()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior5();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior5()
+   {
+      return new BehaviorSearcher("*#||| " + Pojo2.class.getName() + " ||||",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior6()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior6();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior6()
+   {
+      return new BehaviorSearcher("*#| int | " + Pojo2.class.getName() + " ||||",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior7()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior7();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior7()
+   {
+      return new BehaviorSearcher("*#| int ||| long ||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior8()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior8();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior8()
+   {
+      return new BehaviorSearcher("*#| int ||||| " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior9()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior9();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior9()
+   {
+      return new BehaviorSearcher("*#||| " + Pojo2.class.getName()+ " | long ||",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior10()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior10();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior10()
+   {
+      return new BehaviorSearcher("*#||| " + Pojo2.class.getName()+ " ||| " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior11()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior11();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior11()
+   {
+      return new BehaviorSearcher("*#||||| long | " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior12()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior12();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior12()
+   {
+      return new BehaviorSearcher("*#| int | " + Pojo2.class.getName() + " | long ||",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior13()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior13();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior13()
+   {
+      return new BehaviorSearcher("*#| int | " + Pojo2.class.getName() + " ||| " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior14()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior14();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior14()
+   {
+      return new BehaviorSearcher("*#| int ||| long | " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testMixedFourParamBehavior15()
+   {
+      BehaviorSearcher searcher = getMixedFourParamBehavior15();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedFourParamBehavior15()
+   {
+      return new BehaviorSearcher("*#||| " + Pojo2.class.getName() + " | long | " +
+            DummyAnnotationPojo.class.getName() + "  ",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+   }
+   
+   public void testFiveParamBehavior()
+   {
+      BehaviorSearcher searcher = getFiveParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor5Exec2, method5Exec1,
+            method5Exec3);
+   }
+   
+   public BehaviorSearcher getFiveParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testFiveOrMoreParamBehavior()
+   {
+      BehaviorSearcher searcher = getFiveOrMoreParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor5Exec2, method5Exec1,
+            method5Exec3);
+   }
+   
+   public BehaviorSearcher getFiveOrMoreParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||||||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testSixParamBehavior()
+   {
+      BehaviorSearcher searcher = getSixParamBehavior();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getSixParamBehavior()
+   {
+      return new BehaviorSearcher("*#||||||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards1()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards1();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, intConstructorExec, intConstructorExec2,
+            stringConstructorExec2, stringConstructorExec3,
+            pojo3ConstructorExec1, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec,
+            doSomethingMethodExec, doSomethingMethodExec1, someMethod1Exec2,
+            someMethod2Exec2, method1Exec1, method1Exec3, method2Exec1, method3Exec1,
+            method3Exec3, method4Exec1, method5Exec1, method5Exec3, method6Exec3,
+            method7Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards1()
+   {
+      return new BehaviorSearcher("*#*||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards2()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards2();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec,
+            doSomethingMethodExec, doSomethingMethodExec1, someMethod1Exec2,
+            someMethod2Exec2, method1Exec1, method1Exec3, method2Exec1, method3Exec1,
+            method3Exec3, method4Exec1, method5Exec1, method5Exec3, method6Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards2()
+   {
+      return new BehaviorSearcher("*#*||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards3()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards3();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, doSomethingMethodExec,
+            doSomethingMethodExec1, method1Exec1, method1Exec3, method2Exec1,
+            method3Exec1, method3Exec3, method4Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards3()
+   {
+      return new BehaviorSearcher("*#*||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards4()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards4();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec,
+            multiArgConstructor5Exec2, method2Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards4()
+   {
+      return new BehaviorSearcher("*#*||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards5()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards5();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor5Exec2, method5Exec1,
+            method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards5()
+   {
+      return new BehaviorSearcher("*#*||||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards6()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards6();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards6()
+   {
+      return new BehaviorSearcher("*#*||||||||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards7()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards7();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, intConstructorExec, intConstructorExec2,
+            stringConstructorExec2, stringConstructorExec3,
+            pojo3ConstructorExec1, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec,
+            doSomethingMethodExec, doSomethingMethodExec1, someMethod1Exec2,
+            someMethod2Exec2, method1Exec1, method1Exec3, method2Exec1, method3Exec1,
+            method3Exec3, method4Exec1, method5Exec1, method5Exec3, method6Exec3,
+            method7Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards7()
+   {
+      return new BehaviorSearcher("*#||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards8()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards8();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec,
+            doSomethingMethodExec, doSomethingMethodExec1, someMethod1Exec2,
+            someMethod2Exec2, method1Exec1, method1Exec3, method2Exec1, method3Exec1,
+            method3Exec3, method4Exec1, method5Exec1, method5Exec3, method6Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards8()
+   {
+      return new BehaviorSearcher("*#||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards9()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards9();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, doSomethingMethodExec,
+            doSomethingMethodExec1, method1Exec1, method1Exec3, method2Exec1,
+            method3Exec1, method3Exec3, method4Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards9()
+   {
+      return new BehaviorSearcher("*#||||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards10()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards10();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec,
+            multiArgConstructor5Exec2, method2Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards10()
+   {
+      return new BehaviorSearcher("*#||||||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards11()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards11();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor5Exec2, method5Exec1,
+            method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards11()
+   {
+      return new BehaviorSearcher("*#||||||||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards12()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards12();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards12()
+   {
+      return new BehaviorSearcher("*#||||||||||||*", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards13()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards13();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, multiArgConstructor6Exec1,
+            multiArgConstructor6Exec3, method1StringStringExec,
+            doSomethingMethodExec, doSomethingMethodExec1, someMethod1Exec2,
+            someMethod2Exec2, method1Exec1, method1Exec3, method2Exec1, method3Exec1,
+            method3Exec3, method4Exec1, method5Exec1, method5Exec3, method6Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards13()
+   {
+      return new BehaviorSearcher("*#||*||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards14()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards14();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, doSomethingMethodExec,
+            doSomethingMethodExec1, method1Exec1, method1Exec3, method2Exec1,
+            method3Exec1, method3Exec3, method4Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards14()
+   {
+      return new BehaviorSearcher("*#||*||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards15()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards15();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor1Exec,
+            multiArgConstructor2Exec, multiArgConstructor3Exec,
+            multiArgConstructor3Exec1, multiArgConstructor4Exec2,
+            multiArgConstructor5Exec2, doSomethingMethodExec,
+            doSomethingMethodExec1, method1Exec1, method1Exec3, method2Exec1,
+            method3Exec1, method3Exec3, method4Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards15()
+   {
+      return new BehaviorSearcher("*#||||*||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards16()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards16();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec,
+            multiArgConstructor5Exec2, method2Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards16()
+   {
+      return new BehaviorSearcher("*#||*||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards17()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards17();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec,
+            multiArgConstructor5Exec2, method2Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards17()
+   {
+      return new BehaviorSearcher("*#||||*||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards18()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards18();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec,
+            multiArgConstructor5Exec2, method2Exec1, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards18()
+   {
+      return new BehaviorSearcher("*#||||||*||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards19()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards19();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1,
+            multiArgConstructor5Exec2, method5Exec1, method5Exec3);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards19()
+   {
+      return new BehaviorSearcher("*#|* int ||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards20()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards20();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards20()
+   {
+      return new BehaviorSearcher("*#| int *||||||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards21()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards21();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards21()
+   {
+      return new BehaviorSearcher("*#| int ||||*||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards22()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards22();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards22()
+   {
+      return new BehaviorSearcher("*#| int ||||*" +
+            DummyAnnotationPojo.class.getName() + "  ", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards23()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards23();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards23()
+   {
+      return new BehaviorSearcher("*#| int ||||| " +
+            DummyAnnotationPojo.class.getName() + " * ", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards24()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards24();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards24()
+   {
+      return new BehaviorSearcher("*#| int ||* long ||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards25()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards25();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards25()
+   {
+      return new BehaviorSearcher("*#| int ||| long *||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards26()
+   {
+      BehaviorSearcher searcher = getMixedWildcardZeroOrMoreWildcards26();
+      searcher.setSearchType(SearchType.EXECUTION);
+      searcher.search(classNode, result);
+      Util.assertCollection(result, multiArgConstructor2Exec, method2Exec1);
+   }
+   
+   public BehaviorSearcher getMixedWildcardZeroOrMoreWildcards26()
+   {
+      return new BehaviorSearcher("*#| int ||* long *||", new ArrayList<ASTAttribute>(),
+            new ArrayList<ASTException>());
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CalleeSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CalleeSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CalleeSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,500 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.Aspect;
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTConstructor;
+import org.jboss.aop.pointcut.ast.ASTException;
+import org.jboss.aop.pointcut.ast.ASTMethod;
+import org.jboss.aop.pointcut.ast.ASTParameter;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+import org.jboss.aop.pointcut.ast.IdentifierExpression;
+
+/**
+ * Tests {@code CalleeSearcher}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class CalleeSearcherTest extends TestCase
+{
+   BehaviorNode behaviorNode1 = null;
+   // private void privateMethod()
+   MethodByMethodInfo pojo1MetByPojo3;
+   // public String stringMethod() throws ArrayIndexOutOfBoundsException, NullPointerException
+   MethodByMethodInfo pojo3MetByPojo3;
+   // public static final Pojo2 getPojo2()
+   MethodByMethodInfo pojo2MetByPojo3;
+   // public void method4(Pojo2 arg1, int arg2, long arg3)  throws IllegalArgumentException, IllegalStateException {}
+   MethodByMethodInfo annPojoMet4ByPojo3;
+   // public String method5(String arg1, int arg2, long arg3, DummyAnnotationPojo arg4,
+   // AnyAnnotationPojo arg5)
+   MethodByMethodInfo annPojoMet5ByPojo3;
+   // public void method6(DummyAnnotationPojo arg1, AnyAnnotationPojo arg2)
+   MethodByMethodInfo annPojoMet6ByPojo3;
+   // public AnyAnnotationPojo method7(AnyAnnotationPojo arg1)
+   MethodByMethodInfo annPojoMet7ByPojo3;
+   // public void interfaceMethod() throws NotImplementedException 
+   MethodByMethodInfo dummyAnnPojoMet1ByPojo3;
+   // public DummyAnnotationPojo interfaceMethod2  throws IllegalArgumentException, IllegalStateException
+   MethodByMethodInfo dummyAnnPojoMet2ByPojo3;
+   
+   BehaviorNode behaviorNode2 = null;
+   // @AnyAnnotation
+   // protected Pojo5(Collection arg)
+   ConByConInfo pojo5ConByPojo4Con;
+   // @Bind(pointcut="all(Pojo5)")
+   // public void calledByCon() throws NullPointerException, IllegalStateException
+   MethodByConInfo pojo5MetByPojo4Con;
+   
+   BehaviorNode behaviorNode3 = null;
+   // @Deprecated
+   // public Pojo5(Pojo3 pojo3) throws Exception
+   ConByMethodInfo pojo5ConByPojo4Met;
+   // @Mixin(interfaces={MetaDataKeyLoader.class})
+   // void calledByMethod()
+   MethodByMethodInfo pojo5MetByPojo4Met;
+   
+   
+   @SuppressWarnings("deprecation")
+   public void setUp() throws Exception
+   {  
+      // will be associated with fictitious scenarios
+      Advisor pojo4Advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
+      // will be associated with fictitious scenarios
+      Advisor pojo3Advisor = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      
+      // BehaviorNode2 (Fictitious Scenario)
+      Method callerMethod = Pojo3.class.getDeclaredMethod("voidMethod");
+      behaviorNode1 = new BehaviorNode(pojo3Advisor,
+               Pojo3.class.getDeclaredMethod("voidMethod"));
+      pojo1MetByPojo3 = new MethodByMethodInfo(pojo3Advisor, Pojo1.class,
+            Pojo1.class.getDeclaredMethod("privateMethod"), callerMethod, 0L, 0L,
+            new Interceptor[0]);
+      behaviorNode1.addCallee(pojo1MetByPojo3);
+      pojo3MetByPojo3 = new MethodByMethodInfo(pojo3Advisor, Pojo3.class,
+            Pojo3.class.getDeclaredMethod("stringMethod"), callerMethod, 0L, 0L,
+            new Interceptor[0]);
+      behaviorNode1.addCallee(pojo3MetByPojo3);
+      pojo2MetByPojo3 = new MethodByMethodInfo(pojo3Advisor, Pojo2.class,
+            Pojo2.class.getDeclaredMethod("getPojo2"), callerMethod, 0L, 0L,
+            new Interceptor[0]);
+      behaviorNode1.addCallee(pojo2MetByPojo3);
+      annPojoMet4ByPojo3 = new MethodByMethodInfo(pojo3Advisor, AnnPojo.class,
+            AnnPojo.class.getDeclaredMethod("method4", Pojo2.class, int.class,
+                  long.class), callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(annPojoMet4ByPojo3);
+      annPojoMet5ByPojo3 = new MethodByMethodInfo(pojo3Advisor, AnnPojo.class,
+            AnnPojo.class.getDeclaredMethod("method5", String.class, int.class,
+                  long.class, DummyAnnotationPojo.class, AnyAnnotationPojo.class),
+                  callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(annPojoMet5ByPojo3);
+      annPojoMet6ByPojo3 = new MethodByMethodInfo(pojo3Advisor, AnnPojo.class,
+            AnnPojo.class.getDeclaredMethod("method6", DummyAnnotationPojo.class,
+                 AnyAnnotationPojo.class), callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(annPojoMet6ByPojo3);
+      annPojoMet7ByPojo3 = new MethodByMethodInfo(pojo3Advisor, AnnPojo.class,
+            AnnPojo.class.getDeclaredMethod("method7", AnyAnnotationPojo.class),
+                  callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(annPojoMet7ByPojo3);
+      dummyAnnPojoMet1ByPojo3 = new MethodByMethodInfo(pojo3Advisor,
+            DummyAnnotationPojo.class,
+            DummyAnnotationPojo.class.getDeclaredMethod("interfaceMethod"),
+            callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(dummyAnnPojoMet1ByPojo3);
+      dummyAnnPojoMet2ByPojo3 = new MethodByMethodInfo(pojo3Advisor,
+            DummyAnnotationPojo.class,
+            DummyAnnotationPojo.class.getDeclaredMethod("interfaceMethod2"),
+            callerMethod, 0L, 0L, new Interceptor[0]);
+      behaviorNode1.addCallee(dummyAnnPojoMet2ByPojo3);
+      
+      // BehaviorNode2 (Fictitious Scenario)
+      Constructor callerConstructor = Pojo4.class.getDeclaredConstructor();
+      behaviorNode2 = new BehaviorNode(pojo4Advisor, callerConstructor);
+      pojo5ConByPojo4Con = new ConByConInfo(pojo4Advisor, Pojo5.class,
+            callerConstructor.getDeclaringClass(), 0,
+            Pojo5.class.getDeclaredConstructor(Collection.class), 0L, null,
+            new Interceptor[0]);
+      behaviorNode2.addCallee(pojo5ConByPojo4Con);
+      pojo5MetByPojo4Con = new MethodByConInfo(pojo4Advisor,
+            Pojo5.class, Pojo4.class, 0,
+            Pojo5.class.getDeclaredMethod("calledByCon"), 0L, new Interceptor[0]);
+      behaviorNode2.addCallee(pojo5MetByPojo4Con);
+      
+      // BehaviorNode3 (Fictitious Scenario)
+      callerMethod = Pojo4.class.getDeclaredMethod("callMethod");
+      behaviorNode3 = new BehaviorNode(pojo4Advisor, callerMethod);
+      pojo5ConByPojo4Met = new ConByMethodInfo(pojo4Advisor, Pojo5.class,
+            callerMethod, 0L, Pojo5.class.getDeclaredConstructor(Pojo3.class), 0L,
+            null, new Interceptor[0]);
+      behaviorNode3.addCallee(pojo5ConByPojo4Met);
+      pojo5MetByPojo4Met = new MethodByMethodInfo(pojo4Advisor, Pojo5.class,
+            Pojo5.class.getDeclaredMethod("calledByMethod"), callerMethod, 0L, 0L,
+            new Interceptor[0]);
+      behaviorNode3.addCallee(pojo5MetByPojo4Met);
+   }
+   
+   public void testDisjunctiveCalleeSearcher1()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PRIVATE);
+      attributes.add(attribute);
+      CalleeSearcher searcher1 = CalleeSearcherFactory.create("*", attributes,
+            new ArrayList<ASTException>());
+      attributes = new ArrayList<ASTAttribute>();
+      attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PROTECTED);
+      attributes.add(attribute);
+      CalleeSearcher searcher2 = CalleeSearcherFactory.create("*", attributes,
+            new ArrayList<ASTException>());
+      CalleeSearcher searcher = new DisjunctiveCalleeSearcher(searcher1, searcher2);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo1MetByPojo3},
+            {pojo5ConByPojo4Con},{}});
+   }
+   
+   public void testDisjunctiveCalleeSearcher2()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception = new ASTException(0);
+      exception.setTypeExpression("*");
+      exceptions.add(exception);
+      CalleeSearcher searcher1 = CalleeSearcherFactory.create("*",
+            new ArrayList<ASTAttribute>(), exceptions);
+      IdentifierExpression exp = new IdentifierExpression("$implements{" +
+            DummyInterface.class.getName() + "}");
+      CalleeSearcher searcher2 = CalleeSearcherFactory.create("*.* *(*)",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            new ImplementedMethodFilter(exp));
+      CalleeSearcher searcher = new DisjunctiveCalleeSearcher(searcher1, searcher2);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         annPojoMet4ByPojo3, dummyAnnPojoMet1ByPojo3, dummyAnnPojoMet2ByPojo3},
+         {pojo5MetByPojo4Con},{pojo5ConByPojo4Met}});
+   }
+   
+   public void testDisjunctiveCalleeSearcher3()
+   {
+      CalleeSearcher subSearcher = CalleeSearcherFactory.create("*|void| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      CalleeSearcher searcher1 = new NegativeCalleeSearcher(subSearcher);
+      // Constructors
+      CalleeSearcher searcher2 = CalleeSearcherFactory.create("*|@*#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      CalleeSearcher searcher = new DisjunctiveCalleeSearcher(searcher1, searcher2);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         pojo2MetByPojo3, annPojoMet5ByPojo3, annPojoMet7ByPojo3,
+         dummyAnnPojoMet2ByPojo3}, {pojo5ConByPojo4Con}, {pojo5ConByPojo4Met}});
+      // Methods
+      searcher2 = CalleeSearcherFactory.create("*|*| @*#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher = new DisjunctiveCalleeSearcher(searcher1, searcher2);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         pojo2MetByPojo3, annPojoMet5ByPojo3, annPojoMet7ByPojo3,
+         dummyAnnPojoMet2ByPojo3}, {pojo5ConByPojo4Con, pojo5MetByPojo4Con},
+         {pojo5ConByPojo4Met, pojo5MetByPojo4Met}});
+   }
+   
+   public void testNegativeCalleeSearcher1()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException exception1 = new ASTException(1);
+      exception1.setTypeExpression(IllegalStateException.class.getName());
+      exceptions.add(exception1);
+      ASTException exception2 = new ASTException(1);
+      exception2.setTypeExpression(IllegalArgumentException.class.getName());
+      exceptions.add(exception2);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*",
+            new ArrayList<ASTAttribute>(), exceptions);
+      CalleeSearcher negativeSearcher = new NegativeCalleeSearcher(searcher);
+      assertSearcher(negativeSearcher, new JoinPointInfo[][]{{pojo1MetByPojo3,
+         pojo3MetByPojo3, pojo2MetByPojo3, annPojoMet5ByPojo3, annPojoMet6ByPojo3,
+         annPojoMet7ByPojo3, dummyAnnPojoMet1ByPojo3}, {pojo5ConByPojo4Con,
+         pojo5MetByPojo4Con}, {pojo5ConByPojo4Met, pojo5MetByPojo4Met}});
+   }
+   
+   public void testNegativeCalleeSearcher2()
+   {
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|void| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      CalleeSearcher negativeSearcher = new NegativeCalleeSearcher(searcher);
+      assertSearcher(negativeSearcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         pojo2MetByPojo3, annPojoMet5ByPojo3, annPojoMet7ByPojo3,
+         dummyAnnPojoMet2ByPojo3}, {pojo5ConByPojo4Con}, {pojo5ConByPojo4Met}});
+   }
+   
+   public void testNegativeCalleeSearcher3() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(@" +
+            DummyAnnotation.class.getName() + ") OR has(int *->length()) OR" +
+                  "class($instanceof{@" + Deprecated.class.getName() + "})");
+      AspectManager.instance().addTypedef(typedef);
+      ASTParameter parameter1 = new ASTParameter(1);
+      ASTParameter parameter2 = new ASTParameter(1);
+      ASTParameter parameter3 = new ASTParameter(1);
+      parameter1.setTypeExpression("..");
+      parameter2.setTypeExpression("$typedef{ComplexExp}");
+      parameter3.setTypeExpression("..");
+      // astMethod
+      ASTMethod astMethod = new ASTMethod(0);
+      astMethod.jjtAddChild(parameter3, 0);
+      astMethod.jjtAddChild(parameter2, 0);
+      astMethod.jjtAddChild(parameter1, 0);
+      BehaviorFilter behaviorFilter = new FullParameterFilter(astMethod);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            behaviorFilter);
+      CalleeSearcher negativeSearcher = new NegativeCalleeSearcher(searcher);
+      assertSearcher(negativeSearcher, new JoinPointInfo[][]{{pojo1MetByPojo3,
+            pojo3MetByPojo3, pojo2MetByPojo3, annPojoMet7ByPojo3,
+            dummyAnnPojoMet1ByPojo3, dummyAnnPojoMet2ByPojo3},
+            {pojo5ConByPojo4Con, pojo5MetByPojo4Con}, {pojo5ConByPojo4Met,
+               pojo5MetByPojo4Met}});
+   }
+   
+   public void testOptimizedCalleeSearcher1()
+   {
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|void| *ethod*#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      assertTrue(searcher instanceof OptimizedCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo1MetByPojo3,
+            annPojoMet4ByPojo3, annPojoMet6ByPojo3, dummyAnnPojoMet1ByPojo3}, {},
+            {pojo5MetByPojo4Met}});
+   }
+   
+   public void testOptimizedCalleeSearcher2()
+   {
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|new#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      assertTrue(searcher instanceof OptimizedCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{}, {pojo5ConByPojo4Con},
+            {pojo5ConByPojo4Met}});
+   }
+   
+   public void testOptimizedCalleeSearcher3()
+   {
+      CalleeSearcher searcher = CalleeSearcherFactory.create("@" +
+            DummyAnnotation.class.getName() + "|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      assertTrue(searcher instanceof OptimizedCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         dummyAnnPojoMet1ByPojo3, dummyAnnPojoMet2ByPojo3}, {}, {}});
+   }
+   
+   public void testAttExcCalleeSearcher1()
+   {
+      Collection<ASTAttribute> atts = new ArrayList<ASTAttribute>();
+      ASTAttribute astAttribute = new ASTAttribute(0);
+      astAttribute.setValue(Modifier.PUBLIC);
+      atts.add(astAttribute);
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException astException = new ASTException(0);
+      astException.setTypeExpression("$instanceof{" + Exception.class.getName() + "}");
+      exceptions.add(astException);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*", atts, exceptions);
+      assertTrue(searcher instanceof AttExcCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo3MetByPojo3,
+         annPojoMet4ByPojo3, dummyAnnPojoMet1ByPojo3, dummyAnnPojoMet2ByPojo3},
+         {pojo5MetByPojo4Con}, {pojo5ConByPojo4Met}});
+   }
+   
+   public void testAttExcCalleeSearcher2()
+   {
+      Collection<ASTAttribute> atts = new ArrayList<ASTAttribute>();
+      ASTAttribute astAttribute = new ASTAttribute(0);
+      astAttribute.setValue(Modifier.PROTECTED);
+      atts.add(astAttribute);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*", atts,
+            new ArrayList<ASTException>());
+      assertTrue(searcher instanceof AttExcCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{}, {pojo5ConByPojo4Con}, {}});
+   }
+   
+   public void testAttExcCalleeSearcher3()
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException astException = new ASTException(0);
+      astException.setTypeExpression(IllegalStateException.class.getName());
+      exceptions.add(astException);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*",
+            new ArrayList<ASTAttribute>(), exceptions);
+      assertTrue(searcher instanceof AttExcCalleeSearcher);
+      assertSearcher(searcher, new JoinPointInfo[][]{{annPojoMet4ByPojo3, dummyAnnPojoMet2ByPojo3},
+            {pojo5MetByPojo4Con}, {}});
+   }
+   
+   public void testFilteredCalleeSearcher1()
+   {
+      BehaviorFilter behaviorFilter = new TargetTypeFilter(new ClassExpression(
+            "@" + Aspect.class.getName()));
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            behaviorFilter);
+      assertTrue(searcher instanceof FilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{},
+            {pojo5ConByPojo4Con, pojo5MetByPojo4Con},
+            {pojo5ConByPojo4Met, pojo5MetByPojo4Met}});
+   }
+   
+   public void testFilteredCalleeSearcher2()
+   {
+      PartialParameterFilter behaviorFilter = new DescendingPartialParameterFilter(1);
+      behaviorFilter.addParameterRestriction(new ClassExpression(
+            "@" + AnyAnnotation.class.getName()), 0);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|*| *#||",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            behaviorFilter);
+      assertTrue(searcher instanceof FilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{annPojoMet7ByPojo3}, {}, {}});
+   }
+   
+   public void testFilteredCalleeSearcher3() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(@" +
+            DummyAnnotation.class.getName() + ") OR has(int *->length()) OR" +
+                  "class($instanceof{@" + Deprecated.class.getName() + "})");
+      AspectManager.instance().addTypedef(typedef);
+      ASTParameter parameter1 = new ASTParameter(1);
+      ASTParameter parameter2 = new ASTParameter(1);
+      ASTParameter parameter3 = new ASTParameter(1);
+      parameter1.setTypeExpression("..");
+      parameter2.setTypeExpression("$typedef{ComplexExp}");
+      parameter3.setTypeExpression("..");
+      // astMethod
+      ASTMethod astMethod = new ASTMethod(0);
+      astMethod.jjtAddChild(parameter3, 0);
+      astMethod.jjtAddChild(parameter2, 0);
+      astMethod.jjtAddChild(parameter1, 0);
+      BehaviorFilter behaviorFilter = new FullParameterFilter(astMethod);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            behaviorFilter);
+      assertTrue(searcher instanceof FilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{annPojoMet4ByPojo3,
+         annPojoMet5ByPojo3, annPojoMet6ByPojo3}, {}, {}});
+      // astConstructor
+      ASTConstructor astConstructor = new ASTConstructor(0);
+      astConstructor.jjtAddChild(parameter3, 0);
+      astConstructor.jjtAddChild(parameter2, 0);
+      astConstructor.jjtAddChild(parameter1, 0);
+      behaviorFilter = new FullParameterFilter(astConstructor);
+      searcher = CalleeSearcherFactory.create("*|new#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>(),
+            behaviorFilter);
+      assertTrue(searcher instanceof FilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{}, {}, {pojo5ConByPojo4Met}});
+   }
+   
+   public void testAttExcFilteredCalleeSearcher1()
+   {
+      Collection<ASTAttribute> atts = new ArrayList<ASTAttribute>();
+      ASTAttribute astAttribute = new ASTAttribute(0);
+      astAttribute.setValue(Modifier.PUBLIC);
+      atts.add(astAttribute);
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException astException = new ASTException(0);
+      astException.setTypeExpression(Exception.class.getName());
+      exceptions.add(astException);
+      BehaviorFilter behaviorFilter = new TargetTypeFilter(new ClassExpression(
+            "@" + Aspect.class.getName()));
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*", atts,
+            exceptions, behaviorFilter);
+      assertTrue(searcher instanceof AttExcFilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{}, {}, {pojo5ConByPojo4Met}});
+   }
+   
+   public void testAttExcFilteredCalleeSearcher2()
+   {
+      Collection<ASTAttribute> atts = new ArrayList<ASTAttribute>();
+      ASTAttribute astAttribute1 = new ASTAttribute(0);
+      astAttribute1.setValue(Modifier.STATIC);
+      ASTAttribute astAttribute2 = new ASTAttribute(0);
+      astAttribute2.setValue(Modifier.FINAL);
+      atts.add(astAttribute1);
+      atts.add(astAttribute2);
+      BehaviorFilter behaviorFilter = new ReturnTypeFilter(new ClassExpression(
+            "@" + Deprecated.class.getName()));
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|*| *#", atts,
+            new ArrayList<ASTException>(), behaviorFilter);
+      assertTrue(searcher instanceof AttExcFilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{pojo2MetByPojo3}, {}, {}});
+   }
+   
+   public void testAttExcFilteredCalleeSearcher3() throws Exception
+   {
+      Collection<ASTException> exceptions = new ArrayList<ASTException>();
+      ASTException astException = new ASTException(0);
+      astException.setTypeExpression("$instanceof{" + Exception.class.getName() + "}");
+      exceptions.add(astException);
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(@" +
+            DummyAnnotation.class.getName() + ") OR has(int *->length()) OR" +
+                  "class($instanceof{@" + Deprecated.class.getName() + "})");
+      AspectManager.instance().addTypedef(typedef);
+      ASTMethod astBehavior= new ASTMethod(0);
+      ASTParameter parameter1 = new ASTParameter(1);
+      ASTParameter parameter2 = new ASTParameter(1);
+      ASTParameter parameter3 = new ASTParameter(1);
+      parameter1.setTypeExpression("..");
+      parameter2.setTypeExpression("$typedef{ComplexExp}");
+      parameter3.setTypeExpression("..");
+      astBehavior.jjtAddChild(parameter3, 0);
+      astBehavior.jjtAddChild(parameter2, 0);
+      astBehavior.jjtAddChild(parameter1, 0);
+      BehaviorFilter behaviorFilter = new FullParameterFilter(astBehavior);
+      CalleeSearcher searcher = CalleeSearcherFactory.create("*|*| *#*",
+            new ArrayList<ASTAttribute>(), exceptions, behaviorFilter);
+      assertTrue(searcher instanceof AttExcFilteredCalleeRestriction);
+      assertSearcher(searcher, new JoinPointInfo[][]{{annPojoMet4ByPojo3}, {}, {}});
+   }
+   
+   private void assertSearcher(CalleeSearcher searcher, JoinPointInfo[][] results)
+   {
+      assertEquals(3, results.length);
+      Collection<JoinPointInfo> result = new HashSet<JoinPointInfo>();
+      searcher.search(behaviorNode1, result);
+      Util.assertCollection(result, results[0]);
+      result.clear();
+      searcher.search(behaviorNode2, result);
+      Util.assertCollection(result, results[1]);
+      result.clear();
+      searcher.search(behaviorNode3, result);
+      Util.assertCollection(result, results[2]);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassNodeTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassNodeTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassNodeTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -101,7 +101,8 @@
       AdvisedData classAdvisedData = classNode.getAdvisedData(advisor);
       AdvisedData instanceAdvisedData = classNode.getAdvisedData(instanceAdvisor);
       classAdvisedData = classNode.getAdvisedData(advisor);
-      assertClassNode(Pojo3.class, classNode, advisor, Pojo3.class.getName());
+      assertClassNode(Pojo3.class, classNode, advisor, Pojo3.class.getName(),
+            "@" + DummyAnnotation.class.getName());
       assertNotSame(instanceAdvisedData, classAdvisedData);
       assertTrue(instanceAdvisedData instanceof AdvisedData);
       assertSame(instanceAdvisor, instanceAdvisedData.getAdvisor());

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ClassSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,369 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutExpression;
+
+/**
+ * Tests {@link SearchKeyParser} on expressions containing exclusively class
+ * expressions (has and within) and on expressions containing complex class
+ * expressions.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class ClassSearchKeyParserTest extends AbstractSearchKeyParserTest
+{
+   public void testAll() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(org.company.Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "org.company.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testAllWildcards1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(org.company.*.Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "org.company.*.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testAllWildcards2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "*");
+      assertNull(filter);
+   }
+   
+   public void testAllWildcards3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(*Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "*Pojo");
+      assertNull(filter);
+   }
+   
+   public void testAllWildcards4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(Pojo*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "Pojo*");
+      assertNull(filter);
+   }
+   
+   public void testAllAnnotation1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(@org.company.AnyAnnotation)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "@org.company.AnyAnnotation");
+      assertNull(filter);
+   }
+   
+   public void testAllAnnotation2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(@*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "@*");
+      assertNull(filter);
+   }
+   
+   public void testAllAnnotation3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all(@*Annotation)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "@*Annotation");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceof1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{org.company.Pojo})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "org.company.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceof2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{java.lang.Object})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "java.lang.Object");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceof3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{org.jboss.aop.Pojo})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "org.jboss.aop.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceofAnnotated1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{@AnyInterface})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "@AnyInterface");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceofAnnotated2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{@*})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "@*");
+      assertNull(filter);
+   }
+   
+   public void testAllInstanceofAnnotated3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($instanceof{@Annotation*})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeAllSearchKey(searchKey, "@Annotation*");
+      assertNull(filter);
+   }
+   
+   public void testAllTypedef() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "all($typedef{typedef})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertAllSearchKey(searchKey, "TypedefClass");
+      assertTypedefFilter(filter, "typedef");
+   }
+   
+   public void testWithin() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(org.company.Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "org.company.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testWithinWildcards1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(org.company.*.Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "org.company.*.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testWithinWildcards2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "*");
+      assertNull(filter);
+   }
+   
+   public void testWithinWildcards3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(*Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "*Pojo");
+      assertNull(filter);
+   }
+   
+   public void testWithinWildcards4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(Pojo*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "Pojo*");
+      assertNull(filter);
+   }
+   
+   public void testWithinAnnotation1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(@org.company.AnyAnnotation)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "@org.company.AnyAnnotation");
+      assertNull(filter);
+   }
+   
+   public void testWithinAnnotation2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(@*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "@*");
+      assertNull(filter);
+   }
+   
+   public void testWithinAnnotation3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within(@*Annotation)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "@*Annotation");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceof1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{org.company.Pojo})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "org.company.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceof2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{java.lang.Object})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "java.lang.Object");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceof3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{org.jboss.aop.Pojo})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "org.jboss.aop.Pojo");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceofAnnotated1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{@AnyInterface})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "@AnyInterface");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceofAnnotated2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{@*})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "@*");
+      assertNull(filter);
+   }
+   
+   public void testWithinInstanceofAnnotated3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($instanceof{@Annotation*})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeWithinSearchKey(searchKey, "@Annotation*");
+      assertNull(filter);
+   }
+   
+   public void testWithinTypedef() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "within($typedef{typedef})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertWithinSearchKey(searchKey, "TypedefClass");
+      assertTypedefFilter(filter, "typedef");
+   }
+   
+   public void testAnnotation1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "construction(@org.company.AnyAnnotation->new(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter behaviorFilter = assertBehaviorSearchKey(searchKey,
+            "@org.company.AnyAnnotation", "new#*",
+            BehaviorSearcher.SearchType.CONSTRUCTION);
+      assertNull(behaviorFilter);
+      assertNull(typeFilterField.get(searchKey));
+   }
+   
+   public void testAnnotation2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "execution(@*->new(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter behaviorFilter = assertBehaviorSearchKey(searchKey, "@*",
+            "new#*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(behaviorFilter);
+      assertNull(typeFilterField.get(searchKey));
+   }
+   
+   public void testAnnotation3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+               "execution(int @*Annotation->execute())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter behaviorFilter = assertBehaviorSearchKey(searchKey,
+            "@*Annotation", "int| execute#", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(behaviorFilter);
+      assertNull(typeFilterField.get(searchKey));
+   }
+   
+   public void testInstanceof1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode($instanceof{org.company.Pojo}->@Annotation(int, long, char))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeBehaviorSearchKey(searchKey,
+            "org.company.Pojo", "@Annotation#| int | long | char  ",
+            BehaviorSearcher.SearchType.CALL);
+      assertNull(filter);
+   }
+   
+   public void testInstanceof2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void $instanceof{java.lang.Object}->doIt())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeBehaviorSearchKey(searchKey,
+            "java.lang.Object", "void| doIt#", BehaviorSearcher.SearchType.CALL);
+      assertNull(filter);
+   }
+   
+   public void testInstanceof3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "field(int $instanceof{org.jboss.aop.Pojo}->counter)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeFieldSearchKey(searchKey,
+            "org.jboss.aop.Pojo","int counter", null, FieldSearcher.SearchType.ALL);
+      assertNull(filter);
+   }
+   
+   public void testInstanceofAnnotated1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "get(java.lang.String $instanceof{@AnyInterface}->id)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeFieldSearchKey(searchKey, "@AnyInterface",
+            "java.lang.String id", null, FieldSearcher.SearchType.READ);
+      assertNull(filter);
+   }
+   
+   public void testInstanceofAnnotated2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "set(java.util.Date $instanceof{@*}->currentDate)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      TypeFilter filter = assertSubtypeFieldSearchKey(searchKey, "@*",
+            "java.util.Date currentDate", null, FieldSearcher.SearchType.WRITE);
+      assertNull(filter);
+   }
+   
+   public void testTypedef() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode($typedef{typedef}->new(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter behaviorFilter = assertBehaviorSearchKey(searchKey,
+            "TypedefClass", "new#*", BehaviorSearcher.SearchType.CALL);
+      assertNull(behaviorFilter);
+      TypeFilter filter = (TypeFilter) typeFilterField.get(searchKey);
+      assertTypedefFilter(filter, "typedef");
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeDomainDataTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeDomainDataTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeDomainDataTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -263,39 +263,39 @@
             behaviorNode2, behaviorNode3, behaviorNode4, behaviorNode5, behaviorNode6,
             behaviorNode7, behaviorNode8, behaviorNode9, behaviorNode10,
             behaviorNode11, behaviorNode12, behaviorNode13, behaviorNode14);
-      Util.assertCollection(compositeData.searchBehaviors("*(*)"), behaviorNode1,
+      Util.assertCollection(compositeData.searchBehaviors("*#*"), behaviorNode1,
             behaviorNode2, behaviorNode3, behaviorNode4, behaviorNode5, behaviorNode6,
             behaviorNode7, behaviorNode8, behaviorNode9, behaviorNode10,
             behaviorNode11, behaviorNode12, behaviorNode13, behaviorNode14);
-      Util.assertCollection(compositeData.searchBehaviors("new(*)"),
+      Util.assertCollection(compositeData.searchBehaviors("new#*"),
             behaviorNode1, behaviorNode2, behaviorNode3, behaviorNode4, behaviorNode5);
-      Util.assertCollection(compositeData.searchBehaviors("*()"),
+      Util.assertCollection(compositeData.searchBehaviors("*#"),
             behaviorNode1, behaviorNode2, behaviorNode6, behaviorNode7);
       Util.assertCollection(compositeData.searchBehaviors("*int*"),
             behaviorNode3, behaviorNode4, behaviorNode5, behaviorNode8,
             behaviorNode9, behaviorNode10, behaviorNode11, behaviorNode12);
-      Util.assertCollection(compositeData.searchBehaviors("void someMethod(*)"),
+      Util.assertCollection(compositeData.searchBehaviors("void| someMethod#*"),
             behaviorNode8, behaviorNode9, behaviorNode10, behaviorNode11,
             behaviorNode12);
-      Util.assertCollection(compositeData.searchBehaviors("* someMethod(*)"),
+      Util.assertCollection(compositeData.searchBehaviors("*| someMethod#*"),
             behaviorNode8, behaviorNode9, behaviorNode10, behaviorNode11,
             behaviorNode12, behaviorNode13, behaviorNode14);
       
-      Util.assertCollection(compositeData.searchBehaviors("new()"),
+      Util.assertCollection(compositeData.searchBehaviors("new#"),
             behaviorNode1, behaviorNode2);
-      Util.assertCollection(compositeData.searchBehaviors("new(int long )"),
+      Util.assertCollection(compositeData.searchBehaviors("new#| int | long  "),
             behaviorNode3);
-      Util.assertCollection(compositeData.searchBehaviors("new(int java.lang.String )"),
+      Util.assertCollection(compositeData.searchBehaviors("new#| int | java.lang.String  "),
             behaviorNode4, behaviorNode5);
-      Util.assertCollection(compositeData.searchBehaviors("void voidMethod()"),
+      Util.assertCollection(compositeData.searchBehaviors("void| voidMethod#"),
             behaviorNode6);
       Util.assertCollection(compositeData.searchBehaviors(
-            "java.lang.String stringMethod()"), behaviorNode7);
-      Util.assertCollection(compositeData.searchBehaviors( "void someMethod(int long )"),
+            "java.lang.String| stringMethod#"), behaviorNode7);
+      Util.assertCollection(compositeData.searchBehaviors( "void| someMethod#| int | long  "),
             behaviorNode8, behaviorNode9, behaviorNode10, behaviorNode11,
             behaviorNode12);
       Util.assertCollection(compositeData.searchBehaviors(
-            "java.lang.String someMethod(java.lang.String long )"),
+            "java.lang.String| someMethod#| java.lang.String | long  "),
             behaviorNode13, behaviorNode14);
    }
 }
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/CompositeSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,749 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Modifier;
+
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+
+/**
+ * Tests {@link SearchKeyParser} on composite pointcuts.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class CompositeSearchKeyParserTest extends AbstractSearchKeyParserTest
+{
+   public void testCallAndWithinCode() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND withincode(void $instanceof{PojoClient}->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testCallAndWithin() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND within($instanceof{PojoClient})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testWithinAndCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND call(* org.jboss.Pojo->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testWithinAndNotCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND !call(* org.jboss.Pojo->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testCallAndWithinAndWithinCode() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND within($instanceof{PojoClient}) AND withincode(*->new())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey1 = getSearchKey1(searchKey, true);
+      SearchKey searchKey2 = getSearchKey2(searchKey, true);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey2,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      callee = assertBehaviorCallSearchKey(searchKey1, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testCallAndWithinAndWithinAndWithinAndWithinCode() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND within($instanceof{PojoClient}) " +
+         "AND withincode(*->new()) AND within(*) AND withincode(*->@AnyAnnotation())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey2 = getSearchKey2(searchKey, true);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey2, "*", "@AnyAnnotation#");
+      assertNull(callee);
+      searchKey = getSearchKey1(searchKey, true);
+      searchKey2 = getSearchKey2(searchKey, true);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "*");
+      assertNull(callee);
+      searchKey = getSearchKey1(searchKey, true);
+      searchKey2 = getSearchKey2(searchKey, true);
+      callee = assertSubtypeBehaviorCallSearchKey(searchKey2,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey searchKey1 = getSearchKey1(searchKey, true);
+       callee = assertBehaviorCallSearchKey(searchKey1, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testCallAndCallAndWithinCode() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int)) " +
+            "AND withincode(void $instanceof{PojoClient}->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testNotCallAndCallAndWithinCode() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "!(call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int))) " +
+            "AND withincode(void $instanceof{PojoClient}->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testWithinCodeAndNotCallAndCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void $instanceof{PojoClient}->*(..)) AND" +
+            "!(call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testCallAndWithinOrWithin() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND (within($instanceof{PojoClient}) OR " +
+         "withincode(*->new()))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey1 = getSearchKey1(searchKey, false);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey1,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey searchKey2 = getSearchKey2(searchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testCallAndNotWithinOrWithin() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND !(within($instanceof{PojoClient}) OR " +
+         "withincode(*->new()))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey negativeSearchKey = getNegativeSearchKey(searchKey, 0, 1);
+      SearchKey searchKey1 = getSearchKey1(negativeSearchKey, false);
+      callee = assertSubtypeBehaviorCallSearchKey(searchKey1, "PojoClient", "*");
+      assertNull(callee);
+      SearchKey searchKey2 = getSearchKey2(negativeSearchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testWithinOrWithinAndCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "(within($instanceof{PojoClient}) OR withincode(*->new())) AND " +
+         "call(* org.jboss.Pojo->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey1 = getSearchKey1(searchKey, false);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey1,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey searchKey2 = getSearchKey2(searchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testNotWithinOrWithinAndCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "!(within($instanceof{PojoClient}) OR withincode(*->new())) AND " +
+         "call(* org.jboss.Pojo->*(..))"); 
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey negativeSearchKey = getNegativeSearchKey(searchKey, 0, 1);
+      SearchKey searchKey1 = getSearchKey1(negativeSearchKey, false);
+      callee = assertSubtypeBehaviorCallSearchKey(searchKey1, "PojoClient", "*");
+      assertNull(callee);
+      SearchKey searchKey2 = getSearchKey2(negativeSearchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testWithinAndCallOrCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND (call(* org.jboss.Pojo->*(..)) OR" +
+            " call(org.jboss.Pojo->new(..)) OR call(* org.jboss.Pojo2->*(..)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      CalleeSearcher subCallee = getRestriction1(callee, false);
+      assertSimpleCalleeRestriction(getRestriction1(subCallee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(subCallee, false),
+            "org.jboss.Pojo|new#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo2|*| *#*");
+   }
+   
+   public void testCallOrCallOrCallAndWithin() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..)) OR " +
+            "call(* org.jboss.Pojo2->*(..))) AND within($instanceof{PojoClient})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      CalleeSearcher subCallee = getRestriction1(callee, false);
+      assertSimpleCalleeRestriction(getRestriction1(subCallee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(subCallee, false),
+            "org.jboss.Pojo|new#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo2|*| *#*");
+   }
+   
+   public void testWithinOrWithinAndCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(within($instanceof{PojoClient}) OR within(org.jboss.aop.*)) AND " +
+            "(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(
+            getSearchKey1(searchKey, false), "PojoClient", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, false),
+            "org.jboss.aop.*", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+   }
+   
+   public void testNotWithinOrWithinAndCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "!(within($instanceof{PojoClient}) OR within(org.jboss.aop.*)) AND " +
+            "(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+      searchKey = getNegativeSearchKey(searchKey, 0, 1);
+      callee = assertSubtypeBehaviorCallSearchKey(getSearchKey1(searchKey, false),
+            "PojoClient", "*");
+      assertNull(callee);
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, false),
+            "org.jboss.aop.*", "*");
+      assertNull(callee);
+   }
+   
+   public void testWithinOrWithinAndNotCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(within($instanceof{PojoClient}) OR within(org.jboss.aop.*)) AND " +
+            "!(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(
+            getSearchKey1(searchKey, false), "PojoClient", "*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, false),
+            "org.jboss.aop.*", "*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+   }
+   
+   public void testNotWithinOrWithinAndNotCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "!(within($instanceof{PojoClient}) OR within(org.jboss.aop.*)) AND " +
+            "!(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..)))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+      searchKey = getNegativeSearchKey(searchKey, 0, 1);
+      callee = assertSubtypeBehaviorCallSearchKey(getSearchKey1(searchKey, false),
+            "PojoClient", "*");
+      assertNull(callee);
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, false),
+            "org.jboss.aop.*", "*");
+      assertNull(callee);
+   }
+   
+   public void testNegativeWithinOrWithinAndCallOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "!((within($instanceof{PojoClient}) OR within(org.jboss.aop.*)) AND " +
+            "(call(* org.jboss.Pojo->*(..)) OR call(org.jboss.Pojo->new(..))))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertBehaviorSearchKey(getSearchKey1(searchKey, false), "*", "*",
+         BehaviorSearcher.SearchType.ALL);
+      assertFieldSearchKey(getSearchKey2(searchKey, false), "*", "*", null,
+            FieldSearcher.SearchType.ALL);
+      searchKey = getNegativeSearchKey(searchKey, 0, 1);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(
+            getSearchKey1(searchKey, false), "PojoClient", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, false),
+            "org.jboss.aop.*", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, false),
+            "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, false),
+            "org.jboss.Pojo|new#*");
+   }
+   
+   public void testCallAndWithinCodeWithHas1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND has(* *->*(int)) AND " +
+            "withincode(void $instanceof{PojoClient}->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SubtypeSearcher searcher = assertSubtypeSearchKey(searchKey, "PojoClient");
+      assertHasBehaviorFilter((TypeFilter) subtypeSearcherTypeFilterField.get(searcher));
+   }
+   
+   public void testCallAndWithinCodeWithHas2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND has(* *->*(int)) AND " +
+            "withincode(void $typedef{typedef}->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey,
+            "TypedefClass", "void| *#*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      TypeFilter typeFilter = (TypeFilter) typeFilterField.get(searchKey);
+      assertHasBehaviorFilter(getTypeFilter1(typeFilter, true));
+      assertTypedefFilter(getTypeFilter2(typeFilter, true), "typedef");
+   }
+   
+   public void testCallAndWithinWithHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND hasfield(int *->counter) AND " +
+            "within($instanceof{PojoClient})");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SubtypeSearcher searcher = assertSubtypeSearchKey(searchKey, "PojoClient");
+      assertHasFieldFilter((TypeFilter) subtypeSearcherTypeFilterField.get(searcher));
+   }
+   
+   public void testWithinAndCallWithHas1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND (call(* org.jboss.Pojo->*(..)) " +
+            "OR hasfield(int *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, true);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(subSearchKey,
+            "PojoClient", "*");
+      assertNull(callee);
+      callee = assertBehaviorCallSearchKey(getSearchKey2(searchKey, true), "*", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      assertNull((TypeFilter) typeFilterField.get(getSearchKey2(searchKey, true)));
+   }
+   
+   public void testWithinAndCallWithHas2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND call(* org.jboss.Pojo->*(..)) " +
+            "OR hasfield(int *->counter)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+   }
+   
+   public void testWithinAndNotCallWitHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "within($instanceof{PojoClient}) AND !call(* org.jboss.Pojo->*(..))" +
+            " AND !has(void *->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "*");
+      callee = assertNegativeCalleeRestriction(callee);
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      TypeFilter typeFilter = (TypeFilter) subtypeSearcherTypeFilterField.get(
+            assertSubtypeSearchKey(searchKey, "PojoClient"));
+      typeFilter = assertNegativeTypeFilter(typeFilter);
+      assertHasBehaviorFilter(typeFilter);
+   }
+   
+   public void testCallAndCallAndWithinCodeWithHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int)) " +
+            "AND withincode(void $instanceof{PojoClient}->*(..)) OR hasfield(int *->counter)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testNotCallAndCallAndWithinCodeWithHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "!(call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int)) AND has(*->new())) " +
+            "AND withincode(void $instanceof{PojoClient}->*(..)) AND hasfield(int *->counter)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertNull(callee);
+      assertHasFieldFilter((TypeFilter) subtypeSearcherTypeFilterField.get(
+            assertSubtypeSearchKey(searchKey, "PojoClient")));
+      searchKey = getNegativeSearchKey(searchKey, 0, 1);
+      callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testWithinCodeAndNotCallAndCallWithHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "withincode(void $instanceof{PojoClient}->*(..)) AND" +
+            "!(call(* org.jboss.Pojo->*(..)) AND call(* *->@AnyAnnotation(int))" +
+            "OR hasfield(int *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey,
+            "PojoClient", "void| *#*");
+      assertNull(callee);
+      searchKey = getNegativeSearchKey(searchKey, 0, 1);
+      callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "org.jboss.Pojo|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|*| @AnyAnnotation#| int  ");
+   }
+   
+   public void testCallAndWithinOrWithinWitHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND (within($instanceof{PojoClient}) OR " +
+         "withincode(*->new())) AND has(*->new())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey1 = getSearchKey1(searchKey, false);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey1,
+            "PojoClient", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      assertHasBehaviorFilter((TypeFilter) subtypeSearcherTypeFilterField.get(
+            assertSubtypeSearchKey(searchKey1, "PojoClient")));
+      SearchKey searchKey2 = getSearchKey2(searchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      assertHasBehaviorFilter((TypeFilter) typeFilterField.get(searchKey2));
+   }
+   
+   public void testCallAndNotWithinOrWithinWithHas1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND !(within($instanceof{PojoClient}) OR " +
+         "withincode(*->new()) AND hasfield(int *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey negativeSearchKey = getNegativeSearchKey(searchKey, 0, 1);
+      SearchKey searchKey1 = getSearchKey1(negativeSearchKey, false);
+      callee = assertSubtypeBehaviorCallSearchKey(searchKey1, "PojoClient", "*");
+      assertNull(callee);
+      SearchKey searchKey2 = getSearchKey2(negativeSearchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testCallAndNotWithinOrWithinWithHas2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "call(* org.jboss.Pojo->*(..)) AND !(within($instanceof{PojoClient}) OR " +
+         "withincode(*->new()) OR !hasfield(int *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(searchKey, "*", "*");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey negativeSearchKey = getNegativeSearchKey(searchKey, 0, 1);
+      SearchKey searchKey1 = getSearchKey1(negativeSearchKey, false);
+      callee = assertSubtypeBehaviorCallSearchKey(searchKey1, "PojoClient", "*");
+      assertNull(callee);
+      SearchKey searchKey2 = getSearchKey2(negativeSearchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertNull(callee);
+   }
+   
+   public void testWithinOrWithinAndCallWitHas() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "has(* *->method()) AND (within($instanceof{PojoClient}) OR " +
+         "withincode(*->new())) AND call(* org.jboss.Pojo->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey searchKey1 = getSearchKey1(searchKey, false);
+      CalleeSearcher callee = assertSubtypeBehaviorCallSearchKey(searchKey1,
+            "PojoClient", "*");
+      assertHasBehaviorFilter((TypeFilter) subtypeSearcherTypeFilterField.get(
+            assertSubtypeSearchKey(searchKey1, "PojoClient")));
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      SearchKey searchKey2 = getSearchKey2(searchKey, false);
+      callee = assertBehaviorCallSearchKey(searchKey2, "*", "new#");
+      assertSimpleCalleeRestriction(callee, "org.jboss.Pojo|*| *#*");
+      assertHasBehaviorFilter((TypeFilter) typeFilterField.get(searchKey2));
+   }
+   
+   public void testExecutionAndCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(* *->*(..)) AND call(* *->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertTrue(searchKey instanceof EmptySearchKey);
+   }
+   
+   public void testExecutionAndField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(* *->*(..)) AND field(* *->*)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertTrue(searchKey instanceof EmptySearchKey);
+   }
+   
+   public void testExecutionAndAll() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(* *->*(..)) AND all(Pojo)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertAllSearchKey(getSearchKey1(searchKey, true), "Pojo");
+      assertBehaviorSearchKey(getSearchKey2(searchKey, true), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+   }
+   
+   public void testExecutionOrCall() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+         "execution(* *->*(..)) OR call(* *->*(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertBehaviorSearchKey(getSearchKey1(searchKey, false), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(searchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+   }
+   
+   public void testFieldOrWithinOrExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "field(int *->index) OR call(* *->*(..)) OR " +
+            "execution(public void org.jboss.Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertFieldSearchKey(getSearchKey1(subSearchKey, false), "*", "int index",
+            null, FieldSearcher.SearchType.ALL);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "org.jboss.Pojo",
+            "void| method#", BehaviorSearcher.SearchType.EXECUTION, attribute);
+   }
+   
+   public void testFieldOrWithinAndCallAndCallOrExecution() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "field(int *->index) OR" +
+            "(within(org.jboss.Pojo) AND call(* *->*(..)) AND call(*->new(..))) OR " +
+            "execution(public void org.jboss.Pojo->method())");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertFieldSearchKey(getSearchKey1(subSearchKey, false), "*", "int index",
+            null, FieldSearcher.SearchType.ALL);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "org.jboss.Pojo", "*");
+      assertSimpleCalleeRestriction(getRestriction1(callee, true), "*|*| *#*");
+      assertSimpleCalleeRestriction(getRestriction2(callee, true), "*|new#*");
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "org.jboss.Pojo",
+            "void| method#", BehaviorSearcher.SearchType.EXECUTION, attribute);
+   }
+   
+   public void testGetAndNotExecutionAndCallAndGet() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "get(int $typedef{typedef}->index) OR !(within(org.jboss.Pojo) AND " +
+            "call(* *->*(..)) AND get(int org.jboss..->index))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertFieldSearchKey(searchKey, "TypedefClass",
+            "int index", null, FieldSearcher.SearchType.READ);
+      TypeFilter typeFilter = (TypeFilter) typeFilterField.get(searchKey);
+      assertTypedefFilter(typeFilter, "typedef");
+   }
+   
+   public void testExecutionOrCallOrConsAndHasAndHasField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(execution(* *->*(..)) OR call(* *->*(..)) OR construction(*->new()))" +
+            " AND has(void *->method()) AND hasfield($instanceof{Pojo} *->counter)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertBehaviorSearchKey(getSearchKey1(subSearchKey, false), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      TypeFilter filter = (TypeFilter) typeFilterField.get(getSearchKey1(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, true));
+      assertHasFieldFilter(getTypeFilter2(filter, true));
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, true));
+      assertHasFieldFilter(getTypeFilter2(filter, true));
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "*", "new#",
+            BehaviorSearcher.SearchType.CONSTRUCTION);
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(searchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, true));
+      assertHasFieldFilter(getTypeFilter2(filter, true));
+   }
+   
+   public void testExecutionOrCallOrConsAndHasOrHasField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(execution(* *->*(..)) OR call(* *->*(..)) OR construction(*->new()))" +
+            " AND (has(void *->method()) OR hasfield($instanceof{Pojo} *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertBehaviorSearchKey(getSearchKey1(subSearchKey, false), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      TypeFilter filter = (TypeFilter) typeFilterField.get(getSearchKey1(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "*", "new#",
+            BehaviorSearcher.SearchType.CONSTRUCTION);
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(searchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+   }
+   
+   public void testExecutionOrCallOrConsAndHasOrNotHasField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(execution(* *->*(..)) OR call(* *->*(..)) OR construction(*->new()))" +
+            " AND (has(void *->method()) OR !hasfield($instanceof{Pojo} *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertBehaviorSearchKey(getSearchKey1(subSearchKey, false), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      TypeFilter filter = (TypeFilter) typeFilterField.get(getSearchKey1(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      filter = assertNegativeTypeFilter(getTypeFilter2(filter, false));
+      assertHasFieldFilter(filter);
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(subSearchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      filter = assertNegativeTypeFilter(getTypeFilter2(filter, false));
+      assertHasFieldFilter(filter);
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "*", "new#",
+            BehaviorSearcher.SearchType.CONSTRUCTION);
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(searchKey, false));
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      filter = assertNegativeTypeFilter(getTypeFilter2(filter, false));
+      assertHasFieldFilter(filter);
+   }
+   
+   public void testExecutionOrCallOrConsAndNotHasOrHasField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "(execution(* *->*(..)) OR call(* *->*(..)) OR construction(*->new()))" +
+            " AND !(has(void *->method()) OR hasfield($instanceof{Pojo} *->counter))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      SearchKey subSearchKey = getSearchKey1(searchKey, false);
+      assertBehaviorSearchKey(getSearchKey1(subSearchKey, false), "*", "*| *#*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      TypeFilter filter = (TypeFilter) typeFilterField.get(getSearchKey1(subSearchKey, false));
+      filter = assertNegativeTypeFilter(filter);
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+      CalleeSearcher callee = assertBehaviorCallSearchKey(
+            getSearchKey2(subSearchKey, false), "*", "*");
+      assertSimpleCalleeRestriction(callee, "*|*| *#*");
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(subSearchKey, false));
+      filter = assertNegativeTypeFilter(filter);
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+      assertBehaviorSearchKey(getSearchKey2(searchKey, false), "*", "new#",
+            BehaviorSearcher.SearchType.CONSTRUCTION);
+      filter = (TypeFilter) typeFilterField.get(getSearchKey2(searchKey, false));
+      filter = assertNegativeTypeFilter(filter);
+      assertHasBehaviorFilter(getTypeFilter1(filter, false));
+      assertHasFieldFilter(getTypeFilter2(filter, false));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKeyTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKeyTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ConjunctiveSearchKeyTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+
+/**
+ * Tests {@link ConjunctiveSearchKey}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class ConjunctiveSearchKeyTest extends FullScenarioBuilder
+{
+   public void test1()
+   {
+      ParsedSearchKey searchKey1 = StandardSearchKeyTest.getAllSearchKey();
+      ParsedSearchKey searchKey2 = StandardSearchKeyTest.getRestrictionCall2SearchKey();
+      
+      ParsedSearchKey searchKey = new ConjunctiveSearchKey(searchKey1, searchKey2);
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      result.clear();
+      searchKey = new ConjunctiveSearchKey(searchKey2, searchKey1);
+      searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+   }
+   
+   public void test2()
+   {
+      ParsedSearchKey searchKey1 = StandardSearchKeyTest.getAllCallSearchKey();
+      ParsedSearchKey searchKey2 = StandardSearchKeyTest.getRestrictionCall3SearchKey();
+      ParsedSearchKey searchKey = new ConjunctiveSearchKey(searchKey1, searchKey2);
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod);
+      result.clear();
+      searchKey = new ConjunctiveSearchKey(searchKey2, searchKey1);
+      searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod);
+   }
+   
+   public void test3()
+   {
+      ParsedSearchKey searchKey1 = StandardSearchKeyTest.getAllCallSearchKey();
+      ParsedSearchKey searchKey2 = StandardSearchKeyTest.getRestrictionCall3SearchKey();
+      ParsedSearchKey searchKey3 = new ConjunctiveSearchKey(searchKey1, searchKey2);
+      ParsedSearchKey searchKey = new ConjunctiveSearchKey(searchKey3,
+            PointcutDelegatorTest.getAllPojo());
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod);
+      result.clear();
+      searchKey = new ConjunctiveSearchKey(searchKey2, searchKey1);
+      searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKeyTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKeyTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/DisjunctiveSearchKeyTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,381 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+
+/**
+ * Tests {@code DisjunctiveSearchKey}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class DisjunctiveSearchKeyTest extends FullScenarioBuilder
+{
+   public void testAllOrFilterSubtypeSearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getFilterSubtypeSearchKey(),
+            StandardSearchKeyTest.getAllSearchKey());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1FieldRead, pojo1FieldWrite,
+            pojo1DefaultConstructorExec, pojo1IntConstructorExec,
+            pojo1IntConstructorExec2, pojo1Method1Exec, pojo1PrivateMethodExec,
+            pojo1PrivateMethodExec1, pojo1PrivateMethodExec2,
+            pojo1PrivateMethodExec3, pojo2Pojo3Read, pojo2Pojo3Write,
+            pojo2Pojo3ConstructorExec, pojo2Pojo3ConstructorExec1,
+            pojo2DefaultConstructorExec, pojo2StringConstructorExec,
+            pojo2StringConstructorExec2, pojo2StringConstructorExec3,
+            pojo2GetPojo2MethodExec, pojo2GetPojo2MethodExec1,
+            pojo2DoSomethingMethodExec, pojo2DoSomethingMethodExec1,
+            pojo2GetPojo3MethodExec, pojo3IntFieldRead, pojo3IntFieldWrite,
+            pojo3DumbFieldRead, pojo3DumbFieldWrite, pojo3AnyConstantRead,
+            pojo3FieldRead, pojo3FieldWrite, pojo3DefaultConstructorExec,
+            pojo3IntLongConstructorExec, pojo3IntStringConstructorExec,
+            pojo3VoidMethodExec, pojo3StringMethodExec, pojo3IntLongSomeMethodExec,
+            pojo3IntLongSomeMethodExec1, pojo3StringLongSomeMethodExec,
+            pojo3StringLongSomeMethodExec1, pojo4DefaultConstructorExec,
+            pojo4IntConstructorExec, pojo4CallConstructorMethodExec,
+            pojo4CallMethodMethodExec, pojo5DefaultConstructorExec,
+            pojo5CollectionConstructorExec, pojo5Pojo3ConstructorExec,
+            pojo5CalledByConExec, pojo5CalledByConExec2, pojo5CalledByMethodExec,
+            annPojoMultiArgConstructor1Exec, annPojoMultiArgConstructor2Exec,
+            annPojoMultiArgConstructor3Exec, annPojoMultiArgConstructor3Exec1,
+            annPojoMultiArgConstructor4Exec, annPojoMultiArgConstructor4Exec2,
+            annPojoMultiArgConstructor5Exec, annPojoMultiArgConstructor5Exec2,
+            annPojoMultiArgConstructor6Exec, annPojoMultiArgConstructor6Exec1,
+            annPojoMultiArgConstructor6Exec3, annPojoMultiArgConstructor7Exec,
+            annPojoMethod1Exec, annPojoMethod1Exec1, annPojoMethod1Exec3,
+            annPojoMethod2Exec, annPojoMethod2Exec1, annPojoMethod3Exec,
+            annPojoMethod3Exec1, annPojoMethod3Exec3, annPojoMethod4Exec,
+            annPojoMethod4Exec1, annPojoMethod5Exec, annPojoMethod5Exec1,
+            annPojoMethod5Exec3, annPojoMethod6Exec, annPojoMethod6Exec3,
+            annPojoMethod7Exec, annPojoMethod7Exec3,
+            anyAnnotationPojoIntConstructorExec, anyAnnotationPojoMethod1Exec,
+            anyAnnotationPojoMethod2Exec, dummyAnnotationPojoMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec, dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);
+   }
+   
+   public void testSearchAllCallOrNegative7SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getAllCallSearchKey(),
+            StandardSearchKeyTest.getNegativeSearchKey7());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod, pojo2Pojo3Read,
+            pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor,
+            pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1,
+            pojo2GetPojo2_pojo5CalledByMethod, pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo1IntConstructor, pojo2GetPojo3_pojo2StringConstructor,
+            pojo2GetPojo3_pojo5CalledByMethod, pojo3DumbFieldRead, pojo3FieldRead,
+            pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1,
+            annPojoMultiArgConstructor2_pojo1IntConstructor,
+            annPojoMultiArgConstructor2_pojo1IntConstructor2,
+            annPojoMultiArgConstructor2_pojo2StringConstructor,
+            annPojoMultiArgConstructor2_pojo2StringConstructor2,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testRestrictionCallOrNegative6SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getNegativeSearchKey6(),
+            StandardSearchKeyTest.getRestrictionCallSearchKey());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2Pojo3Read, pojo3DumbFieldRead,
+            pojo3FieldRead, pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4CallConstructor_pojo5Pojo3Constructor);
+   }
+   
+   public void testRestrictionCall2OrNegative5SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getRestrictionCall2SearchKey(),
+            StandardSearchKeyTest.getNegativeSearchKey5());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1, pojo2GetPojo3_pojo5CalledByMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            annPojoMethod4_pojo5CalledByMethod, annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testRestrictionCall3OrNegative4SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getRestrictionCall3SearchKey(),
+            StandardSearchKeyTest.getNegativeSearchKey4());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1, pojo2GetPojo3_pojo5CalledByMethod,
+            pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1);
+   }
+   
+   public void testEmpty1OrNegative3SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getEmptySearchKey(),
+            StandardSearchKeyTest.getNegativeSearchKey3());
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo3StringMethodExec,
+            pojo3StringLongSomeMethodExec, pojo3StringLongSomeMethodExec1);
+   }
+   
+   public void testEmpty2OrNegative2SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getNegativeSearchKey2(),
+            StandardSearchKeyTest.getEmptySearchKey2());
+      searchKey =  searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, anyAnnotationPojoIntConstruction, 
+            dummyAnnotationPojo2DummyInterface2Construction);
+   }
+   
+   public void testEmpty3OrNegative1SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getEmptySearchKey3(),
+            StandardSearchKeyTest.getNegativeSearchKey1());
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1DefaultConstruction,
+            pojo1DefaultConstruction1, pojo1DefaultConstruction3,
+            pojo1IntConstruction, pojo2DefaultConstruction, pojo2Pojo3Construction,
+            pojo2StringConstruction, pojo3DefaultConstruction,
+            pojo3IntStringConstruction, pojo3IntStringConstruction,
+            pojo4DefaultConstruction, pojo4IntConstruction, pojo5DefaultConstruction,
+            pojo5CollectionConstruction, pojo5Pojo3Construction,
+            annPojoMultiArgConstruction1, annPojoMultiArgConstruction2,
+            annPojoMultiArgConstruction3, annPojoMultiArgConstruction4,
+            annPojoMultiArgConstruction5, annPojoMultiArgConstruction5_2,
+            annPojoMultiArgConstruction6, annPojoMultiArgConstruction6_2,
+            annPojoMultiArgConstruction7,
+            dummyAnnotationPojo2DummyInterface2Construction,
+            anyAnnotationPojoIntConstruction,
+            pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod,
+            pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor,
+            pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1,
+            pojo2GetPojo2_pojo5CalledByMethod, pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo1IntConstructor, pojo2GetPojo3_pojo2StringConstructor,
+            pojo2GetPojo3_pojo5CalledByMethod, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1,
+            annPojoMultiArgConstructor2_pojo1IntConstructor,
+            annPojoMultiArgConstructor2_pojo1IntConstructor2,
+            annPojoMultiArgConstructor2_pojo2StringConstructor,
+            annPojoMultiArgConstructor2_pojo2StringConstructor2,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testEmpty4OrFilteredSearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            StandardSearchKeyTest.getEmptySearchKey4(),
+            StandardSearchKeyTest.getFilteredSearchKey());
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, dummyAnnotationPojoMethodExec, 
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec,
+            dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);
+   }
+   
+   public void testEmptyOrEmpty3OrEmpty2OrEmpty4SearchKey()
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            (new DisjunctiveSearchKey(new DisjunctiveSearchKey(
+                  StandardSearchKeyTest.getEmptySearchKey(),
+                  StandardSearchKeyTest.getEmptySearchKey3()),
+                  StandardSearchKeyTest.getEmptySearchKey2())),
+            StandardSearchKeyTest.getEmptySearchKey4());
+      searchKey = searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAllOrFilterSubtypeOrAllCallOrNegative7SearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = new DisjunctiveSearchKey(
+            new DisjunctiveSearchKey(new DisjunctiveSearchKey(
+                  StandardSearchKeyTest.getFilterSubtypeSearchKey(),
+                  StandardSearchKeyTest.getAllSearchKey()),
+                  StandardSearchKeyTest.getAllCallSearchKey()),
+            StandardSearchKeyTest.getNegativeSearchKey7());
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1FieldRead, pojo1FieldWrite,
+            pojo1DefaultConstructorExec, pojo1IntConstructorExec,
+            pojo1IntConstructorExec2, pojo1Method1Exec, pojo1PrivateMethodExec,
+            pojo1PrivateMethodExec1, pojo1PrivateMethodExec2,
+            pojo1PrivateMethodExec3,
+            pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod,         
+            pojo2Pojo3Read, pojo2Pojo3Write,
+            pojo2Pojo3ConstructorExec, pojo2Pojo3ConstructorExec1,
+            pojo2DefaultConstructorExec, pojo2StringConstructorExec,
+            pojo2StringConstructorExec2, pojo2StringConstructorExec3,
+            pojo2GetPojo2MethodExec, pojo2GetPojo2MethodExec1,
+            pojo2DoSomethingMethodExec, pojo2DoSomethingMethodExec1,
+            pojo2GetPojo3MethodExec, pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor,
+            pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1,
+            pojo2GetPojo2_pojo5CalledByMethod, pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo1IntConstructor, pojo2GetPojo3_pojo2StringConstructor,
+            pojo2GetPojo3_pojo5CalledByMethod,  pojo3IntFieldRead,
+            pojo3IntFieldWrite, pojo3DumbFieldRead, pojo3DumbFieldWrite,
+            pojo3AnyConstantRead, pojo3FieldRead, pojo3FieldWrite,
+            pojo3DefaultConstructorExec, pojo3IntLongConstructorExec,
+            pojo3IntStringConstructorExec,
+            pojo3VoidMethodExec, pojo3StringMethodExec, pojo3IntLongSomeMethodExec,
+            pojo3IntLongSomeMethodExec1, pojo3StringLongSomeMethodExec,
+            pojo3StringLongSomeMethodExec1, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1, pojo4DefaultConstructorExec,
+            pojo4IntConstructorExec, pojo4CallConstructorMethodExec,
+            pojo4CallMethodMethodExec,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1, pojo5DefaultConstructorExec,
+            pojo5CollectionConstructorExec, pojo5Pojo3ConstructorExec,
+            pojo5CalledByConExec, pojo5CalledByConExec2, pojo5CalledByMethodExec,
+            pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1,
+            annPojoMultiArgConstructor1Exec, annPojoMultiArgConstructor2Exec,
+            annPojoMultiArgConstructor3Exec, annPojoMultiArgConstructor3Exec1,
+            annPojoMultiArgConstructor4Exec, annPojoMultiArgConstructor4Exec2,
+            annPojoMultiArgConstructor5Exec, annPojoMultiArgConstructor5Exec2,
+            annPojoMultiArgConstructor6Exec, annPojoMultiArgConstructor6Exec1,
+            annPojoMultiArgConstructor6Exec3, annPojoMultiArgConstructor7Exec,
+            annPojoMethod1Exec, annPojoMethod1Exec1, annPojoMethod1Exec3,
+            annPojoMethod2Exec, annPojoMethod2Exec1, annPojoMethod3Exec,
+            annPojoMethod3Exec1, annPojoMethod3Exec3, annPojoMethod4Exec,
+            annPojoMethod4Exec1, annPojoMethod5Exec, annPojoMethod5Exec1,
+            annPojoMethod5Exec3, annPojoMethod6Exec, annPojoMethod6Exec3,
+            annPojoMethod7Exec, annPojoMethod7Exec3,
+            annPojoMultiArgConstructor2_pojo1IntConstructor,
+            annPojoMultiArgConstructor2_pojo1IntConstructor2,
+            annPojoMultiArgConstructor2_pojo2StringConstructor,
+            annPojoMultiArgConstructor2_pojo2StringConstructor2,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3,
+            anyAnnotationPojoIntConstructorExec, anyAnnotationPojoMethod1Exec,
+            anyAnnotationPojoMethod2Exec, dummyAnnotationPojoMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec, dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/EmptySearchKeyTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/EmptySearchKeyTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/EmptySearchKeyTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,144 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.FieldInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.MethodInfo;
+
+/**
+ * Tests {@link EmptySearchKey}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class EmptySearchKeyTest extends FullScenarioBuilder
+{
+   public void setUp() throws Exception
+   {
+      this.result = new HashSet<JoinPointInfo>();
+      this.enableRegistry();
+   }
+   
+   public void testBuildScenario() throws Exception
+   {
+      SearchKey searchKey = EmptySearchKey.getInstance();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      Method method = Pojo1.class.getDeclaredMethod("privateMethod");
+      new MethodInfo(advisor, 0l, method, null);
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      method = Pojo1.class.getDeclaredMethod("method1", String.class, String.class);
+      new MethodInfo(advisor, 0l, method, null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      new FieldInfo(advisor, Pojo3.class.getField("intField"), 0, false);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      Constructor constructor = Pojo3.class.getDeclaredConstructor(int.class,
+            long.class);
+      new ConstructionInfo(advisor, constructor, 1);
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      new ConstructorInfo(advisor, constructor, 1);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
+      constructor = Pojo4.class.getDeclaredConstructor();
+      Constructor calledConstructor = Pojo5.class.getDeclaredConstructor(
+            Collection.class);
+      new ConByConInfo(advisor, Pojo5.class, Pojo4.class, 0, calledConstructor, 0l,
+            null, null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      Method calledMethod = Pojo5.class.getDeclaredMethod("calledByCon");
+      new MethodByConInfo(advisor, Pojo5.class, Pojo4.class, 1, calledMethod, 0l,
+            null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      method = Pojo4.class.getDeclaredMethod("callConstructor");
+      calledConstructor = Pojo5.class.getDeclaredConstructor(Pojo3.class);
+      new ConByMethodInfo(advisor, Pojo5.class, method, 0l, calledConstructor, 0l,
+            null, null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      calledMethod = Pojo5.class.getDeclaredMethod("calledByMethod");
+      new MethodByMethodInfo(advisor, Pojo5.class, calledMethod, method, 0l, 0l, null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      advisor = new AdvisorMock("Pojo5Advisor", Pojo5.class);
+      new ConstructorInfo(advisor,
+            Pojo5.class.getDeclaredConstructor(Collection.class), 1);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      new ConstructorInfo(advisor, Pojo5.class.getDeclaredConstructor(Pojo3.class),
+            1);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+      
+      new MethodInfo(advisor, 0l, Pojo5.class.getDeclaredMethod("calledByCon"), null);
+      result.clear();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testScenarioBuilt() throws Exception
+   {
+      super.buildScenario();
+      SearchKey searchKey = EmptySearchKey.getInstance();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result);  
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,97 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Modifier;
+
+import org.jboss.aop.joinpoint.graph.FieldSearcher.SearchType;
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+
+/**
+ * Tests {@link SearchKeyParser} on field pointcut expressions.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class FieldSearchKeyParserTest extends AbstractSearchKeyParserTest
+{
+   public void testSimpleField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut", "field(int Pojo->name)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertFieldSearchKey(searchKey, "Pojo", "int name", null,
+            FieldSearcher.SearchType.ALL);
+   }
+   
+   public void testTypedefField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "get($typedef{typedef} Pojo->name)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertFieldSearchKey(searchKey, "Pojo",
+            "TypedefClass name", "$typedef{typedef}", SearchType.READ);
+   }
+   
+   public void testInstanceOfField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "set(private !static $instanceof{Object} Pojo->name)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute1 = new ASTAttribute(0);
+      attribute1.setValue(Modifier.PRIVATE);
+      ASTAttribute attribute2 = new ASTAttribute(0);
+      attribute2.setValue(Modifier.STATIC);
+      attribute2.not = true;
+      assertFieldSearchKey(searchKey, "Pojo", "* name",
+            "$instanceof{Object}", SearchType.WRITE, attribute1, attribute2);
+   }
+   
+   public void testAnnotatedTypeField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "field(public @AnyAnnotation Pojo->name)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      assertFieldSearchKey(searchKey, "Pojo", "* name", "@AnyAnnotation",
+            FieldSearcher.SearchType.ALL, attribute);
+   }
+   
+   public void testAnnotatedField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "field(* Pojo->@my.Annotation)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertFieldSearchKey(searchKey, "Pojo", "* @my.Annotation", null,
+            FieldSearcher.SearchType.ALL);
+   }
+   
+   public void testInstanceOfAnnotatedField() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "get($instanceof{@AnyAnnotation} Pojo->name)");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      assertFieldSearchKey(searchKey, "Pojo", "* name",
+            "$instanceof{@AnyAnnotation}", SearchType.READ);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FieldSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,430 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.FieldInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+
+/**
+ * Tests {@link FieldSearcher}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class FieldSearcherTest extends TestCase
+{
+   private StandardClassNode classNode;
+   private FieldInfo intFieldRead;
+   private FieldInfo intFieldWrite;
+   private FieldInfo dumbFieldWrite;
+   private FieldInfo anyConstantFieldRead;
+   private FieldInfo fieldFieldRead;
+   private FieldInfo fieldFieldWrite;
+   
+   private FieldInfo dumbFieldRead1;
+   private FieldInfo dumbFieldWrite1;
+   
+   private FieldInfo intFieldRead2;
+   private FieldInfo intFieldWrite2;
+   private FieldInfo anyConstantFieldRead2;
+   
+   private FieldInfo dumbFieldWrite3;
+
+   private Collection<JoinPointInfo> result;
+   
+   public void setUp() throws Exception
+   {
+      // create advisors
+      Advisor advisor = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      Advisor instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      Advisor instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      Advisor instanceAdvisor3 = new InstanceAdvisorMock(advisor);
+      
+      // get fields
+      
+      // public int intField;
+      Field intField = Pojo3.class.getDeclaredField("intField");
+      // private static String dumbField;
+      Field dumbField = Pojo3.class.getDeclaredField("dumbField");
+      // public static final long ANY_CONSTANT = 0l;
+      Field anyConstantField = Pojo3.class.getDeclaredField("ANY_CONSTANT");
+      // protected Collection<String> field;
+      Field fieldField = Pojo3.class.getDeclaredField("field");
+      
+      // create field infos
+      intFieldRead = new FieldInfo(advisor, intField, 0, true);
+      intFieldWrite = new FieldInfo(advisor, intField, 0, false);
+      dumbFieldWrite = new FieldInfo(advisor, dumbField, 1, false);
+      anyConstantFieldRead = new FieldInfo(advisor, anyConstantField, 2, true);
+      fieldFieldRead = new FieldInfo(advisor, fieldField, 2, true);
+      fieldFieldWrite = new FieldInfo(advisor, fieldField, 2, false);
+      dumbFieldRead1 = new FieldInfo(instanceAdvisor1, dumbField, 1, true);
+      dumbFieldWrite1 = new FieldInfo(instanceAdvisor1, dumbField, 1, false);
+      anyConstantFieldRead2 = new FieldInfo(instanceAdvisor2, anyConstantField, 2, true);
+      intFieldRead2 = new FieldInfo(instanceAdvisor2, intField, 0, true);
+      intFieldWrite2 = new FieldInfo(instanceAdvisor2, intField, 0, false);
+      dumbFieldWrite3 = new FieldInfo(instanceAdvisor3, dumbField, 1, false);
+      
+      // mount class node structure
+      classNode = new StandardClassNode(Pojo3.class);
+      AdvisedData advisedData = classNode.getAdvisedData(advisor);
+      advisedData.getField(intField).setFieldRead(intFieldRead);
+      advisedData.getField(intField).setFieldWrite(intFieldWrite);
+      advisedData.getField(dumbField).setFieldWrite(dumbFieldWrite);
+      advisedData.getField(anyConstantField).setFieldRead(anyConstantFieldRead);
+      advisedData.getField(fieldField).setFieldRead(fieldFieldRead);
+      advisedData.getField(fieldField).setFieldWrite(fieldFieldWrite);
+      advisedData = classNode.getAdvisedData(instanceAdvisor1);
+      advisedData.getField(dumbField).setFieldRead(dumbFieldRead1);
+      advisedData.getField(dumbField).setFieldWrite(dumbFieldWrite1);
+      advisedData = classNode.getAdvisedData(instanceAdvisor2);
+      advisedData.getField(anyConstantField).setFieldRead(anyConstantFieldRead2);
+      advisedData.getField(intField).setFieldRead(intFieldRead2);
+      advisedData.getField(intField).setFieldWrite(intFieldWrite2);
+      advisedData = classNode.getAdvisedData(instanceAdvisor3);
+      advisedData.getField(dumbField).setFieldWrite(dumbFieldWrite3);
+      
+      // result collection
+      result = new HashSet<JoinPointInfo>();
+   }
+   
+   public void testAll()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, intFieldWrite, dumbFieldWrite,
+            anyConstantFieldRead, fieldFieldRead, fieldFieldWrite, dumbFieldRead1,
+            dumbFieldWrite1, anyConstantFieldRead2, intFieldRead2, intFieldWrite2,
+            dumbFieldWrite3);
+   }
+   
+   public void testAllRead()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, anyConstantFieldRead,
+            fieldFieldRead, dumbFieldRead1, anyConstantFieldRead2, intFieldRead2);
+   }
+   
+   public void testAllWrite()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldWrite, dumbFieldWrite,
+            fieldFieldWrite, dumbFieldWrite1, intFieldWrite2, dumbFieldWrite3);
+   }
+   
+   public void testAttributeAll()
+   {
+      FieldSearcher fieldSearcher = getAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, dumbFieldWrite, anyConstantFieldRead,
+            dumbFieldRead1, dumbFieldWrite1, anyConstantFieldRead2, dumbFieldWrite3);
+   }
+   
+   public void testAttributeRead()
+   {
+      FieldSearcher fieldSearcher = getAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, anyConstantFieldRead, dumbFieldRead1,
+            anyConstantFieldRead2);
+   }
+   
+   public void testAttributeWrite()
+   {
+      FieldSearcher fieldSearcher = getAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, dumbFieldWrite, dumbFieldWrite1, dumbFieldWrite3);
+   }
+   
+   private FieldSearcher getAttributeSearcher()
+   {
+      ArrayList<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attributes.add(attribute);
+      return new FieldSearcher("*", attributes, null);
+   }
+   
+   public void testAttributesAll()
+   {
+      FieldSearcher fieldSearcher = getAttributesSearcherFilter();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, anyConstantFieldRead, anyConstantFieldRead2);
+   }
+   
+   public void testAttributesRead()
+   {
+      FieldSearcher fieldSearcher = getAttributesSearcherFilter();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, anyConstantFieldRead, anyConstantFieldRead2);
+   }
+   
+   public void testAttributesWrite()
+   {
+      FieldSearcher fieldSearcher = getAttributesSearcherFilter();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   private FieldSearcher getAttributesSearcherFilter()
+   {
+      ArrayList<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attributes.add(attribute);
+      attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attributes.add(attribute);
+      return new FieldSearcher("*", attributes, null);
+   }
+   
+   public void testExpAll()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*Field", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, intFieldWrite, dumbFieldWrite,
+            dumbFieldRead1, dumbFieldWrite1, intFieldRead2, intFieldWrite2,
+            dumbFieldWrite3);
+   }
+   
+   public void testExpRead()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*Field", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, dumbFieldRead1, intFieldRead2);
+   }
+   
+   public void testExpWrite()
+   {
+      FieldSearcher fieldSearcher = new FieldSearcher("*Field", new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldWrite, dumbFieldWrite, dumbFieldWrite1,
+            intFieldWrite2, dumbFieldWrite3);
+   }
+   
+   public void testExpAttributeAll()
+   {
+      FieldSearcher fieldSearcher = getExpAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, intFieldWrite, fieldFieldRead,
+            fieldFieldWrite, intFieldRead2, intFieldWrite2);
+   }
+   
+   public void testExpAttributeRead()
+   {
+      FieldSearcher fieldSearcher = getExpAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, fieldFieldRead, intFieldRead2);
+   }
+   
+   public void testExpAttributeWrite()
+   {
+      FieldSearcher fieldSearcher = getExpAttributeSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldWrite, fieldFieldWrite, intFieldWrite2);
+   }
+   
+   private FieldSearcher getExpAttributeSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      return new FieldSearcher("*ield", attributes, null);
+   }
+   
+   public void testFilterAll() throws Exception
+   {
+      FieldSearcher fieldSearcher = getFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, intFieldWrite,
+            anyConstantFieldRead, anyConstantFieldRead2, intFieldRead2,
+            intFieldWrite2);
+   }
+   
+   public void testFilterRead() throws Exception
+   {
+      FieldSearcher fieldSearcher = getFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldRead, anyConstantFieldRead,
+            anyConstantFieldRead2, intFieldRead2);
+   }
+   
+   public void testFilterWrite() throws Exception
+   {
+      FieldSearcher fieldSearcher = getFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, intFieldWrite, intFieldWrite2);
+   }
+   
+   private FieldSearcher getFilterSearcher() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("primitive", "class(int) OR class(long)");
+      AspectManager.instance().addTypedef(typedef);
+      FieldFilter filter = new FieldTypeFilter(
+            new ClassExpression("$typedef{primitive}"));;
+      return new FieldSearcher("*", new ArrayList<ASTAttribute>(), filter);
+   }
+   
+   public void testAttributeFilterAll()
+   {
+      FieldSearcher fieldSearcher = getAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttributeFilterRead()
+   {
+      FieldSearcher fieldSearcher = getAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testAttributeFilterWrite()
+   {
+      FieldSearcher fieldSearcher = getAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   private FieldSearcher getAttributeFilterSearcher()
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PROTECTED);
+      attributes.add(attribute);
+      attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.STATIC);
+      attribute.not = true;
+      attributes.add(attribute);
+      FieldFilter filter = new FieldTypeFilter(
+            new ClassExpression("$instanceof{" + Object.class.getName() + "}"));;
+      return new FieldSearcher("*", attributes, filter);
+   }
+   
+   public void testExpFilterSearcherAll()
+   {
+      FieldSearcher fieldSearcher = getExpFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, dumbFieldWrite, dumbFieldRead1, dumbFieldWrite1,
+            dumbFieldWrite3);
+   }
+   
+   public void testExpFilterSearcherRead()
+   {
+      FieldSearcher fieldSearcher = getExpFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, dumbFieldRead1);
+   }
+   
+   public void testExpFilterSearcherWrite()
+   {
+      FieldSearcher fieldSearcher = getExpFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, dumbFieldWrite, dumbFieldWrite1,
+            dumbFieldWrite3);
+   }
+   
+   private FieldSearcher getExpFilterSearcher()
+   {
+      FieldFilter filter = new FieldTypeFilter(
+            new ClassExpression("$instanceof{" + Object.class.getName() + "}"));;
+      return new FieldSearcher("* dumbField", new ArrayList<ASTAttribute>(), filter);
+   }
+   
+   public void testExpAttributeFilterAll() throws Exception
+   {
+      FieldSearcher fieldSearcher = getExpAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, fieldFieldRead, fieldFieldWrite);
+   }
+   
+   public void testExpAttributeFilterRead() throws Exception
+   {
+      FieldSearcher fieldSearcher = getExpAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.READ);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, fieldFieldRead);
+   }
+   
+   public void testExpAttributeFilterWrite() throws Exception
+   {
+      FieldSearcher fieldSearcher = getExpAttributeFilterSearcher();
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      fieldSearcher.search(classNode, result);
+      Util.assertCollection(result, fieldFieldWrite);
+   }
+   
+   private FieldSearcher getExpAttributeFilterSearcher() throws Exception
+   {
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PRIVATE);
+      attribute.not = true;
+      attributes.add(attribute);
+      Typedef typedef = new TypedefExpression("collection", "has(int *->size())");
+      AspectManager.instance().addTypedef(typedef);
+      FieldFilter filter = new FieldTypeFilter(
+            new ClassExpression("$typedef{collection}"));
+      return new FieldSearcher("* *d", attributes, filter);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FullScenarioBuilder.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FullScenarioBuilder.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/FullScenarioBuilder.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,729 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.ConByConInfo;
+import org.jboss.aop.ConByMethodInfo;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.FieldInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodByConInfo;
+import org.jboss.aop.MethodByMethodInfo;
+import org.jboss.aop.MethodInfo;
+import org.jboss.aop.joinpoint.JoinPointRegistry;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+
+/**
+ * Builds a complete joinpoint info scenario using the scenario classes contained
+ * in this package.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public abstract class FullScenarioBuilder extends TestCase
+{
+   Collection<JoinPointInfo> result;
+   private Field infoRegistryField = null;
+   Tree<StandardClassNode> classTree = null;
+   private MainJoinPointGraph graph = null;
+   
+   
+   // public class Pojo1
+   // * POJO1 * //
+   
+   // public static String field
+   JoinPointInfo pojo1FieldRead;
+   JoinPointInfo pojo1FieldWrite;
+   
+   // private Pojo1()
+   JoinPointInfo pojo1DefaultConstruction;
+   JoinPointInfo pojo1DefaultConstruction1;
+   JoinPointInfo pojo1DefaultConstruction3;
+   JoinPointInfo pojo1DefaultConstructorExec;
+   // public Pojo1(int value)
+   JoinPointInfo pojo1IntConstruction;
+   JoinPointInfo pojo1IntConstructorExec;
+   JoinPointInfo pojo1IntConstructorExec2;
+   // public void method1(String arg1, String arg2)
+   JoinPointInfo pojo1Method1Exec;
+   // private void privateMethod()
+   JoinPointInfo pojo1PrivateMethodExec;
+   JoinPointInfo pojo1PrivateMethodExec1;
+   JoinPointInfo pojo1PrivateMethodExec2;
+   JoinPointInfo pojo1PrivateMethodExec3;
+   
+   JoinPointInfo pojo1DefaultConstructor_pojo1IntConstructor;
+   JoinPointInfo pojo1DefaultConstructor_pojo1PrivateMethod;
+   JoinPointInfo pojo1Method1_pojo1IntConstructor;
+   JoinPointInfo pojo1Method1_pojo1PrivateMethod;
+   
+   // @Deprecated
+   // public class Pojo2
+   // * POJO2 * //
+   
+   // private Pojo3
+   JoinPointInfo pojo2Pojo3Read;
+   JoinPointInfo pojo2Pojo3Write;
+   
+   // public Pojo2(Pojo3 pojo3)
+   JoinPointInfo pojo2Pojo3Construction;
+   JoinPointInfo pojo2Pojo3ConstructorExec;
+   JoinPointInfo pojo2Pojo3ConstructorExec1;
+   // public Pojo2()
+   JoinPointInfo pojo2DefaultConstruction;
+   JoinPointInfo pojo2DefaultConstructorExec;
+   // public Pojo2(String arg)
+   JoinPointInfo pojo2StringConstruction;
+   JoinPointInfo pojo2StringConstructorExec;
+   JoinPointInfo pojo2StringConstructorExec2;
+   JoinPointInfo pojo2StringConstructorExec3;
+   // public static final Pojo2 getPojo2()
+   JoinPointInfo pojo2GetPojo2MethodExec;
+   JoinPointInfo pojo2GetPojo2MethodExec1;
+   // public Pojo1 doSomething(int arg1, long arg2, Collection<Pojo1> arg3)
+   JoinPointInfo pojo2DoSomethingMethodExec;
+   JoinPointInfo pojo2DoSomethingMethodExec1;
+   // public Pojo3 getPojo3()
+   JoinPointInfo pojo2GetPojo3MethodExec;
+   
+   
+   JoinPointInfo pojo2StringConstructor_pojo1IntConstructor;
+   JoinPointInfo pojo2StringConstructor_pojo2StringConstructor;
+   JoinPointInfo pojo2StringConstructor_pojo5CalledByConMethod;
+   JoinPointInfo pojo2GetPojo2_pojo1IntConstructor;
+   JoinPointInfo pojo2GetPojo2_pojo2StringConstructor;
+   JoinPointInfo pojo2GetPojo2_pojo2StringConstructor1;
+   JoinPointInfo pojo2GetPojo2_pojo5CalledByMethod;
+   JoinPointInfo pojo2GetPojo2_pojo5CalledByMethod1;
+   JoinPointInfo pojo2GetPojo3_pojo1IntConstructor;
+   JoinPointInfo pojo2GetPojo3_pojo2StringConstructor;
+   JoinPointInfo pojo2GetPojo3_pojo5CalledByMethod;
+   
+   
+   // @DummyAnnotation
+   // public class Pojo3 extends Pojo2
+   // * POJO3 * //
+   
+   // public int intField;
+   JoinPointInfo pojo3IntFieldRead;
+   JoinPointInfo pojo3IntFieldWrite;
+   // private static String dumbField;
+   JoinPointInfo pojo3DumbFieldRead;
+   JoinPointInfo pojo3DumbFieldWrite;
+   // public static final long ANY_CONSTANT = 0l;
+   JoinPointInfo pojo3AnyConstantRead;
+   // protected Collection<String> field;
+   JoinPointInfo pojo3FieldRead;
+   JoinPointInfo pojo3FieldWrite;
+
+   // public Pojo3()
+   JoinPointInfo pojo3DefaultConstruction;
+   JoinPointInfo pojo3DefaultConstructorExec;
+   // public Pojo3(int arg1, long arg2)
+   JoinPointInfo pojo3IntLongConstruction;
+   JoinPointInfo pojo3IntLongConstructorExec;
+   // public Pojo3(int arg1, String arg3)
+   JoinPointInfo pojo3IntStringConstruction;
+   JoinPointInfo pojo3IntStringConstructorExec;
+   
+   // public void voidMethod() throws Exception
+   JoinPointInfo pojo3VoidMethodExec;
+   // public String stringMethod()
+   JoinPointInfo pojo3StringMethodExec;
+   // throws ArrayIndexOutOfBoundsException, NullPointerException
+   // public void someMethod(int arg1, long arg2)
+   JoinPointInfo pojo3IntLongSomeMethodExec;
+   JoinPointInfo pojo3IntLongSomeMethodExec1;
+   // public String someMethod(String arg1, long arg2)
+   JoinPointInfo pojo3StringLongSomeMethodExec;
+   JoinPointInfo pojo3StringLongSomeMethodExec1;
+   
+   JoinPointInfo pojo3StringMethod_pojo1IntConstructor;
+   JoinPointInfo pojo3StringMethod_pojo1IntConstructor1;
+   JoinPointInfo pojo3StringMethod_pojo2StringConstructor;
+   JoinPointInfo pojo3StringMethod_pojo2StringConstructor1;
+   
+   // public class Pojo4
+   // * POJO4 * //
+   // public Pojo4()
+   JoinPointInfo pojo4DefaultConstruction;
+   JoinPointInfo pojo4DefaultConstructorExec;
+   // public Pojo4(int arg)
+   JoinPointInfo pojo4IntConstruction;
+   JoinPointInfo pojo4IntConstructorExec;
+   // public void callConstructor() throws Exception
+   JoinPointInfo pojo4CallConstructorMethodExec;
+   // public void callMethod()
+   JoinPointInfo pojo4CallMethodMethodExec;
+   
+   
+   JoinPointInfo pojo4DefaultConstructor_pojo5CollectionConstructor;
+   JoinPointInfo pojo4IntConstructor_pojo5DefaultConstructor;
+   JoinPointInfo pojo4IntConstructor_pojo5CalledByConMethod;
+   
+   JoinPointInfo pojo4CallConstructor_pojo5Pojo3Constructor;
+   JoinPointInfo pojo4CallMethod_pojo5DefaultConstructor;
+   JoinPointInfo pojo4CallMethod_pojo5CalledByMethodMethod;
+   JoinPointInfo pojo4CallMethod_pojo5CalledByMethodMethod1;
+   
+   
+   // Aspect
+   // public class Pojo5 extends Pojo2
+   // * POJO5 * //
+   
+   // public Pojo5()
+   JoinPointInfo pojo5DefaultConstruction;
+   JoinPointInfo pojo5DefaultConstructorExec;
+   // @AnyAnnotation
+   // protected Pojo5(Collection arg)
+   JoinPointInfo pojo5CollectionConstruction;
+   JoinPointInfo pojo5CollectionConstructorExec;
+   // @Deprecated
+   // public Pojo5(Pojo3 pojo3) throws Exception
+   JoinPointInfo pojo5Pojo3Construction;
+   JoinPointInfo pojo5Pojo3ConstructorExec;
+   // @Bind(pointcut="all(Pojo5)")
+   // public void calledByCon() throws NullPointerException, IllegalStateException
+   JoinPointInfo pojo5CalledByConExec;
+   JoinPointInfo pojo5CalledByConExec2;
+   // @Mixin(interfaces={MetaDataKeyLoader.class})
+   // void calledByMethod()
+   JoinPointInfo pojo5CalledByMethodExec;
+   
+   JoinPointInfo pojo5CollectionConstructor_pojo1IntConstructor;
+   JoinPointInfo pojo5CollectionConstructor_pojo1IntConstructor1;
+   JoinPointInfo pojo5CollectionConstructor_pojo2StringConstructor;
+   JoinPointInfo pojo5CollectionConstructor_pojo2StringConstructor1;
+   JoinPointInfo pojo5CollectionConstructor_pojo5CalledByCon;
+   JoinPointInfo pojo5CollectionConstructor_pojo5CalledByCon1;
+   
+   
+   // class AnnPojo
+   // * ANN POJO * //
+   
+   // public AnnPojo(Pojo2 arg1, AnyAnnotationPojo arg2, DummyAnnotationPojo arg3)
+   JoinPointInfo annPojoMultiArgConstruction1;
+   JoinPointInfo annPojoMultiArgConstructor1Exec;
+   // public AnnPojo(int arg1, Pojo2 arg2, long arg3, DummyAnnotationPojo arg4)
+   JoinPointInfo annPojoMultiArgConstruction2;
+   JoinPointInfo annPojoMultiArgConstructor2Exec;
+   // public AnnPojo(Pojo2 arg1, DummyAnnotationPojo arg2, long arg3)
+   JoinPointInfo annPojoMultiArgConstruction3;
+   JoinPointInfo annPojoMultiArgConstructor3Exec;
+   JoinPointInfo annPojoMultiArgConstructor3Exec1;
+   // public AnnPojo(Pojo2 arg1, int arg2, long arg3)
+   JoinPointInfo annPojoMultiArgConstruction4;
+   JoinPointInfo annPojoMultiArgConstructor4Exec;
+   JoinPointInfo annPojoMultiArgConstructor4Exec2;
+   // public AnnPojo(String arg1, int arg2, long arg3, DummyAnnotationPojo arg4,
+   //     AnyAnnotationPojo arg5)
+   JoinPointInfo annPojoMultiArgConstruction5;
+   JoinPointInfo annPojoMultiArgConstruction5_2;
+   JoinPointInfo annPojoMultiArgConstructor5Exec;
+   JoinPointInfo annPojoMultiArgConstructor5Exec2;
+   // public AnnPojo(DummyAnnotationPojo arg1, AnyAnnotationPojo arg2) {}
+   JoinPointInfo annPojoMultiArgConstruction6;
+   JoinPointInfo annPojoMultiArgConstruction6_2;
+   JoinPointInfo annPojoMultiArgConstructor6Exec;
+   JoinPointInfo annPojoMultiArgConstructor6Exec1;
+   JoinPointInfo annPojoMultiArgConstructor6Exec3;
+   // public AnnPojo(AnyAnnotationPojo arg1)
+   JoinPointInfo annPojoMultiArgConstruction7;
+   JoinPointInfo annPojoMultiArgConstructor7Exec;
+   // public void method1(Pojo2, AnyAnnotationPojo, DummyAnnotationPojo)
+   JoinPointInfo annPojoMethod1Exec;
+   JoinPointInfo annPojoMethod1Exec1;
+   JoinPointInfo annPojoMethod1Exec3;
+   // public Pojo2 method2(int, Pojo2, long, DummyAnnotationPojo)
+   JoinPointInfo annPojoMethod2Exec;
+   JoinPointInfo annPojoMethod2Exec1;
+   // public DummyAnnotationPojo method3(Pojo2, DummyAnnotationPojo, long)
+   JoinPointInfo annPojoMethod3Exec;
+   JoinPointInfo annPojoMethod3Exec1;
+   JoinPointInfo annPojoMethod3Exec3;
+   // public void method4(Pojo2, int, long) throws IllegalArgumentException, IllegalStateException {}
+   JoinPointInfo annPojoMethod4Exec;
+   JoinPointInfo annPojoMethod4Exec1;
+   // public String method5(String, int, long, DummyAnnotationPojo, AnyAnnotationPojo)
+   JoinPointInfo annPojoMethod5Exec;
+   JoinPointInfo annPojoMethod5Exec1;
+   JoinPointInfo annPojoMethod5Exec3;
+   // public void method6(DummyAnnotationPojo, AnyAnnotationPojo)
+   JoinPointInfo annPojoMethod6Exec;
+   JoinPointInfo annPojoMethod6Exec3;
+   // public AnyAnnotationPojo method7(AnyAnnotationPojo)
+   JoinPointInfo annPojoMethod7Exec;
+   JoinPointInfo annPojoMethod7Exec3;
+   
+   JoinPointInfo annPojoMultiArgConstructor2_pojo1IntConstructor;
+   JoinPointInfo annPojoMultiArgConstructor2_pojo1IntConstructor2;
+   JoinPointInfo annPojoMultiArgConstructor2_pojo2StringConstructor;
+   JoinPointInfo annPojoMultiArgConstructor2_pojo2StringConstructor2;
+   JoinPointInfo annPojoMethod4_pojo5CalledByMethod;
+   JoinPointInfo annPojoMethod4_pojo5CalledByMethod3;
+   
+   // @AnyAnnotation
+   // abstract class AnyAnnotationPojo implements DummyInterface
+   // * ANY ANNOTATION POJO * //
+   // public AnyAnnotationPojo(int)
+   JoinPointInfo anyAnnotationPojoIntConstruction;
+   JoinPointInfo anyAnnotationPojoIntConstructorExec;
+   // public void method1()
+   JoinPointInfo anyAnnotationPojoMethod1Exec;
+   // public void method2()
+   JoinPointInfo anyAnnotationPojoMethod2Exec;
+   
+   // @DummyAnnotation
+   // class DummyAnnotationPojo implements DummyInterface
+   // * DUMMY ANNOTATION POJO * //
+
+   // public void method()
+   JoinPointInfo dummyAnnotationPojoMethodExec;
+   // public void interfaceMethod() throws NotImplementedException
+   JoinPointInfo dummyAnnotationPojoInterfaceMethodExec;
+   JoinPointInfo dummyAnnotationPojoInterfaceMethodExec2;
+   // public DummyAnnotationPojo interfaceMethod2() throws IllegalArgumentException, IllegalStateException
+   JoinPointInfo dummyAnnotationPojoInterfaceMethod2Exec;
+   JoinPointInfo dummyAnnotationPojoInterfaceMethod2Exec1;
+   JoinPointInfo dummyAnnotationPojoInterfaceMethod2Exec2;
+   
+   // @DummyAnnotation
+   // class DummyAnnotationPojo2 extends AnyAnnotationPojo
+   // * DUMMY ANNOTATION POJO2 * //
+   
+   //public DummyAnnotationPojo2(DummyInterface2)
+   JoinPointInfo dummyAnnotationPojo2DummyInterface2Construction;
+   JoinPointInfo dummyAnnotationPojo2DummyInterface2ConstructorExec;
+   // @Override
+   // public void method1()
+   JoinPointInfo dummyAnnotationPojo2Method1Exec;
+   // public void method2(int arg)
+   JoinPointInfo dummyAnnotationPojo2Method2Exec;
+   // public void interfaceMethod() {}
+   JoinPointInfo dummyAnnotationPojo2InterfaceMethodExec;
+   // public DummyAnnotationPojo interfaceMethod2()
+   JoinPointInfo dummyAnnotationPojo2InterfaceMethod2Exec;
+   
+   
+   
+   public void setUp() throws Exception
+   {
+      AspectManager.instance();
+      this.result = new HashSet<JoinPointInfo>();
+      this.enableRegistry();
+      this.buildScenario();
+   }
+   
+   public void enableRegistry() throws Exception
+   {
+      this.graph = MainJoinPointGraph.getInstance();
+      classTree = new Tree<StandardClassNode>();
+      graph.classTree = classTree;
+      infoRegistryField = JoinPointInfo.class.getDeclaredField("registry");
+      infoRegistryField.setAccessible(true);
+      infoRegistryField.set(null, MainJoinPointGraph.getInstance());
+   }
+   
+   public void tearDown() throws Exception
+   {
+      infoRegistryField.set(null, new JoinPointRegistry() {
+         public void register(ConstructorInfo info){}
+         public void register(ConstructionInfo info){}
+         public void register(FieldInfo info){}
+         public void register(MethodInfo info){}
+         public void register(ConByConInfo info){}
+         public void register(ConByMethodInfo info){}
+         public void register(MethodByConInfo info){}
+         public void register(MethodByMethodInfo info){}});
+      graph.classTree = new Tree<StandardClassNode>();
+   }
+   
+   @SuppressWarnings("deprecation")
+   protected void buildScenario() throws Exception
+   {
+      // Pojo1
+      Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      // public static String field
+      Field field = Pojo1.class.getField("field");
+      pojo1FieldRead = new FieldInfo(advisor, field, 0, true);
+      pojo1FieldWrite = new FieldInfo(advisor, field, 0, false);
+      // private new()
+      Constructor pojo1DefaultConstructor = Pojo1.class.getDeclaredConstructor();
+      pojo1DefaultConstruction = new ConstructionInfo(advisor,
+            pojo1DefaultConstructor, 0);
+      pojo1DefaultConstructorExec = new ConstructorInfo(advisor,
+            pojo1DefaultConstructor, 0);
+      // public new(int value)
+      Constructor pojo1IntConstructor = Pojo1.class.getDeclaredConstructor(int.class);
+      pojo1DefaultConstructor_pojo1IntConstructor = new ConByConInfo(advisor,
+            Pojo1.class, Pojo1.class, 0, pojo1IntConstructor, 0l, null, null);
+      // privateMethod()
+      Method pojo1PrivateMethod = Pojo1.class.getDeclaredMethod("privateMethod");
+      pojo1DefaultConstructor_pojo1PrivateMethod = new MethodByConInfo(advisor,
+            Pojo1.class, Pojo1.class, 0, pojo1PrivateMethod, 0l, null);
+      pojo1IntConstruction = new ConstructionInfo(advisor, pojo1IntConstructor, 1);
+      pojo1IntConstructorExec = new ConstructorInfo(advisor, pojo1IntConstructor, 1);
+      // public void method1(String arg1, String arg2)
+      Method pojo1Method1 = Pojo1.class.getDeclaredMethod("method1",
+            String.class, String.class);
+      pojo1Method1Exec = new MethodInfo(advisor, 0l, pojo1Method1, null);
+      pojo1Method1_pojo1IntConstructor = new ConByMethodInfo(advisor, Pojo1.class,
+            pojo1Method1, 0l, pojo1IntConstructor, 0l, null, null);
+      pojo1Method1_pojo1PrivateMethod = new MethodByMethodInfo(advisor, Pojo1.class,
+            pojo1PrivateMethod, pojo1Method1, 0l, 0l, null);
+      pojo1PrivateMethodExec = new MethodInfo(advisor, 0l, pojo1PrivateMethod, null);
+      Advisor instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      pojo1DefaultConstruction1 = pojo1DefaultConstruction.copy(instanceAdvisor1);
+      pojo1PrivateMethodExec1 = pojo1PrivateMethodExec.copy(instanceAdvisor1);
+      Advisor instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      pojo1IntConstructorExec2 = pojo1IntConstructorExec.copy(instanceAdvisor2);
+      pojo1PrivateMethodExec2 = pojo1PrivateMethodExec.copy(instanceAdvisor2);
+      Advisor instanceAdvisor3 = new InstanceAdvisorMock(advisor);
+      pojo1DefaultConstruction3 = pojo1DefaultConstruction.copy(instanceAdvisor3);      
+      pojo1PrivateMethodExec3 = pojo1PrivateMethodExec.copy(instanceAdvisor3);
+      
+      // Pojo2
+      advisor = new AdvisorMock("Pojo2Advisor", Pojo2.class);
+      field = Pojo2.class.getDeclaredField("pojo3");
+      pojo2Pojo3Read = new FieldInfo(advisor, field, 0, true);
+      pojo2Pojo3Write = new FieldInfo(advisor, field, 0, false);
+      Constructor constructor = Pojo2.class.getDeclaredConstructor(Pojo3.class);
+      pojo2Pojo3Construction = new ConstructionInfo(advisor, constructor, 0);
+      pojo2Pojo3ConstructorExec = new ConstructorInfo(advisor, constructor, 0);
+      constructor = Pojo2.class.getDeclaredConstructor();
+      pojo2DefaultConstruction = new ConstructionInfo(advisor, constructor, 0);
+      pojo2DefaultConstructorExec = new ConstructorInfo(advisor, constructor, 0);
+      Constructor pojo2StringConstructor = Pojo2.class.getDeclaredConstructor(String.class);
+      pojo2StringConstruction = new ConstructionInfo(advisor, pojo2StringConstructor,
+            0);
+      pojo2StringConstructorExec = new ConstructorInfo(advisor,
+            pojo2StringConstructor, 0);
+         Method pojo2GetPojo2Method = Pojo2.class.getDeclaredMethod("getPojo2");
+      pojo2StringConstructor_pojo1IntConstructor = new ConByConInfo(advisor, Pojo1.class,
+            Pojo2.class, 2, pojo1IntConstructor, 0l, null, null);
+      pojo2StringConstructor_pojo2StringConstructor = new ConByConInfo(advisor,
+            Pojo2.class, Pojo2.class, 2, pojo2StringConstructor, 0l, null, null);
+      Method pojo5CalledByConMethod = Pojo5.class.getDeclaredMethod("calledByCon");
+      pojo2StringConstructor_pojo5CalledByConMethod = new MethodByConInfo(advisor,
+            Pojo5.class, Pojo2.class, 2, pojo5CalledByConMethod, 0l, null);
+      pojo2GetPojo2MethodExec = new MethodInfo(advisor, 0l, pojo2GetPojo2Method, null);
+      pojo2GetPojo2_pojo1IntConstructor = new ConByMethodInfo(advisor, Pojo1.class,
+            pojo2GetPojo2Method, 0l, pojo1IntConstructor, 0l, null, null);
+      pojo2GetPojo2_pojo2StringConstructor = new ConByMethodInfo(advisor,
+            Pojo2.class, pojo2GetPojo2Method, 0l, pojo2StringConstructor, 0l, null,
+            null);
+      Method pojo5CalledByMethod = Pojo5.class.getDeclaredMethod("calledByMethod");
+      pojo2GetPojo2_pojo5CalledByMethod = new MethodByMethodInfo(advisor,
+            Pojo5.class, pojo5CalledByMethod, pojo2GetPojo2Method, 0l, 0l, null);
+      Method pojo2DoSomethingMethod = Pojo2.class.getDeclaredMethod("doSomething",
+            int.class, long.class, Collection.class);
+      pojo2DoSomethingMethodExec = new MethodInfo(advisor, 0l, pojo2DoSomethingMethod, null);
+      Method pojo2GetPojo3Method = Pojo2.class.getDeclaredMethod("getPojo3");
+      pojo2GetPojo3MethodExec = new MethodInfo(advisor, 0l, pojo2GetPojo3Method, null);
+      pojo2GetPojo3_pojo1IntConstructor = new ConByMethodInfo(advisor, Pojo1.class,
+            pojo2GetPojo3Method, 0l, pojo1IntConstructor, 0l, null, null);
+      pojo2GetPojo3_pojo2StringConstructor = new ConByMethodInfo(advisor, Pojo2.class,
+            pojo2GetPojo3Method, 0l, pojo2StringConstructor, 0l, null, null);
+      pojo2GetPojo3_pojo5CalledByMethod = new MethodByMethodInfo(advisor, Pojo5.class,
+            pojo5CalledByMethod, pojo2GetPojo3Method, 0l, 0l, null);
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      pojo2Pojo3ConstructorExec1 = pojo2Pojo3ConstructorExec.copy(instanceAdvisor1);
+      pojo2GetPojo2MethodExec1 = pojo2GetPojo2MethodExec.copy(instanceAdvisor1);
+      pojo2DoSomethingMethodExec1 = new MethodInfo(instanceAdvisor1, 0l, pojo2DoSomethingMethod, null);
+      pojo2GetPojo2_pojo2StringConstructor1 = pojo2GetPojo2_pojo2StringConstructor.copy(instanceAdvisor1);
+      pojo2GetPojo2_pojo5CalledByMethod1 = pojo2GetPojo2_pojo5CalledByMethod.copy(advisor);
+      instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      pojo2StringConstructorExec2 = pojo2StringConstructorExec.copy(instanceAdvisor2);
+      instanceAdvisor3 = new InstanceAdvisorMock(advisor);
+      pojo2StringConstructorExec3 = pojo2StringConstructorExec.copy(instanceAdvisor3);
+
+      // Pojo3
+      advisor = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      field = Pojo3.class.getField("intField");
+      pojo3IntFieldRead = new FieldInfo(advisor, field, 0, true);
+      pojo3IntFieldWrite = new FieldInfo(advisor, field, 0, false);
+      field = Pojo3.class.getDeclaredField("dumbField");
+      pojo3DumbFieldRead = new FieldInfo(advisor, field, 0, true);
+      pojo3DumbFieldWrite = new FieldInfo(advisor, field, 0, false);
+      field = Pojo3.class.getField("ANY_CONSTANT");
+      pojo3AnyConstantRead = new FieldInfo(advisor, field, 0, true);
+      field = Pojo3.class.getDeclaredField("field");
+      pojo3FieldRead = new FieldInfo(advisor, field, 0, true);
+      pojo3FieldWrite = new FieldInfo(advisor, field, 0, false);
+      constructor = Pojo3.class.getDeclaredConstructor();
+      pojo3DefaultConstruction = new ConstructionInfo(advisor, constructor, 1);
+      pojo3DefaultConstructorExec = new ConstructorInfo(advisor, constructor, 1);
+      constructor = Pojo3.class.getDeclaredConstructor(int.class, long.class);
+      pojo3IntLongConstruction = new ConstructionInfo(advisor, constructor, 1);
+      pojo3IntLongConstructorExec = new ConstructorInfo(advisor, constructor, 1);
+      constructor = Pojo3.class.getDeclaredConstructor(int.class, String.class);
+      pojo3IntStringConstruction = new ConstructionInfo(advisor, constructor, 1);
+      pojo3IntStringConstructorExec = new ConstructorInfo(advisor, constructor, 1);
+      pojo3VoidMethodExec = new MethodInfo(advisor, 0l,
+            Pojo3.class.getDeclaredMethod("voidMethod"), null);
+      Method pojo3StringMethod = Pojo3.class.getDeclaredMethod("stringMethod");      
+      pojo3StringMethodExec = new MethodInfo(advisor, 0l, pojo3StringMethod, null);
+      pojo3StringMethod_pojo1IntConstructor = new ConByMethodInfo(advisor,
+            Pojo1.class, pojo3StringMethod, 0l, pojo1IntConstructor, 0l, null, null);
+      pojo3StringMethod_pojo2StringConstructor = new ConByMethodInfo(advisor,
+            Pojo2.class, pojo3StringMethod, 0l, pojo2StringConstructor, 0l, null, null);
+      Method pojo3IntLongSomeMethod = Pojo3.class.getDeclaredMethod("someMethod",
+            int.class, long.class);
+      pojo3IntLongSomeMethodExec = new MethodInfo(advisor, 0l,
+            pojo3IntLongSomeMethod, null);
+      Method pojo3StringLongSomeMethod = Pojo3.class.getDeclaredMethod("someMethod",
+            String.class, long.class);
+      pojo3StringLongSomeMethodExec = new MethodInfo(advisor, 0l,
+            pojo3StringLongSomeMethod, null);
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      pojo3IntLongSomeMethodExec1 = pojo3IntLongSomeMethodExec.copy(instanceAdvisor1);      
+      pojo3StringLongSomeMethodExec1 = pojo3StringLongSomeMethodExec.copy(
+            instanceAdvisor1);
+      pojo3StringMethod_pojo1IntConstructor1 =
+         pojo3StringMethod_pojo1IntConstructor.copy(instanceAdvisor1); 
+      pojo3StringMethod_pojo2StringConstructor1 =
+         pojo3StringMethod_pojo2StringConstructor.copy(instanceAdvisor1);
+      
+      // Pojo4
+      advisor = new AdvisorMock("Pojo4Advisor", Pojo4.class);
+      constructor = Pojo4.class.getDeclaredConstructor();
+      Constructor pojo5CollectionConstructor = Pojo5.class.getDeclaredConstructor(
+             Collection.class);
+      pojo4DefaultConstruction = new ConstructionInfo(advisor, constructor, 0);
+      constructor = Pojo4.class.getDeclaredConstructor();
+      pojo4DefaultConstructorExec = new ConstructorInfo(advisor, constructor, 0);
+      pojo4DefaultConstructor_pojo5CollectionConstructor = new ConByConInfo(
+            advisor, Pojo5.class, Pojo4.class, 0, pojo5CollectionConstructor, 0l,
+            null, null);
+      constructor = Pojo4.class.getDeclaredConstructor(int.class);
+      pojo4IntConstruction = new ConstructionInfo(advisor, constructor, 1);
+      pojo4IntConstructorExec = new ConstructorInfo(advisor, constructor, 1);
+      Constructor pojo5DefaultConstructor = Pojo5.class.getDeclaredConstructor();
+      pojo4IntConstructor_pojo5DefaultConstructor = new ConByConInfo(advisor,
+            Pojo5.class, Pojo4.class, 0, pojo5DefaultConstructor, 0l, null, null);
+      pojo4IntConstructor_pojo5CalledByConMethod = new MethodByConInfo(advisor,
+            Pojo5.class, Pojo4.class, 1, pojo5CalledByConMethod, 0l, null);
+      Method pojo4CallConstructorMethod = Pojo4.class.getDeclaredMethod(
+            "callConstructor");
+      pojo4CallConstructorMethodExec = new MethodInfo(advisor, 0l,
+            pojo4CallConstructorMethod, null);
+      Constructor pojo5Pojo3Constructor = Pojo5.class.getDeclaredConstructor(Pojo3.class);
+      pojo4CallConstructor_pojo5Pojo3Constructor = new ConByMethodInfo(advisor,
+            Pojo5.class, pojo4CallConstructorMethod, 0l, pojo5Pojo3Constructor, 0l,
+            null, null);
+      Method pojo4CallMethodMethod = Pojo4.class.getDeclaredMethod("callMethod");
+      pojo4CallMethodMethodExec = new MethodInfo(advisor, 0l, pojo4CallMethodMethod,
+            null);
+      pojo4CallMethod_pojo5DefaultConstructor = new ConByMethodInfo(advisor,
+            Pojo5.class, pojo4CallMethodMethod, 0l, pojo5DefaultConstructor, 0l,
+            null, null);
+      pojo4CallMethod_pojo5CalledByMethodMethod = new MethodByMethodInfo(advisor,
+            Pojo5.class, pojo5CalledByMethod, pojo4CallMethodMethod, 0l, 0l, null);
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      pojo4CallMethod_pojo5CalledByMethodMethod1 =
+         pojo4CallMethod_pojo5CalledByMethodMethod.copy(instanceAdvisor1);
+      
+      // Pojo5
+      advisor = new AdvisorMock("Pojo5Advisor", Pojo5.class);
+      pojo5DefaultConstruction = new ConstructionInfo(advisor,
+            pojo5DefaultConstructor, 1);
+      pojo5DefaultConstructorExec = new ConstructorInfo(advisor,
+            pojo5DefaultConstructor, 1);
+      pojo5CollectionConstruction = new ConstructionInfo(advisor,
+            pojo5CollectionConstructor, 1);
+      pojo5CollectionConstructorExec = new ConstructorInfo(advisor,
+            pojo5CollectionConstructor, 1);
+      pojo5CollectionConstructor_pojo1IntConstructor = new ConByConInfo(advisor,
+            Pojo1.class, Pojo5.class, 1, pojo1IntConstructor, 0l, null, null);
+      pojo5CollectionConstructor_pojo2StringConstructor = new ConByConInfo(advisor,
+            Pojo1.class, Pojo5.class, 1, pojo2StringConstructor, 0l, null, null);
+      pojo5CollectionConstructor_pojo5CalledByCon = new MethodByConInfo(advisor,
+            Pojo5.class, Pojo5.class, 1, pojo5CalledByConMethod, 0l, null);
+      pojo5Pojo3Construction = new ConstructionInfo(advisor, pojo5Pojo3Constructor,
+            1);
+      pojo5Pojo3ConstructorExec = new ConstructorInfo(advisor, pojo5Pojo3Constructor,
+            1);
+      pojo5CalledByConExec = new MethodInfo(advisor, 0l, pojo5CalledByConMethod,
+            null);
+      pojo5CalledByMethodExec = new MethodInfo(advisor, 0l, pojo5CalledByMethod,
+            null);
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      pojo5CollectionConstructor_pojo1IntConstructor1 = pojo5CollectionConstructor_pojo1IntConstructor.copy(instanceAdvisor1);
+      pojo5CollectionConstructor_pojo2StringConstructor1 = pojo5CollectionConstructor_pojo2StringConstructor.copy(instanceAdvisor1);
+      pojo5CollectionConstructor_pojo5CalledByCon1 = pojo5CollectionConstructor_pojo5CalledByCon.copy(instanceAdvisor1);
+      instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      pojo5CalledByConExec2 = pojo5CalledByConExec.copy(instanceAdvisor2);
+      
+      // AnnPojo
+      advisor = new AdvisorMock("AnnPojoAdvisor", AnnPojo.class);
+      Constructor multiArgConstructor1 = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, AnyAnnotationPojo.class, DummyAnnotationPojo.class);
+      annPojoMultiArgConstruction1 = new ConstructionInfo(advisor,
+            multiArgConstructor1, 0);
+      annPojoMultiArgConstructor1Exec = new ConstructorInfo(advisor,
+            multiArgConstructor1, 0);
+      Constructor multiArgConstructor2 = AnnPojo.class.getDeclaredConstructor(
+            int.class, Pojo2.class, long.class, DummyAnnotationPojo.class);
+      annPojoMultiArgConstruction2= new ConstructionInfo(advisor,
+            multiArgConstructor2, 1);
+      annPojoMultiArgConstructor2_pojo1IntConstructor = new ConByConInfo(advisor,
+            Pojo1.class, AnnPojo.class, 1, pojo1IntConstructor, 0l, null, null);
+      annPojoMultiArgConstructor2_pojo2StringConstructor = new ConByConInfo(advisor,
+            Pojo2.class, AnnPojo.class, 1, pojo2StringConstructor, 0l, null, null);
+      annPojoMultiArgConstructor2Exec = new ConstructorInfo(advisor,
+            multiArgConstructor2, 1);
+      Constructor multiArgConstructor3 = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, DummyAnnotationPojo.class, long.class);
+      annPojoMultiArgConstruction3 = new ConstructionInfo(advisor,
+            multiArgConstructor3, 2);
+      annPojoMultiArgConstructor3Exec = new ConstructorInfo(advisor,
+            multiArgConstructor3, 2);
+      constructor = AnnPojo.class.getDeclaredConstructor(
+            Pojo2.class, int.class, long.class);
+      annPojoMultiArgConstruction4 = new ConstructionInfo(advisor, constructor, 3);
+      annPojoMultiArgConstructor4Exec = new ConstructorInfo(advisor, constructor, 3);
+      constructor = AnnPojo.class.getDeclaredConstructor(
+            String.class, int.class, long.class, DummyAnnotationPojo.class,
+            AnyAnnotationPojo.class);
+      annPojoMultiArgConstruction5 = new ConstructionInfo(advisor, constructor, 4);
+      annPojoMultiArgConstructor5Exec = new ConstructorInfo(advisor, constructor, 4);
+      constructor = AnnPojo.class.getDeclaredConstructor(DummyAnnotationPojo.class,
+            AnyAnnotationPojo.class);
+      annPojoMultiArgConstruction6 = new ConstructionInfo(advisor, constructor, 5);
+      annPojoMultiArgConstructor6Exec = new ConstructorInfo(advisor, constructor, 5);
+      constructor = AnnPojo.class.getDeclaredConstructor(AnyAnnotationPojo.class);
+      annPojoMultiArgConstruction7 = new ConstructionInfo(advisor, constructor, 6);
+      annPojoMultiArgConstructor7Exec = new ConstructorInfo(advisor, constructor, 6);
+      Method annPojoMethod1 = AnnPojo.class.getDeclaredMethod("method1", Pojo2.class,
+            AnyAnnotationPojo.class, DummyAnnotationPojo.class);
+      annPojoMethod1Exec = new MethodInfo(advisor, 0l, annPojoMethod1, null);
+      Method annPojoMethod2 = AnnPojo.class.getDeclaredMethod("method2", int.class,
+            Pojo2.class, long.class, DummyAnnotationPojo.class);
+      annPojoMethod2Exec = new MethodInfo(advisor, 0l, annPojoMethod2, null);
+      Method annPojoMethod3 = AnnPojo.class.getDeclaredMethod("method3", Pojo2.class,
+            DummyAnnotationPojo.class, long.class);
+      annPojoMethod3Exec = new MethodInfo(advisor, 0l, annPojoMethod3, null);
+      Method annPojoMethod4 = AnnPojo.class.getDeclaredMethod("method4", Pojo2.class,
+            int.class, long.class);
+      annPojoMethod4Exec = new MethodInfo(advisor, 0l, annPojoMethod4, null);
+      Method annPojoMethod5 = AnnPojo.class.getDeclaredMethod("method5", String.class,
+            int.class, long.class, DummyAnnotationPojo.class, AnyAnnotationPojo.class);
+      annPojoMethod4_pojo5CalledByMethod = new MethodByMethodInfo(advisor,
+            Pojo5.class, pojo5CalledByMethod, annPojoMethod4, 0l, 0l, null);
+      annPojoMethod5Exec = new MethodInfo(advisor, 0l, annPojoMethod5, null);
+      Method annPojoMethod6 = AnnPojo.class.getDeclaredMethod("method6",
+            DummyAnnotationPojo.class, AnyAnnotationPojo.class);
+      annPojoMethod6Exec = new MethodInfo(advisor, 0l, annPojoMethod6, null);
+      Method annPojoMethod7 = AnnPojo.class.getDeclaredMethod("method7",
+            AnyAnnotationPojo.class);
+      annPojoMethod7Exec = new MethodInfo(advisor, 0l, annPojoMethod7, null);
+      
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      annPojoMultiArgConstructor3Exec1 = annPojoMultiArgConstructor3Exec.copy(instanceAdvisor1);
+      annPojoMultiArgConstructor6Exec1 = annPojoMultiArgConstructor6Exec.copy(instanceAdvisor1);
+      annPojoMethod1Exec1 = annPojoMethod1Exec.copy(instanceAdvisor1);
+      annPojoMethod2Exec1 = annPojoMethod2Exec.copy(instanceAdvisor1);
+      annPojoMethod3Exec1 = annPojoMethod3Exec.copy(instanceAdvisor1);
+      annPojoMethod4Exec1 = annPojoMethod4Exec.copy(instanceAdvisor1);
+      annPojoMethod5Exec1 = annPojoMethod5Exec.copy(instanceAdvisor1);
+      instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      annPojoMultiArgConstructor4Exec2 = annPojoMultiArgConstructor4Exec.copy(
+            instanceAdvisor2);
+      annPojoMultiArgConstruction5_2 = annPojoMultiArgConstruction5.copy(
+            instanceAdvisor2);
+      annPojoMultiArgConstructor5Exec2 = annPojoMultiArgConstructor5Exec.copy(
+            instanceAdvisor2);
+      annPojoMultiArgConstruction6_2 = annPojoMultiArgConstruction6.copy(
+            instanceAdvisor2);
+      annPojoMultiArgConstructor2_pojo1IntConstructor2 =
+         annPojoMultiArgConstructor2_pojo1IntConstructor.copy(instanceAdvisor2);
+      annPojoMultiArgConstructor2_pojo2StringConstructor2 =
+         annPojoMultiArgConstructor2_pojo2StringConstructor.copy(instanceAdvisor2);
+      instanceAdvisor3 = new InstanceAdvisorMock(advisor);
+      annPojoMultiArgConstructor6Exec3 = annPojoMultiArgConstructor6Exec.copy(
+            instanceAdvisor3);
+      annPojoMethod1Exec3 = annPojoMethod1Exec.copy(instanceAdvisor3);
+      annPojoMethod3Exec3 = annPojoMethod3Exec.copy(instanceAdvisor3);
+      annPojoMethod5Exec3 = annPojoMethod5Exec.copy(instanceAdvisor3);
+      annPojoMethod6Exec3 = annPojoMethod6Exec.copy(instanceAdvisor3);
+      annPojoMethod7Exec3 = annPojoMethod7Exec.copy(instanceAdvisor3);
+      annPojoMethod4_pojo5CalledByMethod3 = annPojoMethod4_pojo5CalledByMethod.copy(
+            instanceAdvisor3);
+      
+      // AnyAnnotationPojo
+      advisor = new AdvisorMock("AnyAnnotationPojoAdvisor", AnyAnnotationPojo.class);
+      constructor = AnyAnnotationPojo.class.getDeclaredConstructor(int.class);
+      anyAnnotationPojoIntConstruction = new ConstructionInfo(advisor, constructor, 0);
+      anyAnnotationPojoIntConstructorExec = new ConstructorInfo(advisor, constructor, 0);
+      anyAnnotationPojoMethod1Exec = new MethodInfo(advisor, 0l,
+            AnyAnnotationPojo.class.getDeclaredMethod("method1"), null);
+      anyAnnotationPojoMethod2Exec = new MethodInfo(advisor, 0l,
+            AnyAnnotationPojo.class.getDeclaredMethod("method2"), null);
+      
+      // DummyAnnotationPojo
+      advisor = new AdvisorMock("DummyAnnotationPojoAdvisor", DummyAnnotationPojo.class);
+      dummyAnnotationPojoMethodExec = new MethodInfo(advisor, 0l,
+            DummyAnnotationPojo.class.getDeclaredMethod("method"), null);
+      Method dummyAnnotationPojoInterfaceMethod = DummyAnnotationPojo.class.
+         getDeclaredMethod("interfaceMethod");
+      dummyAnnotationPojoInterfaceMethodExec = new MethodInfo(advisor, 0l,
+            dummyAnnotationPojoInterfaceMethod, null);
+      Method dummyAnnotationPojoInterfaceMethod2 = DummyAnnotationPojo.class.
+         getDeclaredMethod("interfaceMethod2");
+      dummyAnnotationPojoInterfaceMethod2Exec = new MethodInfo(advisor, 0l,
+            dummyAnnotationPojoInterfaceMethod2, null);
+      instanceAdvisor1 = new InstanceAdvisorMock(advisor);
+      dummyAnnotationPojoInterfaceMethod2Exec1 =
+         dummyAnnotationPojoInterfaceMethod2Exec.copy(instanceAdvisor1);
+      instanceAdvisor2 = new InstanceAdvisorMock(advisor);
+      dummyAnnotationPojoInterfaceMethodExec2 = 
+         dummyAnnotationPojoInterfaceMethodExec.copy(instanceAdvisor2);
+      dummyAnnotationPojoInterfaceMethod2Exec2 =
+         dummyAnnotationPojoInterfaceMethod2Exec.copy(instanceAdvisor2);
+      
+      // DummyAnnotationPojo2
+      advisor = new AdvisorMock("DummyAnnotationPojo2Advisor", DummyAnnotationPojo2.class);
+      constructor = DummyAnnotationPojo2.class.getDeclaredConstructor(DummyInterface2.class);
+      dummyAnnotationPojo2DummyInterface2Construction = new ConstructionInfo(advisor,
+            constructor, 0);
+      dummyAnnotationPojo2DummyInterface2ConstructorExec = new ConstructorInfo(advisor,
+            constructor, 1);
+      dummyAnnotationPojo2Method1Exec = new MethodInfo(advisor, 0l,
+            DummyAnnotationPojo2.class.getDeclaredMethod("method1"), null);
+      dummyAnnotationPojo2Method2Exec = new MethodInfo(advisor, 0l,
+            DummyAnnotationPojo2.class.getDeclaredMethod("method2", int.class), null);
+      dummyAnnotationPojo2InterfaceMethodExec = new MethodInfo(advisor, 0l,
+            DummyAnnotationPojo2.class.getDeclaredMethod("interfaceMethod"), null);
+      dummyAnnotationPojo2InterfaceMethod2Exec = new MethodInfo(advisor, 0l,
+            DummyAnnotationPojo2.class.getDeclaredMethod("interfaceMethod2"), null);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -58,16 +58,13 @@
    private Advisor advisor = null;
    private Advisor instanceAdvisor = null;
    private Field infoRegistryField = null;
-   Tree<ClassNode> classTree = null;
+   Tree<StandardClassNode> classTree = null;
    private MainJoinPointGraph graph = null;
    public void setUp() throws Exception
    {
-      Field classTreeField = JoinPointGraphImpl.class.getDeclaredField("classTree");
-      classTreeField.setAccessible(true);
       this.graph = MainJoinPointGraph.getInstance();
-      classTree = new Tree<ClassNode>();
-      classTreeField.set(this.graph, classTree);
-      
+      classTree = new Tree<StandardClassNode>();
+      graph.classTree = classTree;
       advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
       instanceAdvisor = new InstanceAdvisorMock(advisor);
       infoRegistryField = JoinPointInfo.class.getDeclaredField("registry");
@@ -86,10 +83,7 @@
          public void register(ConByMethodInfo info){}
          public void register(MethodByConInfo info){}
          public void register(MethodByMethodInfo info){}});
-      Field classTreeField = JoinPointGraphImpl.class.getDeclaredField("classTree");
-      classTreeField.setAccessible(true);
-      classTreeField.set(MainJoinPointGraph.getInstance(),
-            new Tree<StandardClassNode>());
+      graph.classTree = new Tree<StandardClassNode>();
    }
    
    public void testFieldReadInfo() throws Exception
@@ -240,8 +234,8 @@
       ConByConInfo info = new ConByConInfo(advisor, Pojo1.class, Pojo1.class, 0,
             calleeConstructor, 0l, null, null);
       // check if it has been inserted to the graph correctly
-      assertConstructorCallInfo(Pojo1.class, BehaviorType.CONSTRUCTOR, callerConstructor,
-            Pojo1.class, calleeConstructor, info);
+      assertConstructorCallInfo(Pojo1.class, BehaviorType.CONSTRUCTOR,
+            callerConstructor, Pojo1.class, calleeConstructor, info);
    }
    
    public void testConByConInfoInstanceDomain() throws Exception
@@ -556,7 +550,7 @@
       ClassNode classNode = classTree.searchValue(Pojo1.class.getName());
       assertNotNull(classNode);
       Collection<BehaviorNode> behaviorNodesFound = classNode.searchBehaviors(
-            behaviorType.getDefaultKey(behavior));
+            behaviorType.getIdentifierKey(behavior));
       assertEquals(infos.length, behaviorNodesFound.size());
       Collection<JoinPointInfo> infoCol = new HashSet<JoinPointInfo>(
             Arrays.asList(infos));
@@ -593,7 +587,7 @@
             getIdentifierKey(callerClass));
       assertNotNull(classNode);
       Collection<BehaviorNode> behaviorNodesFound = classNode.
-         searchBehaviors(callerType.getDefaultKey(caller));
+         searchBehaviors(callerType.getIdentifierKey(caller));
       assertEquals(infos.length, behaviorNodesFound.size());
       Collection<JoinPointInfo> infoCol = new HashSet<JoinPointInfo>
          (Arrays.asList(infos));
@@ -601,8 +595,8 @@
       for (BehaviorNode behaviorNode: behaviorNodesFound)
       {
          assertEquals(caller, behaviorNode.getBehavior());
-         behaviorNode.searchCallees(ClassNode.getIdentifierKey(calleeClass) + '.' +
-            calleeType.getDefaultKey(callee), callees);
+         behaviorNode.searchCallees(ClassNode.getIdentifierKey(calleeClass) +
+               BehaviorNode.SEPARATOR + calleeType.getIdentifierKey(callee), callees);
          if (callees.isEmpty())
          {
             continue;

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ParamSearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ParamSearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/ParamSearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,952 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutExpression;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+
+/**
+ * Tests {@link SearchKeyParser} on behavior pointcut expressions with complex
+ * param lists.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class ParamSearchKeyParserTest extends AbstractSearchKeyParserTest
+{
+   public void testZeroOrMoreParams1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "construction(Pojo->new(..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo", "new#*",
+      BehaviorSearcher.SearchType.CONSTRUCTION);
+      assertNull(filter);
+   }
+   
+   public void testZeroOrMoreParams2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(int, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int * ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testZeroOrMoreParams3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int  ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+
+   public void testZeroOrMoreParams4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int  ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+
+   public void testZeroOrMoreParams5() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., int, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int * ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testZeroOrMoreParams7() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|*",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testZeroOrMoreParams8() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., .., int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int  ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testZeroOrMoreParams9() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., .., int, .., ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int * ",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testWildcard1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| int  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testWildcard2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testWildcard3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, long))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||| long  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testTwoWildcardParam() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testThreeWildcardParam() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedThreeParamBehavior1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(Pojo2, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| Pojo2 ||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedThreeParamBehavior2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, DummyAnnotationPojo, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| DummyAnnotationPojo ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedThreeParamBehavior3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, long))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||| long  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testFourParamBehavior() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||| int  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||| DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, long, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||| long ||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior5() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, Pojo2, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| Pojo2 ||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior6() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, Pojo2, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int | Pojo2 ||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior7() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, long, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||| long ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior8() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, *, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||||| DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior9() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, Pojo2, long, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| Pojo2 | long ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior10() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, Pojo2, *, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| Pojo2 ||| DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior11() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, long, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||| long | DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior12() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, Pojo2, long, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int | Pojo2 | long ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior13() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, Pojo2, *, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int | Pojo2 ||| DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior14() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, long, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||| long | DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedFourParamBehavior15() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, Pojo2, long, DummyAnnotationPojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| Pojo2 | long | DummyAnnotationPojo  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testFiveParamBehavior() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testFiveOrMorParamBehavior() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testSixParamBehavior() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards5() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards6() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *, *, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||||||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards7() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., *, *, *, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||||||||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards8() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards9() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards10() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards11() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards12() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, *, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||||||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards13() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards14() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, .., *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards15() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||*||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards16() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, .., *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards17() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, .., *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||*||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards18() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, *, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards19() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., int, *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int ||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards20() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, .., *, *, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int *||||||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards21() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, *, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||||*||", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards22() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, *, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||||*", BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards23() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, *, DummyAnnotationPojo, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||||| DummyAnnotationPojo * ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards24() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, .., long, *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||* long ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards25() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, long, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||| long *||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testMixedWildcardZeroOrMoreWildcards26() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, *, .., long, .., *))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||* long *||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertNull(filter);
+   }
+   
+   public void testAscFilter1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(@DummyAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "@DummyAnnotation");
+   }
+   
+   public void testAscFilter2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(@DummyAnnotation, int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||| int  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, @DummyAnnotation, int))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||| int  ",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, null, "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(int, @DummyAnnotation, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#| int ||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, null, "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter5() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, *, @DummyAnnotation, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, null, null, "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter6() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(*, @AnyAnnotation, @DummyAnnotation, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, null, "@AnyAnnotation", "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter7() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(@AnyAnnotation, *, @DummyAnnotation, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "@AnyAnnotation", null, "@DummyAnnotation", null);
+   }
+   
+   public void testAscFilter8() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method($instanceof{@AnyAnnotation}, *, $instanceof{Pojo}, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "$instanceof{@AnyAnnotation}", null,
+            "$instanceof{Pojo}", null);
+   }
+   
+   public void testAscFilter9() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(Pojo*, P*ojo*, *Pojo))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "Pojo*", "P*ojo*", "*Pojo");
+   }
+   
+   public void testAscFilter10() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(a*, *, P*ojo, ..))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||||*",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "a*", null, "P*ojo", null);
+   }
+   
+   public void testDescFilter1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., $instanceof{Pojo}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertDescParamFilter(filter, null, "$instanceof{Pojo}");
+   }
+   
+   public void testDescFilter2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., .., $instanceof{Pojo}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertDescParamFilter(filter, null, null, "$instanceof{Pojo}");
+   }
+   
+   public void testDescFilter3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., .., $instanceof{Pojo}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#*||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertDescParamFilter(filter, null, null, "$instanceof{Pojo}");
+   }
+   
+   public void testDescFilter4() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+      "execution(void Pojo->method(.., int, .., $instanceof{Pojo}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int *||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertDescParamFilter(filter, null, null, null, "$instanceof{Pojo}");
+   }
+   
+   public void testDescFilter5() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(.., int, .., $instanceof{Pojo}, long, *, " +
+            "@AnyAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#|* int *||| long ||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertDescParamFilter(filter, null, null, null, "$instanceof{Pojo}", null,
+            null, "@AnyAnnotation");
+   }
+   
+   public void testCompParamFilter1() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(@AnyAnnotation, .., @DummyAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      BehaviorFilter filter1 = getConjSubFilter1(filter);
+      assertAscParamFilter(filter1, "@AnyAnnotation", null, null);
+      BehaviorFilter filter2 = getConjSubFilter2(filter);
+      assertDescParamFilter(filter2, null, null, "@DummyAnnotation");
+   }
+   
+   public void testCompParamFilter2() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(@AnyAnnotation, .., int, long, Pojo, .., " +
+            "char, .., Pojo, @DummyAnnotation))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||* int | long | Pojo *| char *| Pojo ||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      BehaviorFilter filter1 = getConjSubFilter1(filter);
+      assertAscParamFilter(filter1, "@AnyAnnotation", null, null, null, null, null,
+            null, null, null, null);
+      BehaviorFilter filter2 = getConjSubFilter2(filter);
+      assertDescParamFilter(filter2, null, null, null, null, null, null, null, null,
+            null, "@DummyAnnotation");
+   }
+   
+   public void testCompParamFilter3() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method(@AnyAnnotation, $instanceof{Pojo*}, .., " +
+            "Pojo, @DummyAnnotation, $instanceof{@DummyAnnotation}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||||* Pojo ||||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      BehaviorFilter filter1 = getConjSubFilter1(filter);
+      assertAscParamFilter(filter1, "@AnyAnnotation", "$instanceof{Pojo*}", null,
+            null, null, null);
+      BehaviorFilter filter2 = getConjSubFilter2(filter);
+      assertDescParamFilter(filter2, null, null, null, null, "@DummyAnnotation",
+            "$instanceof{@DummyAnnotation}");
+   }
+   
+   public void testTypedefParam1() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(@" +
+            DummyAnnotation.class.getName() + ") OR has(int *->length()) OR" +
+                  "class($instanceof{@" + AnyAnnotation.class.getName() + "})");
+      AspectManager.instance().addTypedef(typedef);
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method($typedef{ComplexExp}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "$typedef{ComplexExp}");
+   }
+   
+   public void testTypedefParam2() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(Pojo*) OR " +
+            "has(int *->length()) OR class($instanceof{@" +
+            AnyAnnotation.class.getName() + "})");
+      AspectManager.instance().addTypedef(typedef);
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method($typedef{ComplexExp}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "$typedef{ComplexExp}");
+   }
+   
+   public void testTypedefParam3() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("ComplexExp", "class(*)");
+      AspectManager.instance().addTypedef(typedef);
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method($typedef{ComplexExp}))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||",
+            BehaviorSearcher.SearchType.EXECUTION);
+      assertAscParamFilter(filter, "$typedef{ComplexExp}");
+   }
+   
+   public void testFullParameterFilterParam() throws Exception
+   {
+      Pointcut pointcut = new PointcutExpression("pointcut",
+            "execution(void Pojo->method($typedef{ComplexExp}, .., a*, b*, .., c*))");
+      SearchKey searchKey = SearchKeyParser.parse(pointcut);
+      BehaviorFilter filter = assertBehaviorSearchKey(searchKey, "Pojo",
+            "void| method#||*||||*||",
+      BehaviorSearcher.SearchType.EXECUTION);
+      assertFullParamFilter(filter, "$typedef{ComplexExp}", "..", "a*", "b*", "..", "c*");
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/PointcutDelegatorTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/PointcutDelegatorTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/PointcutDelegatorTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,321 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import javassist.CtConstructor;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.expr.MethodCall;
+import javassist.expr.NewExpr;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.pointcut.PointcutMethodMatch;
+
+/**
+ * Tests {@code PointcutDelegator}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class PointcutDelegatorTest extends FullScenarioBuilder
+{
+   public void test1()
+   {
+      getAllPojo().search(classTree, result);
+      Util.assertCollection(result, pojo1FieldRead, pojo1FieldWrite,
+            pojo1DefaultConstruction, pojo1DefaultConstruction1,
+            pojo1DefaultConstruction3, pojo1DefaultConstructorExec,
+            pojo1IntConstruction, pojo1IntConstructorExec,
+            pojo1IntConstructorExec2, pojo1Method1Exec, pojo1PrivateMethodExec,
+            pojo1PrivateMethodExec1, pojo1PrivateMethodExec2,
+            pojo1PrivateMethodExec3, pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod, pojo2Pojo3Read, pojo2Pojo3Write,
+            pojo2Pojo3Construction, pojo2Pojo3ConstructorExec,
+            pojo2Pojo3ConstructorExec1, pojo2DefaultConstruction,
+            pojo2DefaultConstructorExec, pojo2StringConstruction,
+            pojo2StringConstructorExec, pojo2StringConstructorExec2,
+            pojo2StringConstructorExec3, pojo2GetPojo2MethodExec,
+            pojo2GetPojo2MethodExec1, pojo2DoSomethingMethodExec,
+            pojo2DoSomethingMethodExec1, pojo2GetPojo3MethodExec,
+            pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor, pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1, pojo2GetPojo3_pojo1IntConstructor,
+            pojo2GetPojo3_pojo2StringConstructor, pojo2GetPojo3_pojo5CalledByMethod,
+            pojo3IntFieldRead, pojo3IntFieldWrite, pojo3DumbFieldRead,
+            pojo3DumbFieldWrite, pojo3AnyConstantRead, pojo3FieldRead,
+            pojo3FieldWrite, pojo3DefaultConstruction, pojo3DefaultConstructorExec,
+            pojo3IntLongConstruction, pojo3IntLongConstructorExec,
+            pojo3IntStringConstruction, pojo3IntStringConstructorExec,
+            pojo3VoidMethodExec, pojo3StringMethodExec, pojo3IntLongSomeMethodExec,
+            pojo3IntLongSomeMethodExec1, pojo3StringLongSomeMethodExec,
+            pojo3StringLongSomeMethodExec1, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1, pojo4DefaultConstruction,
+            pojo4DefaultConstructorExec, pojo4IntConstruction,
+            pojo4IntConstructorExec, pojo4CallConstructorMethodExec,
+            pojo4CallMethodMethodExec,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1, pojo5DefaultConstruction,
+            pojo5DefaultConstructorExec, pojo5CollectionConstruction,
+            pojo5CollectionConstructorExec, pojo5Pojo3Construction,
+            pojo5Pojo3ConstructorExec, pojo5CalledByConExec, pojo5CalledByConExec2,
+            pojo5CalledByMethodExec, pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1);
+   }
+   
+   public void test2()
+   {
+      getPojo1AndPojo2Cons().search(classTree, result);
+      Util.assertCollection(result, pojo1DefaultConstructorExec,
+            pojo1IntConstructorExec, pojo1IntConstructorExec2,
+            pojo2Pojo3ConstructorExec, pojo2Pojo3ConstructorExec1,
+            pojo2DefaultConstructorExec, pojo2StringConstructorExec,
+            pojo2StringConstructorExec2, pojo2StringConstructorExec3);
+   }
+   
+   public static ParsedSearchKey getAllPojo()
+   {
+      Pointcut pointcut = new Pointcut()
+      {
+         public String getExpr()
+         {
+            return null;
+         }
+
+         public String getName()
+         {
+            return null;
+         }
+
+         public boolean matchesCall(Advisor callingAdvisor, MethodCall methodCall) throws NotFoundException
+         {
+            return callingAdvisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesCall(Advisor callingAdvisor, NewExpr methodCall) throws NotFoundException
+         {
+            return callingAdvisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesCall(Advisor advisor, AccessibleObject within, Class<?> calledClass, Method calledMethod)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesCall(Advisor advisor, AccessibleObject within, Class<?> calledClass, Constructor<?> calledCon)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesConstruction(Advisor advisor, CtConstructor c) throws NotFoundException
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesConstruction(Advisor advisor, Constructor<?> c)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesExecution(Advisor advisor, CtMethod m) throws NotFoundException
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesExecution(Advisor advisor, CtConstructor c) throws NotFoundException
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public PointcutMethodMatch matchesExecution(Advisor advisor, Method m)
+         {
+            return new PointcutMethodMatch(advisor.getClazz().getName().
+                  startsWith(this.getClass().getPackage().getName() + ".Pojo"), null, 0,
+                  false);
+         }
+
+         public boolean matchesExecution(Advisor advisor, Constructor<?> c)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesGet(Advisor advisor, CtField f) throws NotFoundException
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesGet(Advisor advisor, Field f)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesSet(Advisor advisor, CtField f) throws NotFoundException
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean matchesSet(Advisor advisor, Field f)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }
+
+         public boolean softMatch(Advisor advisor)
+         {
+            return advisor.getClazz().getName().startsWith(
+                  this.getClass().getPackage().getName() + ".Pojo");
+         }         
+      };
+      return new PointcutDelegator(pointcut);
+   }
+   
+   public static ParsedSearchKey getPojo1AndPojo2Cons()
+   {
+      Pointcut pointcut = new Pointcut()
+      {
+         public String getExpr()
+         {
+            return null;
+         }
+
+         public String getName()
+         {
+            return null;
+         }
+
+         public boolean matchesCall(Advisor callingAdvisor, MethodCall methodCall) throws NotFoundException
+         {
+            return false;
+         }
+
+         public boolean matchesCall(Advisor callingAdvisor, NewExpr methodCall) throws NotFoundException
+         {
+            return false;
+         }
+
+         public boolean matchesCall(Advisor advisor, AccessibleObject within, Class<?> calledClass, Method calledMethod)
+         {
+            return false;
+         }
+
+         public boolean matchesCall(Advisor advisor, AccessibleObject within, Class<?> calledClass, Constructor<?> calledCon)
+         {
+            return false;
+         }
+
+         public boolean matchesConstruction(Advisor advisor, CtConstructor c) throws NotFoundException
+         {
+            return false;
+         }
+
+         public boolean matchesConstruction(Advisor advisor, Constructor<?> c)
+         {
+            return false;
+         }
+
+         public boolean matchesExecution(Advisor advisor, CtMethod m) throws NotFoundException
+         {
+            return false;
+         }
+
+         @SuppressWarnings("deprecation")
+         public boolean matchesExecution(Advisor advisor, CtConstructor c) throws NotFoundException
+         {
+            return advisor.getClazz().getName().equals(Pojo1.class.getName()) ||
+               advisor.getClazz().getName().equals(Pojo2.class.getName());
+         }
+
+         public PointcutMethodMatch matchesExecution(Advisor advisor, Method m)
+         {
+            return new PointcutMethodMatch(false, null, 0, false);
+         }
+
+         @SuppressWarnings("deprecation")
+         public boolean matchesExecution(Advisor advisor, Constructor<?> c)
+         {
+            return advisor.getClazz().getName().equals(Pojo1.class.getName()) ||
+            advisor.getClazz().getName().equals(Pojo2.class.getName());
+         }
+
+         public boolean matchesGet(Advisor advisor, CtField f) throws NotFoundException
+         {
+            return false;
+         }
+
+         public boolean matchesGet(Advisor advisor, Field f)
+         {
+            return false;
+         }
+
+         public boolean matchesSet(Advisor advisor, CtField f) throws NotFoundException
+         {
+            return false;
+         }
+
+         public boolean matchesSet(Advisor advisor, Field f)
+         {
+            return false;
+         }
+
+         @SuppressWarnings("deprecation")
+         public boolean softMatch(Advisor advisor)
+         {
+            return advisor.getClazz().getName().equals(Pojo1.class.getName()) ||
+               advisor.getClazz().getName().equals(Pojo2.class.getName());
+         }         
+      };
+      return new PointcutDelegator(pointcut);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo2.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo2.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo2.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -40,10 +40,14 @@
    
    public Pojo2(){}
    
-   public Pojo2(String arg){}
+   public Pojo2(String arg)
+   {
+      new Pojo1(1);
+   }
    
    public static final Pojo2 getPojo2()
    {
+      new Pojo1(0);
       return null;
    }
    

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo4.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo4.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo4.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -41,7 +41,7 @@
    }
    
    @SuppressWarnings("deprecation")
-   public void callConstructor()
+   public void callConstructor() throws Exception
    {
       new Pojo5(new Pojo3());
    }

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -49,16 +49,21 @@
    public Pojo5() {}
    
    @AnyAnnotation
-   public Pojo5(Collection arg) {}
+   protected Pojo5(Collection arg)
+   {
+      new Pojo1(5);
+      new Pojo2("Pojo5");
+      this.calledByCon();
+   }
    
    @Deprecated
-   public Pojo5(Pojo3 pojo3) {}
+   public Pojo5(Pojo3 pojo3) throws Exception {}
    
    @Bind(pointcut="all(Pojo5)")
-   public void calledByCon(){}
+   public void calledByCon() throws NullPointerException, IllegalStateException {}
    
    @Mixin(interfaces={MetaDataKeyLoader.class})
-   public void calledByMethod() {}
+   void calledByMethod() {}
 }
 
 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SearchKeyParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SearchKeyParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SearchKeyParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that contains all {@code SearchKeyParser} test cases.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class SearchKeyParserTest extends TestSuite
+{
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Test for " + SearchKeyParser.class.getName());
+      //$JUnit-BEGIN$
+      suite.addTestSuite(CompositeSearchKeyParserTest.class);
+      suite.addTestSuite(ClassSearchKeyParserTest.class);
+      suite.addTestSuite(FieldSearchKeyParserTest.class);
+      suite.addTestSuite(BehaviorSearchKeyParserTest.class);
+      suite.addTestSuite(ParamSearchKeyParserTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/StandardSearchKeyTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/StandardSearchKeyTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/StandardSearchKeyTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,613 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.BehaviorSearcher.SearchType;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTException;
+
+
+/**
+ * Tests {@link StandardSearchKey}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class StandardSearchKeyTest extends FullScenarioBuilder
+{
+   public void testSearchAll()
+   {
+      ParsedSearchKey searchKey = getAllSearchKey();
+      searchKey.finishParsing();
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1FieldRead, pojo1FieldWrite,
+            pojo1DefaultConstructorExec, pojo1IntConstructorExec,
+            pojo1IntConstructorExec2, pojo1Method1Exec, pojo1PrivateMethodExec,
+            pojo1PrivateMethodExec1, pojo1PrivateMethodExec2,
+            pojo1PrivateMethodExec3, pojo2Pojo3Read, pojo2Pojo3Write,
+            pojo2Pojo3ConstructorExec, pojo2Pojo3ConstructorExec1,
+            pojo2DefaultConstructorExec, pojo2StringConstructorExec,
+            pojo2StringConstructorExec2, pojo2StringConstructorExec3,
+            pojo2GetPojo2MethodExec, pojo2GetPojo2MethodExec1,
+            pojo2DoSomethingMethodExec, pojo2DoSomethingMethodExec1,
+            pojo2GetPojo3MethodExec, pojo3IntFieldRead, pojo3IntFieldWrite,
+            pojo3DumbFieldRead, pojo3DumbFieldWrite, pojo3AnyConstantRead,
+            pojo3FieldRead, pojo3FieldWrite, pojo3DefaultConstructorExec,
+            pojo3IntLongConstructorExec, pojo3IntStringConstructorExec,
+            pojo3VoidMethodExec, pojo3StringMethodExec, pojo3IntLongSomeMethodExec,
+            pojo3IntLongSomeMethodExec1, pojo3StringLongSomeMethodExec,
+            pojo3StringLongSomeMethodExec1, pojo4DefaultConstructorExec,
+            pojo4IntConstructorExec, pojo4CallConstructorMethodExec,
+            pojo4CallMethodMethodExec, pojo5DefaultConstructorExec,
+            pojo5CollectionConstructorExec, pojo5Pojo3ConstructorExec,
+            pojo5CalledByConExec, pojo5CalledByConExec2, pojo5CalledByMethodExec,
+            annPojoMultiArgConstructor1Exec, annPojoMultiArgConstructor2Exec,
+            annPojoMultiArgConstructor3Exec, annPojoMultiArgConstructor3Exec1,
+            annPojoMultiArgConstructor4Exec, annPojoMultiArgConstructor4Exec2,
+            annPojoMultiArgConstructor5Exec, annPojoMultiArgConstructor5Exec2,
+            annPojoMultiArgConstructor6Exec, annPojoMultiArgConstructor6Exec1,
+            annPojoMultiArgConstructor6Exec3, annPojoMultiArgConstructor7Exec,
+            annPojoMethod1Exec, annPojoMethod1Exec1, annPojoMethod1Exec3,
+            annPojoMethod2Exec, annPojoMethod2Exec1, annPojoMethod3Exec,
+            annPojoMethod3Exec1, annPojoMethod3Exec3, annPojoMethod4Exec,
+            annPojoMethod4Exec1, annPojoMethod5Exec, annPojoMethod5Exec1,
+            annPojoMethod5Exec3, annPojoMethod6Exec, annPojoMethod6Exec3,
+            annPojoMethod7Exec, annPojoMethod7Exec3,
+            anyAnnotationPojoIntConstructorExec, anyAnnotationPojoMethod1Exec,
+            anyAnnotationPojoMethod2Exec, dummyAnnotationPojoMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec,
+            dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);
+   }
+   
+   public void testSearchAllCall()
+   {
+      ParsedSearchKey searchKey = getAllCallSearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod,
+            pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor,
+            pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1,
+            pojo2GetPojo2_pojo5CalledByMethod, pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo1IntConstructor, pojo2GetPojo3_pojo2StringConstructor,
+            pojo2GetPojo3_pojo5CalledByMethod, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1,
+            annPojoMultiArgConstructor2_pojo1IntConstructor,
+            annPojoMultiArgConstructor2_pojo1IntConstructor2,
+            annPojoMultiArgConstructor2_pojo2StringConstructor,
+            annPojoMultiArgConstructor2_pojo2StringConstructor2,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testSearchRestrictionCall()
+   {
+      ParsedSearchKey searchKey = getRestrictionCallSearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, 
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4CallConstructor_pojo5Pojo3Constructor);
+   }
+   
+   public void testSearchRestrictionCall2()
+   {
+      ParsedSearchKey searchKey = getRestrictionCall2SearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testSearchRestrictionCall3()
+   {
+      ParsedSearchKey searchKey = getRestrictionCall3SearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2GetPojo2_pojo5CalledByMethod,
+            pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo5CalledByMethod);
+   }
+   
+   public void testEmptySearchKey1()
+   {
+      ParsedSearchKey searchKey = getEmptySearchKey();
+      SearchKey finalSearchKey = searchKey.finishParsing();
+      finalSearchKey.search(classTree, result);
+      Util.assertCollection(result);
+      assertTrue(finalSearchKey instanceof EmptySearchKey);
+   }
+   
+   public void testEmptySearchKey2()
+   {
+      ParsedSearchKey searchKey = getEmptySearchKey2();
+      SearchKey finalSearchKey = searchKey.finishParsing();
+      finalSearchKey.search(classTree, result);
+      Util.assertCollection(result);
+      assertTrue(finalSearchKey instanceof EmptySearchKey);
+   }
+   
+   public void testEmptySearchKey3()
+   {
+      ParsedSearchKey searchKey = getEmptySearchKey3();
+      SearchKey finalSearchKey = searchKey.finishParsing();
+      finalSearchKey.search(classTree, result);
+      Util.assertCollection(result);
+      assertTrue(finalSearchKey instanceof EmptySearchKey);
+   }
+   
+   public void testEmptySearchKey4()
+   {
+      ParsedSearchKey searchKey = getEmptySearchKey4();
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*.* @*(*)"));
+      SearchKey finalSearchKey = searchKey.finishParsing();
+      finalSearchKey.search(classTree, result);
+      Util.assertCollection(result);
+      assertTrue(finalSearchKey instanceof EmptySearchKey);
+   }
+   
+   public void testFilteredSearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = getFilteredSearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, dummyAnnotationPojoMethodExec, 
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec,
+            dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);
+   }
+   
+   public void testNegativeSearchKey1() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey1();
+      SearchKey finalSearchKey = searchKey.finishParsing();
+      assertTrue(finalSearchKey instanceof DisjunctiveSearchKey);
+      finalSearchKey.search(classTree, result);
+      Util.assertCollection(result, pojo1DefaultConstruction,
+            pojo1DefaultConstruction1, pojo1DefaultConstruction3,
+            pojo1IntConstruction, pojo2DefaultConstruction, pojo2Pojo3Construction,
+            pojo2StringConstruction, pojo3DefaultConstruction,
+            pojo3IntStringConstruction, pojo3IntStringConstruction,
+            pojo4DefaultConstruction, pojo4IntConstruction, pojo5DefaultConstruction,
+            pojo5CollectionConstruction, pojo5Pojo3Construction,
+            annPojoMultiArgConstruction1, annPojoMultiArgConstruction2,
+            annPojoMultiArgConstruction3, annPojoMultiArgConstruction4,
+            annPojoMultiArgConstruction5, annPojoMultiArgConstruction5_2,
+            annPojoMultiArgConstruction6, annPojoMultiArgConstruction6_2,
+            annPojoMultiArgConstruction7,
+            dummyAnnotationPojo2DummyInterface2Construction,
+            anyAnnotationPojoIntConstruction,
+            pojo1DefaultConstructor_pojo1IntConstructor,
+            pojo1DefaultConstructor_pojo1PrivateMethod,
+            pojo1Method1_pojo1IntConstructor,
+            pojo1Method1_pojo1PrivateMethod,
+            pojo2StringConstructor_pojo1IntConstructor,
+            pojo2StringConstructor_pojo2StringConstructor,
+            pojo2StringConstructor_pojo5CalledByConMethod,
+            pojo2GetPojo2_pojo1IntConstructor,
+            pojo2GetPojo2_pojo2StringConstructor,
+            pojo2GetPojo2_pojo2StringConstructor1,
+            pojo2GetPojo2_pojo5CalledByMethod, pojo2GetPojo2_pojo5CalledByMethod1,
+            pojo2GetPojo3_pojo1IntConstructor, pojo2GetPojo3_pojo2StringConstructor,
+            pojo2GetPojo3_pojo5CalledByMethod, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4DefaultConstructor_pojo5CollectionConstructor,
+            pojo4IntConstructor_pojo5DefaultConstructor,
+            pojo4IntConstructor_pojo5CalledByConMethod,
+            pojo4CallConstructor_pojo5Pojo3Constructor,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1,
+            pojo5CollectionConstructor_pojo1IntConstructor,
+            pojo5CollectionConstructor_pojo1IntConstructor1,
+            pojo5CollectionConstructor_pojo2StringConstructor,
+            pojo5CollectionConstructor_pojo2StringConstructor1,
+            pojo5CollectionConstructor_pojo5CalledByCon,
+            pojo5CollectionConstructor_pojo5CalledByCon1,
+            annPojoMultiArgConstructor2_pojo1IntConstructor,
+            annPojoMultiArgConstructor2_pojo1IntConstructor2,
+            annPojoMultiArgConstructor2_pojo2StringConstructor,
+            annPojoMultiArgConstructor2_pojo2StringConstructor2,
+            annPojoMethod4_pojo5CalledByMethod,
+            annPojoMethod4_pojo5CalledByMethod3);
+   }
+   
+   public void testNegativeSearchKey2() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey2();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, anyAnnotationPojoIntConstruction, 
+            dummyAnnotationPojo2DummyInterface2Construction);
+   }
+   
+   public void testNegativeSearchKey3() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey3();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo3StringMethodExec,
+            pojo3StringLongSomeMethodExec, pojo3StringLongSomeMethodExec1);
+   }
+   
+   public void testNegativeSearchKey4() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey4();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo3StringMethod_pojo1IntConstructor,
+            pojo3StringMethod_pojo1IntConstructor1,
+            pojo3StringMethod_pojo2StringConstructor,
+            pojo3StringMethod_pojo2StringConstructor1,
+            pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1);
+   }
+   
+   public void testNegativeSearchKey5() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey5();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo4CallMethod_pojo5DefaultConstructor,
+            pojo4CallMethod_pojo5CalledByMethodMethod,
+            pojo4CallMethod_pojo5CalledByMethodMethod1);
+   }
+   
+   public void testNegativeSearchKey6() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey6();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2Pojo3Read, pojo3DumbFieldRead,
+            pojo3FieldRead);
+   }
+   
+   public void testNegativeSearchKey7() throws Exception
+   {
+      ParsedSearchKey searchKey = getNegativeSearchKey7();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, pojo2Pojo3Read, pojo3DumbFieldRead,
+            pojo3FieldRead);
+   }
+   
+   public void testFilterSubtypeSearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = getFilterSubtypeSearchKey();
+      assertSame(searchKey, searchKey.finishParsing());
+      searchKey.search(classTree, result);
+      Util.assertCollection(result, 
+            dummyAnnotationPojoMethodExec, 
+            dummyAnnotationPojoInterfaceMethodExec,
+            dummyAnnotationPojoInterfaceMethodExec2,
+            dummyAnnotationPojoInterfaceMethod2Exec,
+            dummyAnnotationPojoInterfaceMethod2Exec1,
+            dummyAnnotationPojoInterfaceMethod2Exec2,
+            dummyAnnotationPojo2DummyInterface2ConstructorExec,
+            dummyAnnotationPojo2Method1Exec,
+            dummyAnnotationPojo2Method2Exec,
+            dummyAnnotationPojo2InterfaceMethodExec,
+            dummyAnnotationPojo2InterfaceMethod2Exec);;
+   }
+   
+   public static ParsedSearchKey getAllSearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("*", false);
+      searchKey.setSearcher(AllSearcher.getInstance());
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getAllCallSearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(behaviorSearcher);
+      return searchKey;
+   }
+
+   
+   public static ParsedSearchKey getRestrictionCallSearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(behaviorSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|@*#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getRestrictionCall2SearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(behaviorSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| *od#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getRestrictionCall3SearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("@*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(behaviorSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| *od#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getEmptySearchKey()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("@*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.CONSTRUCTION);
+      searchKey.setSearcher(behaviorSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getEmptySearchKey2()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("@*", false);
+      BehaviorSearcher behaviorSearcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      behaviorSearcher.setSearchType(SearchType.EXECUTION);
+      searchKey.setSearcher(behaviorSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getEmptySearchKey3()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("@*", false);
+      searchKey.setSearcher(AllSearcher.getInstance());
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getEmptySearchKey4()
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("@*", false);
+      FieldSearcher fieldSearcher = new FieldSearcher("*",
+            new ArrayList<ASTAttribute>(), null);
+      fieldSearcher.setSearchType(FieldSearcher.SearchType.ALL);
+      searchKey.setSearcher(fieldSearcher);
+      searchKey.addConjunctiveCalleeRestriction(new OptimizedCalleeSearcher("*|*| @*#*"));
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getFilteredSearchKey() throws Exception
+   {
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.setClassExpression("*", false);
+      TypeFilter filter = new HasBehaviorFilter(TypeFilterTest.getASTBehavior(
+            "* *->interfaceMethod*(..)")); 
+      searchKey.addConjunctiveTypeFilter(filter);
+      searchKey.setSearcher(AllSearcher.getInstance());
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey1()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      negativeSearchKey.setSearcher(AllSearcher.getInstance());
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey2()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      negativeSearchKey.setSearcher(AllSearcher.getInstance());
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression(DummyInterface.class.getName(), true);
+      BehaviorSearcher searcher = new BehaviorSearcher("*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CONSTRUCTION);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey3()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      BehaviorSearcher negativeSearcher = new BehaviorSearcher("void| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      negativeSearcher.setSearchType(SearchType.EXECUTION);
+      negativeSearchKey.setSearcher(negativeSearcher);
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher searcher = new BehaviorSearcher("*| *od#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.EXECUTION);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey4()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      BehaviorSearcher negativeSearcher = new BehaviorSearcher("void| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      negativeSearcher.setSearchType(SearchType.EXECUTION);
+      negativeSearchKey.setSearcher(negativeSearcher);
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher searcher = new BehaviorSearcher("*| *od#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey5()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      BehaviorSearcher negativeSearcher = new BehaviorSearcher("java.lang.String| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      negativeSearcher.setSearchType(SearchType.CALL);
+      negativeSearchKey.setSearcher(negativeSearcher);
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression("*", false);
+      BehaviorSearcher searcher = new BehaviorSearcher("*| *od#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      searcher.setSearchType(SearchType.CALL);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey6()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      BehaviorSearcher negativeSearcher = new BehaviorSearcher("java.lang.String| *#*",
+            new ArrayList<ASTAttribute>(), new ArrayList<ASTException>());
+      negativeSearcher.setSearchType(SearchType.CALL);
+      negativeSearchKey.setSearcher(negativeSearcher);
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression("*", false);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attribute.not = true;
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      attributes.add(attribute);
+      FieldSearcher searcher = new FieldSearcher("*", attributes, null);
+      searcher.setSearchType(FieldSearcher.SearchType.READ);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getNegativeSearchKey7()
+   {
+      ParsedSearchKey negativeSearchKey = new StandardSearchKey();
+      negativeSearchKey.setClassExpression("*", false);
+      FieldSearcher negativeSearcher = new FieldSearcher("* *",
+            new ArrayList<ASTAttribute>(), null);
+      negativeSearcher.setSearchType(FieldSearcher.SearchType.WRITE);
+      negativeSearchKey.setSearcher(negativeSearcher);
+      assertSame(negativeSearchKey, negativeSearchKey.finishParsing());
+      ParsedSearchKey searchKey = new StandardSearchKey();
+      searchKey.addNegativeSearchKey(negativeSearchKey);
+      searchKey.setClassExpression("*", false);
+      ASTAttribute attribute = new ASTAttribute(0);
+      attribute.setValue(Modifier.PUBLIC);
+      attribute.not = true;
+      Collection<ASTAttribute> attributes = new ArrayList<ASTAttribute>();
+      attributes.add(attribute);
+      FieldSearcher searcher = new FieldSearcher("*", attributes, null);
+      searcher.setSearchType(FieldSearcher.SearchType.ALL);
+      searchKey.setSearcher(searcher);
+      return searchKey;
+   }
+   
+   public static ParsedSearchKey getFilterSubtypeSearchKey() throws Exception
+   {
+      ParsedSearchKey  searchKey = new StandardSearchKey();
+      searchKey.setClassExpression(Object.class.getName(), true);
+      TypeFilter filter = new HasBehaviorFilter(TypeFilterTest.getASTBehavior(
+            "* *->interfaceMethod*(..)")); 
+      searchKey.addConjunctiveTypeFilter(filter);
+      searchKey.setSearcher(AllSearcher.getInstance());
+      return searchKey;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SubtypeSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SubtypeSearcherTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/SubtypeSearcherTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,284 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.Advisor;
+import org.jboss.aop.ConstructionInfo;
+import org.jboss.aop.ConstructorInfo;
+import org.jboss.aop.FieldInfo;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.MethodInfo;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+
+/**
+ * Tests {@link SubtypeSearcher}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class SubtypeSearcherTest extends TestCase
+{
+   private Collection<JoinPointInfo> result;
+   
+   public void setUp()
+   {
+      result = new HashSet<JoinPointInfo>();
+   }
+   
+   public void testEmptyNode()
+   {
+      ClassNode classNode = new StandardClassNode(Pojo1.class);
+      Searcher<ClassNode> classNodeSearcher = new SubtypeSearcher(
+            AllSearcher.getInstance(), null);
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   public void testEmptyHierarchy()
+   {
+      ClassNode classNode = new StandardClassNode(Pojo1.class);
+      classNode.addSubtype(new StandardClassNode(Pojo3.class));
+      Searcher<ClassNode> classNodeSearcher = new SubtypeSearcher(
+            AllSearcher.getInstance(), null);
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result);
+   }
+   
+   // in this scenario, a class node is first filled in, then subtypes are
+   // added to it and filled in as well
+   public void testComplexScenario() throws Exception
+   {
+      StandardClassNode classNode = new StandardClassNode(Pojo1.class);
+      Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      Method method = Pojo1.class.getDeclaredMethod("privateMethod");
+      MethodInfo privateMethodInfo = new MethodInfo(advisor, 0l, method, null);
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(
+            privateMethodInfo);
+      method = Pojo1.class.getDeclaredMethod("method1", String.class, String.class);
+      MethodInfo method1Info = new MethodInfo(advisor, 0l, method, null);
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(method1Info);
+      Searcher<ClassNode> classNodeSearcher = new SubtypeSearcher(
+            AllSearcher.getInstance(), null);
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(method1Info);
+      classNode.addSubtype(new StandardClassNode(Pojo3.class));
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      Advisor subAdvisor1 = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      StandardClassNode subNode1 = new StandardClassNode(Pojo3.class);
+      classNode.addSubtype(subNode1);
+      Field field = Pojo3.class.getField("intField");
+      FieldInfo intFieldWrite = new FieldInfo(subAdvisor1, field, 0, false);
+      subNode1.getAdvisedData(subAdvisor1).getField(field).setFieldWrite(intFieldWrite);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite);
+      
+      Constructor constructor = Pojo3.class.getDeclaredConstructor(int.class,
+            long.class);
+      ConstructionInfo pojo3Construction = new ConstructionInfo(subAdvisor1,
+            constructor, 1);
+      subNode1.getAdvisedData(subAdvisor1).getBehavior(constructor).
+         setConstruction(pojo3Construction);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite);
+      
+      ConstructorInfo pojo3ConstructorInfo = new ConstructorInfo(subAdvisor1,
+            constructor, 1);
+      subNode1.getAdvisedData(subAdvisor1).getBehavior(constructor).
+         setExecution(pojo3ConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo);
+      
+      StandardClassNode subNode2 = new StandardClassNode(Pojo4.class);
+      classNode.addSubtype(subNode2);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo);
+      
+      Advisor subAdvisor2 = new AdvisorMock("Pojo5Advisor", Pojo5.class);
+      StandardClassNode subNode3 = new StandardClassNode(Pojo5.class);
+      subNode2.addSubtype(subNode3);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo);
+      
+      constructor = Pojo5.class.getDeclaredConstructor(Collection.class);
+      ConstructorInfo pojo5ColConstructorInfo = new ConstructorInfo(subAdvisor2,
+            constructor, 1);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(constructor).setExecution(
+            pojo5ColConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo, pojo5ColConstructorInfo);
+      
+      constructor = Pojo5.class.getDeclaredConstructor(Pojo3.class);
+      ConstructorInfo pojo5Pojo3ConstructorInfo = new ConstructorInfo(
+            subAdvisor2, constructor, 1);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(constructor).setExecution(
+            pojo5Pojo3ConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo, pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo);
+      
+      method = Pojo5.class.getDeclaredMethod("calledByCon");
+      MethodInfo calledByConInfo = new MethodInfo(subAdvisor2, 0l, method, null);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(method).setExecution(
+            calledByConInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo, pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo,
+            calledByConInfo);
+      
+      ClassNode objectNode = new StandardClassNode(Object.class);
+      objectNode.addSubtype(classNode);
+      result.clear();
+      classNodeSearcher.search(objectNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info, intFieldWrite,
+            pojo3ConstructorInfo, pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo,
+            calledByConInfo);
+   }
+   
+   // in this scenario, a class node is first filled in, then subtypes are
+   // added to it and filled in as well
+   public void testComplexFilterScenario() throws Exception
+   {
+      StandardClassNode classNode = new StandardClassNode(Pojo1.class);
+      Advisor advisor = new AdvisorMock("Pojo1Advisor", Pojo1.class);
+      Method method = Pojo1.class.getDeclaredMethod("privateMethod");
+      MethodInfo privateMethodInfo = new MethodInfo(advisor, 0l, method, null);
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(
+            privateMethodInfo);
+      method = Pojo1.class.getDeclaredMethod("method1", String.class, String.class);
+      MethodInfo method1Info = new MethodInfo(advisor, 0l, method, null);
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(method1Info);
+      Typedef typedef = new TypedefExpression("hasFilter",
+            "has(* *->privateMethod*(..)) OR has(* *->calledBy*(..))" );
+      Searcher<ClassNode> classNodeSearcher = new SubtypeSearcher(
+            AllSearcher.getInstance(), new TypedefFilter(typedef));
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      classNode.getAdvisedData(advisor).getBehavior(method).setExecution(method1Info);
+      classNode.addSubtype(new StandardClassNode(Pojo3.class));
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      Advisor subAdvisor1 = new AdvisorMock("Pojo3Advisor", Pojo3.class);
+      StandardClassNode subNode1 = new StandardClassNode(Pojo3.class);
+      classNode.addSubtype(subNode1);
+      Field field = Pojo3.class.getField("intField");
+      FieldInfo intFieldWrite = new FieldInfo(subAdvisor1, field, 0, false);
+      subNode1.getAdvisedData(subAdvisor1).getField(field).setFieldWrite(intFieldWrite);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      Constructor constructor = Pojo3.class.getDeclaredConstructor(int.class,
+            long.class);
+      ConstructionInfo pojo3Construction = new ConstructionInfo(subAdvisor1,
+            constructor, 1);
+      subNode1.getAdvisedData(subAdvisor1).getBehavior(constructor).
+         setConstruction(pojo3Construction);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      ConstructorInfo pojo3ConstructorInfo = new ConstructorInfo(subAdvisor1,
+            constructor, 1);
+      subNode1.getAdvisedData(subAdvisor1).getBehavior(constructor).
+         setExecution(pojo3ConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      StandardClassNode subNode2 = new StandardClassNode(Pojo4.class);
+      classNode.addSubtype(subNode2);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      Advisor subAdvisor2 = new AdvisorMock("Pojo5Advisor", Pojo5.class);
+      StandardClassNode subNode3 = new StandardClassNode(Pojo5.class);
+      subNode2.addSubtype(subNode3);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info);
+      
+      constructor = Pojo5.class.getDeclaredConstructor(Collection.class);
+      ConstructorInfo pojo5ColConstructorInfo = new ConstructorInfo(subAdvisor2,
+            constructor, 1);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(constructor).setExecution(
+            pojo5ColConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info,
+            pojo5ColConstructorInfo);
+      
+      constructor = Pojo5.class.getDeclaredConstructor(Pojo3.class);
+      ConstructorInfo pojo5Pojo3ConstructorInfo = new ConstructorInfo(
+            subAdvisor2, constructor, 1);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(constructor).setExecution(
+            pojo5Pojo3ConstructorInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info,
+            pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo);
+      
+      method = Pojo5.class.getDeclaredMethod("calledByCon");
+      MethodInfo calledByConInfo = new MethodInfo(subAdvisor2, 0l, method, null);
+      subNode3.getAdvisedData(subAdvisor2).getBehavior(method).setExecution(
+            calledByConInfo);
+      result.clear();
+      classNodeSearcher.search(classNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info,
+            pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo, calledByConInfo);
+      
+      ClassNode objectNode = new StandardClassNode(Object.class);
+      objectNode.addSubtype(classNode);
+      result.clear();
+      classNodeSearcher.search(objectNode, result);
+      Util.assertCollection(result, privateMethodInfo, method1Info,
+            pojo5ColConstructorInfo, pojo5Pojo3ConstructorInfo, calledByConInfo);
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypeFilterTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypeFilterTest.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypeFilterTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -183,7 +183,7 @@
       throw new RuntimeException("ASTField not found");
    }
    
-   private ASTBehavior getASTBehavior(String behaviorExpression) throws ParseException
+   public static ASTBehavior getASTBehavior(String behaviorExpression) throws ParseException
    {
       ASTStart parsed = new TypeExpressionParser(new StringReader("has(" +
             behaviorExpression + ")")).Start();

Added: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypedefParserTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypedefParserTest.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/TypedefParserTest.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -0,0 +1,244 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import junit.framework.TestCase;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.TypedefExpression;
+
+/**
+ * Tests {@link TypedefParser}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class TypedefParserTest extends TestCase
+{
+   public void testTypedefParser1() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(*)");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser2() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop.Pojo)");
+      assertEquals("org.jboss.aop.Pojo", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser3() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "has(* *->*(..))");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser4() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "method(* *->*(..))");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser5() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "constructor(*->new(..))");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser6() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "field(* *->*)");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser7() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "hasfield(* *->*)");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser8() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(Pojo) OR hasfield(* *->*)");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser9() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(Pojo) AND hasfield(* *->*)");
+      assertEquals("Pojo", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser10() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(Pojo) AND hasfield(* *->*)");
+      assertEquals("Pojo", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser11() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(Pojo) AND hasfield(* *->*) AND class(Pojo2)");
+      assertEquals("Pojo2", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser12() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop..) AND hasfield(* *->*) AND class(Pojo2)");
+      assertEquals("Pojo2", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser13() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop..)");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser14() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop..) OR class(*a*)");
+      assertEquals("*", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser15() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop..) AND class(*a*)");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser16() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef", "class(org.jboss.aop..) AND class(a*)");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser17() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef",
+            "class(org.jboss.aop..) AND class(a*) AND class($instanceof{MyInterface})");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser18() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef",
+            "class(org.jboss.aop..) AND class(a*) AND class(MyClass)");
+      assertEquals("MyClass", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser19() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef",
+            "class(org.jboss.aop..) AND (class(a*) AND class(MyClass))");
+      assertEquals("MyClass", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser20() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef",
+            "class(org.jboss.aop..) AND (class(a*) OR class(MyClass))");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testTypedefParser21() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef",
+            "class(org.jboss.aop..) AND (class(a*) OR class(MyClass)) AND class(*a*)");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testCompositeTypedefParser1() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef1",
+            "class(org.jboss.aop..) AND (class(a*) OR class(MyClass)) AND class(*a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef", "class($typedef{typedef1})");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testCompositeTypedefParser2() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef1",
+            "class(org.jboss.aop..) AND (class(a*) OR class(MyClass)) AND class(*a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef2", "class($typedef{typedef1}) OR class(Pojo1)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef",
+            "has(void *->method(..)) AND class($typedef{typedef2})");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+   
+   public void testCompositeTypedefParser3() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef1",
+            "class(org.jboss.aop..) AND (class(a*) OR class(MyClass)) AND class(*a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef2", "class($typedef{typedef1}) AND class(Pojo1)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef",
+            "has(void *->method(..)) AND class($typedef{typedef2})");
+      assertEquals("Pojo1", TypedefParser.parse(typedef));
+   }
+   
+   public void testCompositeTypedefParser4() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef1", "class(org.jboss.aop..)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef2", "class(a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef3", "class(MyClass)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef4", "class(*a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef5",
+            "class($typedef{typedef1}) AND (class($typedef{typedef2}) OR class($typedef{typedef3})) AND class($typedef{typedef4})");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef6", "class(Pojo1)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef7", "has(void *->method(..))");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef",
+             "class($typedef{typedef5}) AND class($typedef{typedef6}) AND class($typedef{typedef7})");
+      assertEquals("Pojo1", TypedefParser.parse(typedef));
+   }
+   
+   public void testCompositeTypedefParser5() throws Exception
+   {
+      Typedef typedef = new TypedefExpression("typedef1", "class(org.jboss.aop..)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef2", "class(a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef3", "class(MyClass)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef4", "class(*a*)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef5",
+            "class($typedef{typedef1}) AND (class($typedef{typedef2}) OR class($typedef{typedef3})) AND class($typedef{typedef4})");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef6", "class(Pojo1)");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef7", "has(void *->method(..))");
+      AspectManager.instance().addTypedef(typedef);
+      typedef = new TypedefExpression("typedef",
+             "class($typedef{typedef5}) OR class($typedef{typedef6}) AND class($typedef{typedef7})");
+      assertEquals("org.jboss.aop..", TypedefParser.parse(typedef));
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Util.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Util.java	2008-07-16 02:11:53 UTC (rev 75857)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Util.java	2008-07-16 02:16:41 UTC (rev 75858)
@@ -21,8 +21,8 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 
 import junit.framework.TestCase;
 
@@ -43,21 +43,35 @@
     */
    public static <T> void assertCollection(Collection<T> collection, T... contents)
    {
-      TestCase.assertEquals(contents.length, collection.size());
+      for (int i = 0; i < contents.length; i++)
+      {
+         TestCase.assertNotNull("Null: " + i + " out of " + contents.length, contents[i]);
+      }
+      if (contents.length > collection.size())
+      {
+         for (int i = 0; i < contents.length; i++)
+         {
+            TestCase.assertTrue("Collection does not contain " + contents[i],
+                  collection.contains(contents[i]));
+         }
+      }
+      if (collection.size() > contents.length)
+      {
+         int colSize = collection.size();
+         collection.removeAll(Arrays.asList(contents));
+         TestCase.assertEquals("Found these extra elements: " + collection,
+            contents.length, colSize);
+      }
       if (contents.length == 1)
       {
-         TestCase.assertTrue(collection.contains(contents[0]));
+         TestCase.assertTrue("Collection contains " + collection.iterator().next() +
+               ", and not " + contents[0], collection.contains(contents[0]));
       }
       else if (contents.length > 0)
       {
-         Collection<T> expectedNodes = new HashSet<T>();
-         for (T node: contents)
-         {
-            expectedNodes.add(node);
-         }
          TestCase.assertTrue("Collection " + collection +
                "does not contain all expected nodes",
-               collection.containsAll(expectedNodes));
+               collection.containsAll(java.util.Arrays.asList(contents)));
       }
    }
 }
\ No newline at end of file




More information about the jboss-cvs-commits mailing list