[jboss-cvs] JBossAS SVN: r63855 - in projects/aop/trunk/aop/src: main/org/jboss/aop/advice/annotation/assignability and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jul 6 00:45:28 EDT 2007


Author: flavia.rainone at jboss.com
Date: 2007-07-06 00:45:28 -0400 (Fri, 06 Jul 2007)
New Revision: 63855

Added:
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ArgumentContextualizer.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ChoiceBound.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java
   projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AllTests.java
Removed:
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java
   projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java
Modified:
   projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AssignabilityAlgorithmTest.java
Log:
[JBAOP-420] Big refactoring

Deleted: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java	2007-07-06 02:36:30 UTC (rev 63854)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -1,297 +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.advice.annotation;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- * 
- */
-public class Algorithm
-{
-   private static final Algorithm INSTANCE = new Algorithm();
-   public static Algorithm getInstance()
-   {
-      return INSTANCE;
-   }
-
-   public Map<String, VariableNode> getInitialHierarchy()
-   {
-      return new HashMap<String, VariableNode>();
-   }
-   
-   public boolean isAssignable(Type type, Type fromType,
-         Map<String, VariableNode> variableHierarchy)
-   {
-      if (type instanceof Class)
-      {
-         return isAssignable((Class<?>) type, fromType, variableHierarchy);
-      }
-      if (type instanceof ParameterizedType)
-      {
-         return isAssignable((ParameterizedType) type, fromType,
-               variableHierarchy, false);
-      }
-      if (type instanceof TypeVariable)
-      {
-         VariableNode node = null;
-         TypeVariable variable = (TypeVariable) type;
-         if (variableHierarchy.containsKey(variable.getName()))
-         {
-            node = variableHierarchy.get(variable.getName());
-         }
-         else
-         {
-            node = new VariableNode(variable, variableHierarchy);
-         }
-         return node.addLowerBound(fromType);
-      }
-      if (type instanceof WildcardType)
-      {
-         throw new RuntimeException("This comparison should never happen");
-      } else
-      {
-         return isAssignable((GenericArrayType) type, fromType,
-               variableHierarchy);
-      }
-   }
-
-   // is classType super of fromType?
-   private boolean isAssignable(Class<?> classType, Type fromType,
-         Map<String, VariableNode> variableHierarchy)
-   {
-      if (fromType instanceof Class)
-      {
-         return classType.isAssignableFrom((Class<?>) fromType);
-      }
-      else if (fromType instanceof ParameterizedType)
-      {
-         return classType.isAssignableFrom(
-               (Class<?>) ((ParameterizedType) fromType).getRawType());
-      }
-      else if (fromType instanceof TypeVariable)
-      {
-         Type[] bounds = getConcreteBounds(fromType);
-         boolean inside = false;
-         for (int i = 0; i < bounds.length && !inside; i++)
-         {
-            if (bounds[i] instanceof Class)
-            {
-               if (classType.isAssignableFrom((Class<?>) bounds[i]))
-               {
-                  inside = true;
-               }
-            }
-            else
-            {
-               // bound must be a parameterized type
-               if (classType.isAssignableFrom(
-                     (Class<?>) ((ParameterizedType) bounds[i]).getRawType()))
-               {
-                  inside = true;
-               }
-            }
-         }
-         return inside;
-      }
-      else if (fromType instanceof WildcardType)
-      {
-         WildcardType fromWildcard = (WildcardType) fromType;
-         boolean boundOk = false;
-         for (Type upperBound: fromWildcard.getUpperBounds())
-         {
-            if (isAssignable(classType, upperBound, variableHierarchy))
-            {
-               boundOk = true;
-               break;
-            }
-         }
-         if (!boundOk)
-         {
-            return false;
-         }
-         for (Type lowerBound: fromWildcard.getLowerBounds())
-         {
-            if (isAssignable(classType, lowerBound, variableHierarchy))
-            {
-               return true;
-            }
-         }
-         return fromWildcard.getLowerBounds().length == 0;
-      }
-      // type instanceof GenericArrayType (ommitting check for performance
-      // reasons)
-      if (classType == Object.class)
-      {
-         return true;
-      }
-      if (classType.isArray())
-      {
-         return isAssignable(classType.getComponentType(),
-               ((GenericArrayType) fromType).getGenericComponentType(),
-               variableHierarchy);
-      }
-      return false;
-   }
-
-   /**
-    * @param type
-    * @return
-    */
-   private Type[] getConcreteBounds(Type type)
-   {
-      TypeVariable current = (TypeVariable) type;
-      Type[] bounds = current.getBounds();
-      while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
-      {
-         current = (TypeVariable) bounds[0];
-         bounds = current.getBounds();
-      }
-      return bounds;
-   }
-
-   private boolean isAssignable(ParameterizedType paramType, Type fromType, 
-         Map<String, VariableNode> variableHierarchy, boolean boundLevel)
-   {
-      if (fromType instanceof TypeVariable)
-      {
-         Type[] concreteBounds = getConcreteBounds((TypeVariable) fromType);
-         for (int i = 0; i < concreteBounds.length; i++)
-         {
-            if (isAssignable(paramType, concreteBounds[i], variableHierarchy, true))
-            {
-               return true;
-            }
-         }
-         return false;
-      }
-      return ParamTypeAssignabilityAlgorithm.isAssignable(
-            paramType, fromType, CHECKER, variableHierarchy, boundLevel);
-   }
-
-   private boolean isAssignable(GenericArrayType arrayType, Type fromType,
-         Map<String, VariableNode> variableHierarchy)
-   {
-      if (fromType instanceof Class)
-      {
-         Class<?> fromClass = (Class<?>) fromType;
-         if (!fromClass.isArray())
-         {
-            return false;
-         }
-         return isAssignable(arrayType.getGenericComponentType(),
-               fromClass.getComponentType(), variableHierarchy);
-      }
-      if (fromType instanceof GenericArrayType)
-      {
-         GenericArrayType fromArrayType = (GenericArrayType) fromType;
-         return isAssignable(arrayType.getGenericComponentType(),
-               fromArrayType.getGenericComponentType(), variableHierarchy);
-      }
-      return false;
-   }
-
-   //////////////////////////////////////////////////////////
-   private static final ParamTypeAssignabilityAlgorithm.EqualityChecker<Map<String, VariableNode>> CHECKER
-      = new ParamTypeAssignabilityAlgorithm.EqualityChecker<Map<String,VariableNode>>()
-   {
-      public boolean isSame(Type type, Type fromType, Map<String, VariableNode> variableHierarchy, boolean boundLevel)
-      {
-         if (type instanceof TypeVariable)
-         {
-            TypeVariable variable = (TypeVariable) type;
-            VariableNode node = variableHierarchy.containsKey(variable.getName())?
-                  variableHierarchy.get(variable.getName()):
-                     new VariableNode(variable, variableHierarchy);
-             if (boundLevel && fromType instanceof WildcardType)
-             {
-                return false;
-             }
-             return node.assignValue(fromType);
-         }
-         if (type instanceof Class)
-         {
-            return type.equals(fromType);
-         }
-         if (type instanceof ParameterizedType)
-         {
-            if (!(fromType instanceof ParameterizedType))
-            {
-               return false;
-            }
-            ParameterizedType fromParamType = (ParameterizedType) fromType;
-            ParameterizedType paramType = (ParameterizedType) type;
-            if (!isSame(paramType.getRawType(), fromParamType.getRawType(),
-                  variableHierarchy, boundLevel))
-            {
-               return false;
-            }
-            return isSame(paramType.getActualTypeArguments(),
-                  fromParamType.getActualTypeArguments(), variableHierarchy, boundLevel);
-         }
-         if (type instanceof WildcardType)
-         {
-            Type[] upperBounds = ((WildcardType) type).getUpperBounds();
-            Algorithm algorithm = Algorithm.getInstance();
-            if (fromType instanceof WildcardType)
-            {
-               Type[] fromUpperBounds = ((WildcardType) fromType).getUpperBounds();
-               outer: for (int i = 0; i < upperBounds.length; i++)
-               {
-                  for (int j = 0; j < fromUpperBounds.length; j++)
-                  {
-                     if (algorithm.isAssignable(upperBounds[i],
-                           fromUpperBounds[i], variableHierarchy))
-                     {
-                        continue outer;
-                     }
-                  }
-                  return false;
-               }
-               // TODO lower bounds: inverted algorithm
-               return true;
-            }
-            else
-            {
-               for (int i = 0; i < upperBounds.length; i++)
-               {
-                  if (!algorithm.isAssignable(upperBounds[i], fromType,
-                        variableHierarchy))
-                  {
-                     return false;
-                  }
-               }
-               // TODO lower bounds: inverted algorithm
-               return true;
-            }
-         }
-         return true;
-      }
-   };
-}
\ No newline at end of file

Deleted: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java	2007-07-06 02:36:30 UTC (rev 63854)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -1,490 +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.advice.annotation;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-/**
- * Argument contextualizer. Performs contextualization of arguments through hierarchy
- * 
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-class ArgumentContextualizer
-{
-   public static final Type[] getContextualizedArguments(ParameterizedType paramType,
-         Class rawType, Class desiredType)
-   {
-      ArgumentContextualizer contextualizedArguments = getContextualizedArgumentsInternal(
-            desiredType, rawType);
-      if (contextualizedArguments == null)
-      {
-         return null;
-      }
-      if (paramType != null)
-      {
-         contextualizedArguments.contextualizeVariables(null, paramType);
-      }
-      return contextualizedArguments.getArguments();
-   }
-
-   
-   private static final ArgumentContextualizer getContextualizedArgumentsInternal(
-         Class<?> desiredType, Class<?> classType)
-   {
-      Type superType = null;
-      if (desiredType.isInterface())
-      {
-         for (Type superInterface : classType.getGenericInterfaces())
-         {
-            if ((superInterface instanceof Class && desiredType
-                  .isAssignableFrom((Class<?>) superInterface))
-                  || (superInterface instanceof ParameterizedType &&
-                        desiredType.isAssignableFrom((Class<?>)
-                              ((ParameterizedType) superInterface).getRawType())))
-            {
-               superType = superInterface;
-               break;
-            }
-         }
-      }
-      if (superType == null)
-      {
-         superType = classType.getGenericSuperclass();
-      }
-      ArgumentContextualizer result = null;
-      if (superType instanceof Class)
-      {
-         if (superType == desiredType)
-         {
-            return null;
-         }
-         result = getContextualizedArgumentsInternal(desiredType,
-               (Class<?>) superType);
-      }
-      else
-      {
-         ParameterizedType superParamType = (ParameterizedType) superType;
-         Class<?> superClassType = (Class<?>) superParamType.getRawType();
-         if (superClassType == desiredType)
-         {
-            return new ArgumentContextualizer(superParamType
-                  .getActualTypeArguments(), classType);
-         }
-         else
-         {
-            result = getContextualizedArgumentsInternal(desiredType,
-                  superClassType);
-         }
-      }
-      if (result == null
-            || !result.contextualizeVariables(classType, superType))
-      {
-         return null;
-      }
-      return result;
-   }
-   
-   
-   private Type[] arguments;
-   private LinkedList<VariableReplacer> variableReplacements;
-
-   // declaring class extends queried class (DeclaringClass<A, B, C> extends Queried<X, Y, Z, ..., W>,
-   // where X, Y, Z...W, are a list of types for which we need to map (contextualize)
-   // variables
-   // A, B, C... D are variables of DeclaringClass, that may be used in the contextualization proccess
-   /**
-    * Constructor.
-    * 
-    * @param arguments      the set of arguments in their original context (the
-    *                       extends or implements declaration)
-    * @param declaringClass the class that declared those arguments. This class
-    *                       must be the same class that extends/implements a
-    *                       queried parameterized type.
-    */
-   private ArgumentContextualizer(Type[] arguments, Class<?> declaringClass)
-   {
-      this.arguments = arguments;
-      for (int i = 0; i < arguments.length; i++)
-      {
-         Type newArgument = processArgument(arguments, i, declaringClass,
-               replacementCreator, this);
-         if (newArgument != null)
-         {
-            this.arguments[i] = newArgument;
-         }
-      }
-   }
-
-   // newDeclaringClass extends/implements oldDeclaringType
-   // returns false = warning (work with raw type hence)
-   /**
-    * Performs a contextualization step.
-    * 
-    * @param subClass  a class that declares to extend/implement <code>superType
-    *                  </code> 
-    * @param superType the super type of <code>subClass</code>
-    * 
-    * @return <code>true</code> if the contextualization process was successfully
-    *         performed; </code>false</code> otherwise.
-    */
-   private boolean contextualizeVariables(Class subClass, Type superType)
-   {
-      if (!initialized || variableReplacements.isEmpty())
-      {
-         initialized = false;
-         return true;
-      }
-      if (superType instanceof Class)
-      {
-         return false; // warning: variables lost in hierarchy
-      }
-      ParameterizedType superParamType = (ParameterizedType) superType;
-      for (iterator = variableReplacements.listIterator(); iterator.hasNext(); )
-      {
-         if(iterator.next().replace(superParamType, subClass))
-         {
-            iterator.remove();
-         }
-      }
-      iterator = null;
-      return true; 
-   }
-   
-   /**
-    * Process an argument, definining whether it needs to be replaced during
-    * contextualization process or not.
-    * 
-    * @param <O>
-    * 
-    * @param argumentContainer the array that contains the argument to be
-    *                          processed 
-    * @param argumentIndex     the index of the argument in <code>
-    *                          argumentContainer</code>
-    * @param declaringClass    the class that declares the argument
-    * @param recorder          object responsible for recording future
-    *                          replacements to be performed during
-    *                          contextualization
-    * @param outer             
-    * @return the argument processed. This return value may be null if no
-    *         processement of <code>argumentContainer[argumentIndex]</code> is
-    *         rerquired, or an equivalent type otherwise.
-    */
-   private static <O> Type processArgument(Type[] argumentContainer,
-         int argumentIndex, Class<?> declaringClass,
-         ReplacementScheduler<O> recorder, O outer)
-   {
-      Type argument = argumentContainer[argumentIndex];
-      if (argument instanceof Class)
-      {
-         return null;
-      }
-      if (argument instanceof ParameterizedType)
-      {
-         ParameterizedType paramType = (ParameterizedType) argument;
-         ParameterizedType_ newParamType = null;
-         Type[] arguments = paramType.getActualTypeArguments();
-         for (int i = 0; i < arguments.length; i++)
-         {
-            Type newType = processArgument(arguments, i, declaringClass, recorder,
-                  outer);
-            if (newType != null)
-            {
-               if (newParamType == null)
-               {
-                  newParamType = new ParameterizedType_(paramType);
-               }
-               newParamType.getActualTypeArguments()[i] = newType;
-            }
-         }
-         return newParamType;
-      }
-      //else if (bounds[i] instanceof TypeVariable)
-      if (declaringClass == null)
-      {
-         return null;
-      }
-      String paramName = ((TypeVariable) argument).getName();
-      int index = 0;
-      TypeVariable[] typeVariables = declaringClass.getTypeParameters();
-      for (index = 0; index < typeVariables.length; index ++)
-      {
-         if (typeVariables[index].getName().equals(paramName)){
-            break;
-         }
-      }
-      recorder.scheduleReplacement(argumentContainer, argumentIndex, index, outer);
-      return argument; 
-   }
-
-   boolean initialized = false;
-
-   private void initialize()
-   {
-      if (!initialized)
-      {
-         Type[] oldResult = this.arguments;
-         this.arguments = new Type[oldResult.length];
-         System.arraycopy(oldResult, 0, this.arguments, 0, this.arguments.length);
-         this.variableReplacements = new LinkedList<VariableReplacer>();
-         initialized = true;
-      }
-   }
-   private ListIterator<VariableReplacer> iterator;
-
-   /**
-    * Returns contextualized arguments.
-    * 
-    * @return contextualized arguments
-    */
-   public Type[] getArguments()
-   {
-      return this.arguments;
-   }
-
-   /**
-    * Creates a variable replacement. This replacement should take place during the
-    * contextualization steps, where the variable will be replaced by its value.
-    * Notice this value may or may not be another variable.
-
-    * @param argumentContainer array on which the replacement will be executed 
-    * @param argumentIndex     the index that indicates a position of the variable
-    *                          to be replaced in <code>argumentContainer</code>
-    *                          array
-    * @param variableIndex     index of the variable value in the next argument
-    *                          context array. This index shall be used on the
-    *                          replacement, during contextualization process.
-    */
-   private void createVariableReplacement(Type[] argumentContainer, int argumentIndex,
-         int variableIndex)
-   {
-      if (iterator != null)
-      {
-         iterator.add(new VariableReplacer(argumentContainer, argumentIndex,
-               variableIndex));
-      }
-      else
-      {
-         this.variableReplacements.add(new VariableReplacer(
-               argumentContainer, argumentIndex, variableIndex));
-      }
-   }
-   
-   /**
-    * Replaces a variable by another type according to an argument context.
-    *  
-    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
-    */
-   class VariableReplacer
-   {
-      private Type[] arguments;
-      private int argumentIndex;
-      private int valueIndex;
-      private boolean pendingExecution;
-
-      /**
-       * Constructor.
-       * 
-       * @param arguments     array on which the replacement will be executed 
-       * @param argumentIndex the index that indicates a position of the variable
-       *                      to be replaced in <code>argumentContainer</code> array
-       * @param valueIndex    index of the variable value in the next argument
-       *                      context array. This index shall be used on the
-       *                      replacement, during contextualization process.
-       */
-      public VariableReplacer(Type[] arguments, int argumentIndex, int valueIndex)
-      {
-         this.valueIndex = valueIndex;
-         this.arguments = arguments;
-         this.argumentIndex = argumentIndex;
-         this.pendingExecution = true;
-      }
-
-      // return true if replacement has been done for good
-      /**
-       * Performs replacemen of a variable by a new type.
-       * 
-       * @param paramType      parameterized type that contains the context to be
-       *                       used during replacement proccess.
-       * @param declaringClass the class that declares the the variables used in the
-       *                       arguments of <code>paramType</code>. This class must
-       *                       extend/implement the generic type
-       *                       <code>paramType</code>.
-       */
-      public boolean replace(ParameterizedType paramType, Class<?> declaringClass)
-      {
-         arguments[argumentIndex] = paramType.getActualTypeArguments()[valueIndex];
-         this.pendingExecution = false;
-         Type newType = ArgumentContextualizer.processArgument(arguments, argumentIndex,
-               declaringClass, updater, this);
-         if (newType != null)
-         {
-            arguments[argumentIndex] = newType;
-            return false;
-         }
-         return true;
-      }
-
-      /**
-       * Returns the contextualizer that scheduled this replacement.
-       * 
-       * @return the contextualizer.
-       */
-      ArgumentContextualizer getContextualizer()
-      {
-         return ArgumentContextualizer.this;
-      }
-   }
-
-   /**
-    * Parameterized type implementation. Allows replacement of arguments without
-    * affecting reflection information.
-    * 
-    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
-    */
-   private static final class ParameterizedType_ implements ParameterizedType
-   {
-      private Type[] arguments;
-      private Type ownerType;
-      private Type rawType;
-
-      ParameterizedType_(ParameterizedType type)
-      {
-         Type[] actualArguments = type.getActualTypeArguments();
-         this.arguments = new Type[actualArguments.length];
-         System.arraycopy(actualArguments, 0, arguments, 0, actualArguments.length);
-         this.ownerType = type.getOwnerType();
-         this.rawType = type.getRawType();
-      }
-
-
-      public Type[] getActualTypeArguments()
-      {
-         return this.arguments;
-      }
-
-      public Type getOwnerType()
-      {
-         return this.ownerType;
-      }
-
-      public Type getRawType()
-      {
-         return this.rawType;
-      }
-
-      public boolean equals(Object obj)
-      {
-         if (!(obj instanceof ParameterizedType))
-         {
-            return false;
-         }
-         ParameterizedType other = (ParameterizedType) obj;
-         if (!this.ownerType.equals(other.getOwnerType()) ||
-               !this.rawType.equals(other.getRawType()))
-         {
-            return false;
-         }
-         Type[] otherArguments = other.getActualTypeArguments();
-         for (int i = 0; i < arguments.length; i++)
-         {
-            if (!arguments[i].equals(otherArguments[i]))
-            {
-               return false;
-            }
-         }
-         return true;
-      }
-   }
-
-   /**
-    * Schedules replacements to be performed during contextualization.
-    * 
-    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
-    *
-    * @param <C> the scheduler client 
-    */
-   interface ReplacementScheduler<C>
-   {
-      /**
-       * Schedules a variable replacement to be performed on next contextualization
-       * step.
-       * 
-       * @param argumentContainer array on which the replacement will be executed 
-       * @param argumentIndex     the index that indicates a position of the variable
-       *                          to be replaced in <code>argumentContainer</code>
-       *                          array
-       * @param variableIndex     index of the variable value in the next argument
-       *                          context array. This index shall be used on the
-       *                          replacement, during contextualization process.
-       * @param client            the client of recorder
-       */
-      public void scheduleReplacement(Type[] argumentContainer, int argumentIndex,
-            int variableIndex, C client);
-   }
-   
-   /**
-    * Schedules variable replacement when required by contextualizer.
-    * The effect of this scheduling process is the creation of variable replacement.
-    */
-   private static ReplacementScheduler<ArgumentContextualizer> replacementCreator =
-      new ReplacementScheduler<ArgumentContextualizer>()
-   {
-      public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
-            int variableIndex, ArgumentContextualizer outer)
-      {
-         outer.initialize();
-         outer.createVariableReplacement(outer.arguments, targetIndex, variableIndex);
-      }
-   };
-   
-   /**
-    * Schedules variable replacement when required by a <code>VariableReplacement
-    * </code> object.
-    * Generally, the effect of this schedule process will be an update in
-    * the client object, unless this one already has a pending replacement scheduled.
-    */
-   private static ReplacementScheduler<VariableReplacer> updater =
-      new ReplacementScheduler<VariableReplacer>()
-   {
-      public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
-            int variableIndex, VariableReplacer replacer)
-      {
-         if (replacer.pendingExecution) // replacer is already busy
-         {
-            replacer.getContextualizer().createVariableReplacement(replacementTarget,
-                  targetIndex, variableIndex);
-         }
-         else
-         {
-            replacer.valueIndex = variableIndex;
-            replacer.arguments = replacementTarget;
-            replacer.argumentIndex = targetIndex;
-            replacer.pendingExecution = true;
-         }
-      }
-   };
-}
\ No newline at end of file

Deleted: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java	2007-07-06 02:36:30 UTC (rev 63854)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -1,151 +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.advice.annotation;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
-/**
- * 
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-class ParamTypeAssignabilityAlgorithm
-{
-   /**
-    * Class responsible for telling whether two groups of arguments, used on
-    * two different instances of ParameterizedType, can be considered the same
-    * group of arguments.
-    * 
-    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
-    *
-    * @param <T> this is a token that can be used to store information useful for
-    *            the implementor.
-    */
-   static abstract class EqualityChecker<T>
-   {
-      /**
-       * Indicates whether both argument list can be considered the same.
-       * This method is a facility that will invoke {@link #isSame(Type, Type, Object)}
-       * for each argument of the lists. Both lists have the same length.
-       * 
-       * @param arguments     list of arguments.
-       * @param fromArguments list of arguments that will be assigned to <code>
-       *                      arguments</code> only if this method returns <code>true
-       *                      </code>
-       * @param token         a token that may be needed by implementor as auxiliar
-       * @return              <code>true</code> only if values of <code>
-       *                      fromArguments</code> list can be assigned to a list of
-       *                      <code>arguments</code> type.
-       */
-      protected boolean isSame(Type[] arguments, Type[] fromArguments, T token, boolean assignAllowed)
-      {
-         for (int i = 0; i < arguments.length; i++)
-         {
-            if (!isSame(arguments[i], fromArguments[i], token, assignAllowed))
-            {
-               return false;
-            }
-         }
-         return true;
-      }
-
-      /**
-       * Indicates whether both arguments can be considered the same.
-       * This method execution might require some variable inference process,
-       * in which case only a variable type referenced by <code>argument</code> can
-       * have its value infered according to the process.
-       * @param token         a token that may be needed by implementor as auxiliar
-       * @param arguments     an argument type
-       * @param fromArguments argument type that will have its value assigned to
-       *                      <code>argument</code> only if this method returns
-       *                      <code>true</code>
-       * 
-       * @return              <code>true</code> only if a parameterized type with
-       *                      <code>argument</code> as one of its parameter values
-       *                      can be assigned from the same parameterized type with
-       *                      <code>fromArgument</code> as the equivalent parameter
-       *                      value
-       */
-      abstract boolean isSame(Type argument, Type fromArgument, T token, boolean assignAllowed);
-   }
-
-   /**
-    * 
-    * @param <T>
-    * @param paramType
-    * @param fromType
-    * @param checker
-    * @param checkerToken
-    * @return
-    */
-   public static<T> boolean isAssignable(ParameterizedType paramType, Type fromType,
-         EqualityChecker<T> checker, T checkerToken, boolean assignAllowed)
-   {
-      Class<?> fromRaw = null;
-      ParameterizedType fromParamType = null;
-      Class<?> desiredType = (Class<?>) paramType.getRawType();
-      if (fromType instanceof Class)
-      {
-         fromRaw = (Class<?>) fromType;
-         if (!desiredType.isAssignableFrom(fromRaw))
-         {
-            return false;
-         }
-         if (fromRaw.getTypeParameters().length > 0)
-         {
-            // notice that, if fromRaw equals desiredType, we also have the
-            // result true with a warning (i.e., this if statemente is not only for
-            // fromRaw subclass of desiredType, but also for fromRaw same as
-            // desiredType
-            return true;// TODO With warning
-         }
-      }
-      else if (fromType instanceof ParameterizedType)
-      {
-         fromParamType = (ParameterizedType) fromType;
-         fromRaw = (Class<?>) fromParamType.getRawType();
-         if (fromRaw == desiredType)
-         {
-            // compare arguments with arguments
-            return checker.isSame(paramType.getActualTypeArguments(),
-                  fromParamType.getActualTypeArguments(), checkerToken, assignAllowed);
-         }
-         else if (!desiredType.isAssignableFrom(fromRaw))
-         {
-            return false;
-         }
-      }
-      else
-      {
-         return false;
-      }
-      // try to get, if null, warning, parameters lost in hierarchy
-      Type[] arguments = ArgumentContextualizer.getContextualizedArguments(
-            fromParamType, fromRaw, desiredType);
-      if (arguments == null)
-      {
-         return true; // TODO with Warning
-      }
-      return checker.isSame(paramType.getActualTypeArguments(), arguments, checkerToken, assignAllowed);
-   }
-}
\ No newline at end of file

Deleted: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java	2007-07-06 02:36:30 UTC (rev 63854)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -1,460 +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.advice.annotation;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-/**
- * 
- * 
- * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
- */
-public class VariableNode
-{
-   private static int boundComparation = 0;
-   private Map<String, VariableNode> map;
-   private VariableNode previous;
-   private VariableNode next;
-   private Collection<Type> lowerBounds;
-   private TypeVariable variable;
-   private Type assignedValue;
-   
-   public VariableNode(TypeVariable content, Map<String, VariableNode> map)
-   {
-      this.map = map;
-      this.variable = content;
-      lowerBounds = new HashSet<Type>();
-      Type[] bounds = content.getBounds();
-      if (bounds.length == 1 && bounds[0] instanceof TypeVariable)
-      {
-         TypeVariable typeVariable = (TypeVariable) bounds[0];
-         if (map.containsKey(typeVariable.getName()))
-         {
-            next = map.get(typeVariable.getName());
-         }
-         else
-         {
-            next = new VariableNode(typeVariable, map);
-         }
-         next.previous = this;
-      }
-      map.put(content.getName(), this);
-   }
-   
-   public final boolean assignValue(Type value)
-   {
-      if (boundComparation > 0 && !(value instanceof Class)
-            && !(value instanceof ParameterizedType))
-      {
-         return false;
-      }
-      if (this.assignedValue != null)
-      {
-         // TODO HERE1 HERE HERE HERE HERE
-         return isSame(value, this.assignedValue, true);
-      }
-      
-      // TODO fix this
-      /*if (value instanceof WildcardType)
-      {
-         return false;
-      }*/
-      
-      if (!isInsideBounds(value, true) ||
-            (this.previous != null && !this.previous.areBoundsInside(value)))
-      {
-         return false;
-      }
-      this.assignedValue = value;
-      return true;
-   }
-   
-   public final boolean addLowerBound(Type lowerBound)
-   {
-      if (!isInsideBounds(lowerBound, false) ||
-            (this.previous != null && !this.previous.areBoundsInside(lowerBound)))
-      {
-         return false;
-      }
-      // TODO check this
-      if (lowerBound instanceof TypeVariable)
-      {
-         Type[] bounds = ((TypeVariable) lowerBound).getBounds();
-         this.lowerBounds.add(new ChoiceBound((TypeVariable) lowerBound, bounds));
-      }
-      else
-      {
-         this.lowerBounds.add(lowerBound);
-      }
-      return true;
-   }
-   
-   private boolean areBoundsInside(Type bound)
-   {
-      if (this.assignedValue != null && !isAssignable(bound, assignedValue))
-      {
-         return false;
-      }
-      for (Type lowerBound: this.lowerBounds)
-      {
-         if (!isAssignable(bound, lowerBound))
-         {
-            return false;
-         }
-      }
-      if (previous != null)
-      {
-         return previous.areBoundsInside(bound);
-      }
-      return true;
-   }
-   
-   private boolean isInsideBounds(Type lowerBound, boolean checkLowerBounds)
-   {
-      if (this.assignedValue != null && !isAssignable(lowerBound, assignedValue))
-      {
-         return false;
-      }
-      if (checkLowerBounds)
-      {
-         for (Type bound: this.lowerBounds)
-         {
-            if (!isAssignable(bound, lowerBound))
-            {
-               return false;
-            }
-         }
-      }
-      if (next == null)
-      {
-         Type[] bounds = variable.getBounds();
-         boundComparation ++;
-         for (int i = 0; i < bounds.length; i++)
-         {
-            // TODO HERE HERE HERE HERE
-            if (!Algorithm.getInstance().isAssignable(bounds[i], lowerBound, map))
-            {
-               boundComparation --;
-               return false;
-            }
-         }
-         boundComparation --;
-         return true;
-      }
-      return next.isInsideBounds(lowerBound, true);
-   }
-   
-   private boolean isAssignable(TypeVariable type, TypeVariable fromType)
-   {
-      Type[] fromBounds = fromType.getBounds();
-      if (type == fromType)
-      {
-         return true;
-      }
-      while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
-      {
-         if (fromBounds[0] == type)
-         {
-            return true;
-         }
-         fromType = (TypeVariable) fromBounds[0];
-         fromBounds = fromType.getBounds();
-      }
-      TypeVariable variable = (TypeVariable) type;
-      Type[] bounds = variable.getBounds();
-      while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
-      {
-         if (bounds[0] == fromType)
-         {
-            return false;
-         }
-         variable = (TypeVariable) bounds[0];
-         bounds = variable.getBounds();
-      }
-      // TODO check if this should really be removed
-      /*outer: for (int i = 0; i < bounds.length; i++)
-      {
-         for (int j = 0; j < fromBounds.length; j++)
-         {
-            if (isAssignable(bounds[i], fromBounds[j]))
-            {
-               continue outer;
-            }
-         }
-         return false;
-      }
-      return true;*/
-      return false;
-   }
-   
-   // both type and bound belong to the same context
-   private boolean isAssignable(Type type, Type fromType)
-   {
-      if (fromType instanceof TypeVariable)
-      {
-         TypeVariable fromVariable = (TypeVariable) fromType;
-         if (type instanceof TypeVariable)
-         {
-            return isAssignable((TypeVariable) type, fromVariable);
-         }
-         Type[] fromBounds = fromVariable.getBounds();
-         TypeVariable temp = fromVariable;
-         while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
-         {
-            temp = (TypeVariable) fromBounds[0];
-            fromBounds = temp.getBounds();            
-         }
-         for (Type fromBound: fromBounds)
-         {
-            if (isAssignable(type, fromBound))
-            {
-               return true;
-            }
-         }
-         return false;
-      }
-      if (fromType instanceof ChoiceBound)
-      {
-         ChoiceBound fromChoiceBound = (ChoiceBound) fromType;
-         if (type instanceof TypeVariable &&
-               !isAssignable((TypeVariable) type, fromChoiceBound.variable))
-         {
-            return false;
-         }
-         for (Iterator<Type> it = fromChoiceBound.bounds.iterator(); it.hasNext();)
-         {
-            Type fromOption = it.next();
-            if (!isAssignable(type, fromOption))
-            {
-               it.remove();
-            }
-         }
-         return !fromChoiceBound.bounds.isEmpty();
-      }
-      if (type instanceof Class)
-      {
-         if (type == Object.class)
-         {
-            return true;
-         }
-         Class<?> clazz = (Class<?>) type;
-         if (fromType instanceof Class)
-         {
-            return clazz.isAssignableFrom((Class<?>) fromType);
-         }
-         if (fromType instanceof ParameterizedType)
-         {
-            return clazz.isAssignableFrom((Class<?>) ((ParameterizedType) fromType).getRawType());
-         }
-         if (fromType instanceof WildcardType)
-         {
-            WildcardType fromWildcard = (WildcardType) fromType;
-            boolean boundOk = false;
-            for (Type upperBound: fromWildcard.getUpperBounds())
-            {
-               if (isAssignable(type, upperBound))
-               {
-                  boundOk = true;
-                  break;
-               }
-            }
-            if (!boundOk)
-            {
-               return false;
-            }
-            for (Type lowerBound: fromWildcard.getLowerBounds())
-            {
-               if (isAssignable(type, lowerBound))
-               {
-                  return true;
-               }
-            }
-            return false;
-         }
-         if (fromType instanceof TypeVariable)
-         {
-            for (Type upperBound: ((TypeVariable) fromType).getBounds())
-            {
-               if (isAssignable(type, upperBound))
-               {
-                  return true;
-               }
-            }
-            return false;
-         }
-         return clazz.isArray() && isAssignable(clazz.getComponentType(), 
-               ((GenericArrayType) fromType).getGenericComponentType());
-      }
-      if (type instanceof ParameterizedType)
-      {
-         return ParamTypeAssignabilityAlgorithm.isAssignable(
-               (ParameterizedType) type, fromType, CHECKER, this, false);
-      }
-      if (type instanceof TypeVariable)
-      {
-         for (Type bound: ((TypeVariable) type).getBounds())
-         {
-            if (!isAssignable(bound, fromType))
-            {
-               return false;
-            }
-         }
-         return true;
-      }
-      ChoiceBound choiceBound = (ChoiceBound) type;
-      if (fromType instanceof TypeVariable &&
-            !isAssignable(choiceBound.variable, (TypeVariable) fromType))
-      {
-         return false;
-      }
-      for (Iterator<Type> it = choiceBound.bounds.iterator(); it.hasNext();)
-      {
-         Type boundOption = it.next();
-         if (!isAssignable(boundOption, fromType))
-         {
-            it.remove();
-         }
-      }
-      return !choiceBound.bounds.isEmpty();
-   }
-   
-   protected boolean isSame(Type argument, Type fromArgument, boolean argumentAssigned)
-   {
-      if (argument instanceof WildcardType)
-      {
-         WildcardType wildcard = (WildcardType) argument;
-         Type[] upperBounds = wildcard.getUpperBounds();
-         Type[] lowerBounds = wildcard.getLowerBounds();
-         if (fromArgument instanceof WildcardType)
-         {
-            WildcardType fromWildcard = (WildcardType) fromArgument;
-            Type[] fromUpperBounds = fromWildcard.getUpperBounds();
-            if (!isAssignable(upperBounds, fromUpperBounds))
-            {
-               return false;
-            }
-            
-            Type[] fromLowerBounds = fromWildcard.getLowerBounds();
-            outer: for (int i = 0; i < fromLowerBounds.length; i++)
-            {
-               for (int j = 0; j < lowerBounds.length; j++)
-               {
-                  if (isAssignable(fromLowerBounds[i], lowerBounds[j]))
-                  {
-                     continue outer;
-                  }
-               }
-               return false;
-            }
-            return true;
-         }
-         if (argumentAssigned)
-         {
-            return false;
-         }
-         if(fromArgument instanceof TypeVariable)
-         {
-            if (!isAssignable(upperBounds, ((TypeVariable) fromArgument).getBounds()))
-            {
-               return false;
-            }
-         }
-         else
-         {
-            for (int i = 0; i < upperBounds.length; i++)
-            {
-               if (!isAssignable(upperBounds[i], fromArgument))
-               {
-                  return false;
-               }
-            }
-            return true;
-         }
-      }
-      else if (argument instanceof GenericArrayType)
-      {
-         if (fromArgument instanceof GenericArrayType)
-         {
-            return isSame(((GenericArrayType) argument).getGenericComponentType(),
-                  ((GenericArrayType) fromArgument).getGenericComponentType(),
-                  argumentAssigned);
-         }
-         else
-         {
-            return false;
-         }
-      }
-      return argument.equals(fromArgument); // TODO check this works correctly
-   }
-
-   /**
-    * @param node
-    * @param upperBounds
-    * @param upperBounds
-    */
-   private boolean isAssignable(Type[] upperBounds, Type[] fromUpperBounds)
-   {
-      outer: for (int i = 0; i < upperBounds.length; i++)
-      {
-         for (int j = 0; j < fromUpperBounds.length; j++)
-         {
-            if (isAssignable(upperBounds[i], fromUpperBounds[j]))
-            {
-               continue outer;
-            }
-         }
-         return false;
-      }
-      return true;
-   }
-   
-   private static ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode> CHECKER =
-      new ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode>()
-      {
-         public boolean isSame(Type argument, Type fromArgument, VariableNode node, boolean boundLevel)
-         {
-            return node.isSame(argument, fromArgument, false);
-         }
-      };
-}
-
-class ChoiceBound implements Type
-{
-   public ChoiceBound(TypeVariable variable, Type[] bounds)
-   {
-      this.variable = variable;
-      this.bounds = new LinkedList<Type>();
-      Collections.addAll(this.bounds, bounds);
-   }
-   TypeVariable variable;
-   Collection<Type> bounds;
-}
\ No newline at end of file

Copied: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java (from rev 63838, projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/Algorithm.java)
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/Algorithm.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,356 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+
+/**
+ * 
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public enum Algorithm
+{
+   
+   VARIABLE_TARGET()
+   {
+      protected Algorithm getInverseAlgorithm()
+      {
+         return FROM_VARIABLE;
+      }
+      
+      protected boolean isVariableOperationApplicable(Type type, Type fromType)
+      {
+         return type instanceof TypeVariable;
+      }
+      
+      protected boolean assignValue(Type type, Type fromType,
+            VariableHierarchy variableHierarchy, boolean boundLevel)
+      {
+         VariableNode node = variableHierarchy.getVariableNode((TypeVariable) type);
+         return node.assignValue(fromType, boundLevel);
+      }
+      
+      protected boolean addBound(Type type, Type fromType,
+            VariableHierarchy variableHierarchy)
+      {
+         VariableNode node = variableHierarchy.getVariableNode((TypeVariable) type);
+         return node.addLowerBound(fromType);
+      }
+   },
+   FROM_VARIABLE()
+   {
+      protected Algorithm getInverseAlgorithm()
+      {
+         return VARIABLE_TARGET;
+      }
+      
+      protected boolean isVariableOperationApplicable(Type type, Type fromType)
+      {
+         return fromType instanceof TypeVariable;
+      }
+      
+      protected boolean assignValue(Type type, Type fromType,
+            VariableHierarchy variableHierarchy, boolean boundLevel)
+      {
+         VariableNode fromNode = variableHierarchy.getVariableNode((TypeVariable) fromType);
+         return fromNode.assignValue(type, boundLevel);
+      }
+      
+      protected boolean addBound(Type type, Type fromType,
+            VariableHierarchy variableHierarchy)
+      {
+         VariableNode fromNode = variableHierarchy.getVariableNode((TypeVariable) fromType);
+         return fromNode.addUpperBound(type);
+      }
+   };
+
+   protected abstract Algorithm getInverseAlgorithm();
+   protected abstract boolean isVariableOperationApplicable(Type type, Type fromType);
+   
+   protected abstract boolean assignValue(Type type, Type fromType,
+         VariableHierarchy variableHierarchy, boolean boundLevel);
+   
+   protected abstract boolean addBound(Type type, Type fromType,
+         VariableHierarchy variableHierarchy);
+   
+   public boolean isAssignable(Type type, Type fromType,
+         VariableHierarchy variableHierarchy)
+   {
+      // special case, check fromType
+      if (fromType instanceof WildcardType)
+      {
+         return isAssignable(type, (WildcardType) fromType, variableHierarchy);
+      }
+      if (isVariableOperationApplicable(type, fromType))
+      {
+         return addBound(type, fromType, variableHierarchy);
+      }
+      if (type instanceof Class)
+      {
+         return isAssignable((Class<?>) type, fromType, variableHierarchy);
+      }
+      if (type instanceof ParameterizedType)
+      {
+         return isAssignable((ParameterizedType) type, fromType,
+               variableHierarchy, false);
+      }
+      if (type instanceof WildcardType)
+      {
+         throw new RuntimeException("This comparison should never happen");
+      }
+      else
+      {
+         return isAssignable((GenericArrayType) type, fromType,
+               variableHierarchy);
+      }
+   }
+   
+   private boolean isAssignable(Type type, WildcardType fromWildcardType,
+         VariableHierarchy variableHierarchy)
+   {
+      boolean boundOk = false;
+      for (Type upperBound: fromWildcardType.getUpperBounds())
+      {
+         if (isAssignable(type, upperBound, variableHierarchy))
+         {
+            boundOk = true;
+            break;
+         }
+      }
+      if (!boundOk)
+      {
+         return false;
+      }
+      for (Type lowerBound: fromWildcardType.getLowerBounds())
+      {
+         if (isAssignable(type, lowerBound, variableHierarchy))
+         {
+            return true;
+         }
+      }
+      return fromWildcardType.getLowerBounds().length == 0;
+   }
+
+   // is classType super of fromType?
+   private boolean isAssignable(Class<?> classType, Type fromType,
+         VariableHierarchy variableHierarchy)
+   {
+      if (fromType instanceof Class)
+      {
+         return classType.isAssignableFrom((Class<?>) fromType);
+      }
+      else if (fromType instanceof ParameterizedType)
+      {
+         return classType.isAssignableFrom(
+               (Class<?>) ((ParameterizedType) fromType).getRawType());
+      }
+      else if (fromType instanceof TypeVariable)
+      {
+         Type[] bounds = getConcreteBounds(fromType);
+         boolean inside = false;
+         for (int i = 0; i < bounds.length && !inside; i++)
+         {
+            if (bounds[i] instanceof Class)
+            {
+               if (classType.isAssignableFrom((Class<?>) bounds[i]))
+               {
+                  inside = true;
+               }
+            }
+            else
+            {
+               // bound must be a parameterized type
+               if (classType.isAssignableFrom(
+                     (Class<?>) ((ParameterizedType) bounds[i]).getRawType()))
+               {
+                  inside = true;
+               }
+            }
+         }
+         return inside;
+      }
+      // type instanceof GenericArrayType (ommitting check for performance
+      // reasons)
+      if (classType == Object.class)
+      {
+         return true;
+      }
+      if (classType.isArray())
+      {
+         return isAssignable(classType.getComponentType(),
+               ((GenericArrayType) fromType).getGenericComponentType(),
+               variableHierarchy);
+      }
+      return false;
+   }
+
+   /**
+    * @param type
+    * @return
+    */
+   private Type[] getConcreteBounds(Type type)
+   {
+      TypeVariable current = (TypeVariable) type;
+      Type[] bounds = current.getBounds();
+      while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
+      {
+         current = (TypeVariable) bounds[0];
+         bounds = current.getBounds();
+      }
+      return bounds;
+   }
+
+   private boolean isAssignable(ParameterizedType paramType, Type fromType, 
+         VariableHierarchy variableHierarchy, boolean boundLevel)
+   {
+      if (fromType instanceof TypeVariable)
+      {
+         Type[] concreteBounds = getConcreteBounds((TypeVariable) fromType);
+         for (int i = 0; i < concreteBounds.length; i++)
+         {
+            if (isAssignable(paramType, concreteBounds[i], variableHierarchy, true))
+            {
+               return true;
+            }
+         }
+         return false;
+      }
+      return ParamTypeAssignabilityAlgorithm.isAssignable(
+            paramType, fromType, CHECKER, this, variableHierarchy, boundLevel);
+   }
+
+   private boolean isAssignable(GenericArrayType arrayType, Type fromType,
+         VariableHierarchy variableHierarchy)
+   {
+      if (fromType instanceof Class)
+      {
+         Class<?> fromClass = (Class<?>) fromType;
+         if (!fromClass.isArray())
+         {
+            return false;
+         }
+         return isAssignable(arrayType.getGenericComponentType(),
+               fromClass.getComponentType(), variableHierarchy);
+      }
+      if (fromType instanceof GenericArrayType)
+      {
+         GenericArrayType fromArrayType = (GenericArrayType) fromType;
+         return isAssignable(arrayType.getGenericComponentType(),
+               fromArrayType.getGenericComponentType(), variableHierarchy);
+      }
+      return false;
+   }
+
+   //////////////////////////////////////////////////////////
+   private static final ParamTypeAssignabilityAlgorithm.EqualityChecker<Algorithm, VariableHierarchy> CHECKER
+      = new ParamTypeAssignabilityAlgorithm.EqualityChecker<Algorithm, VariableHierarchy>()
+   {
+      public boolean isSame(Type type, Type fromType, Algorithm client, VariableHierarchy variableHierarchy, boolean boundLevel)
+      {
+         if(Algorithm.VARIABLE_TARGET.isVariableOperationApplicable(type, fromType))
+         {
+            return Algorithm.VARIABLE_TARGET.assignValue(type, fromType, variableHierarchy, boundLevel);
+         }
+         if (type instanceof Class)
+         {
+            return type.equals(fromType);
+         }
+         if (type instanceof ParameterizedType)
+         {
+            if (!(fromType instanceof ParameterizedType))
+            {
+               return false;
+            }
+            ParameterizedType fromParamType = (ParameterizedType) fromType;
+            ParameterizedType paramType = (ParameterizedType) type;
+            if (!isSame(paramType.getRawType(), fromParamType.getRawType(), client,
+                  variableHierarchy, boundLevel))
+            {
+               return false;
+            }
+            return isSame(paramType.getActualTypeArguments(),
+                  fromParamType.getActualTypeArguments(), client, variableHierarchy, boundLevel);
+         }
+         if (type instanceof WildcardType)
+         {
+            Type[] upperBounds = ((WildcardType) type).getUpperBounds();
+            Type[] lowerBounds = ((WildcardType) type).getLowerBounds();
+            if (fromType instanceof WildcardType)
+            {
+               Type[] fromUpperBounds = ((WildcardType) fromType).getUpperBounds();
+               outer: for (int i = 0; i < upperBounds.length; i++)
+               {
+                  for (int j = 0; j < fromUpperBounds.length; j++)
+                  {
+                     if (client.isAssignable(upperBounds[i],
+                           fromUpperBounds[i], variableHierarchy))
+                     {
+                        continue outer;
+                     }
+                  }
+                  return false;
+               }
+               Type[] fromLowerBounds = ((WildcardType) fromType).getLowerBounds();
+               outer: for (int i = 0; i < lowerBounds.length; i++)
+               {
+                  for (int j = 0; j < fromLowerBounds.length; j++)
+                  {
+                     if (client.getInverseAlgorithm().isAssignable(
+                           fromLowerBounds[i],
+                           lowerBounds[i], variableHierarchy))
+                     {
+                        continue outer;
+                     }
+                  }
+                  return false;
+               }
+               return true;
+            }
+            else
+            {
+               for (int i = 0; i < upperBounds.length; i++)
+               {
+                  if (!client.isAssignable(upperBounds[i], fromType,
+                        variableHierarchy))
+                  {
+                     return false;
+                  }
+               }
+               for (int i = 0; i < lowerBounds.length; i++)
+               {
+                  if (!client.getInverseAlgorithm().isAssignable(
+                        fromType, lowerBounds[i], variableHierarchy))
+                  {
+                     return false;
+                  }
+               }
+               return true;
+            }
+         }
+         return true;
+      }
+   };
+}
\ No newline at end of file

Copied: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ArgumentContextualizer.java (from rev 63838, projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ArgumentContextualizer.java)
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ArgumentContextualizer.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ArgumentContextualizer.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,490 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+/**
+ * Argument contextualizer. Performs contextualization of arguments through hierarchy
+ * 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ArgumentContextualizer
+{
+   public static final Type[] getContextualizedArguments(ParameterizedType paramType,
+         Class rawType, Class desiredType)
+   {
+      ArgumentContextualizer contextualizedArguments = getContextualizedArgumentsInternal(
+            desiredType, rawType);
+      if (contextualizedArguments == null)
+      {
+         return null;
+      }
+      if (paramType != null)
+      {
+         contextualizedArguments.contextualizeVariables(null, paramType);
+      }
+      return contextualizedArguments.getArguments();
+   }
+
+   
+   private static final ArgumentContextualizer getContextualizedArgumentsInternal(
+         Class<?> desiredType, Class<?> classType)
+   {
+      Type superType = null;
+      if (desiredType.isInterface())
+      {
+         for (Type superInterface : classType.getGenericInterfaces())
+         {
+            if ((superInterface instanceof Class && desiredType
+                  .isAssignableFrom((Class<?>) superInterface))
+                  || (superInterface instanceof ParameterizedType &&
+                        desiredType.isAssignableFrom((Class<?>)
+                              ((ParameterizedType) superInterface).getRawType())))
+            {
+               superType = superInterface;
+               break;
+            }
+         }
+      }
+      if (superType == null)
+      {
+         superType = classType.getGenericSuperclass();
+      }
+      ArgumentContextualizer result = null;
+      if (superType instanceof Class)
+      {
+         if (superType == desiredType)
+         {
+            return null;
+         }
+         result = getContextualizedArgumentsInternal(desiredType,
+               (Class<?>) superType);
+      }
+      else
+      {
+         ParameterizedType superParamType = (ParameterizedType) superType;
+         Class<?> superClassType = (Class<?>) superParamType.getRawType();
+         if (superClassType == desiredType)
+         {
+            return new ArgumentContextualizer(superParamType
+                  .getActualTypeArguments(), classType);
+         }
+         else
+         {
+            result = getContextualizedArgumentsInternal(desiredType,
+                  superClassType);
+         }
+      }
+      if (result == null
+            || !result.contextualizeVariables(classType, superType))
+      {
+         return null;
+      }
+      return result;
+   }
+   
+   
+   private Type[] arguments;
+   private LinkedList<VariableReplacer> variableReplacements;
+
+   // declaring class extends queried class (DeclaringClass<A, B, C> extends Queried<X, Y, Z, ..., W>,
+   // where X, Y, Z...W, are a list of types for which we need to map (contextualize)
+   // variables
+   // A, B, C... D are variables of DeclaringClass, that may be used in the contextualization proccess
+   /**
+    * Constructor.
+    * 
+    * @param arguments      the set of arguments in their original context (the
+    *                       extends or implements declaration)
+    * @param declaringClass the class that declared those arguments. This class
+    *                       must be the same class that extends/implements a
+    *                       queried parameterized type.
+    */
+   private ArgumentContextualizer(Type[] arguments, Class<?> declaringClass)
+   {
+      this.arguments = arguments;
+      for (int i = 0; i < arguments.length; i++)
+      {
+         Type newArgument = processArgument(arguments, i, declaringClass,
+               replacementCreator, this);
+         if (newArgument != null)
+         {
+            this.arguments[i] = newArgument;
+         }
+      }
+   }
+
+   // newDeclaringClass extends/implements oldDeclaringType
+   // returns false = warning (work with raw type hence)
+   /**
+    * Performs a contextualization step.
+    * 
+    * @param subClass  a class that declares to extend/implement <code>superType
+    *                  </code> 
+    * @param superType the super type of <code>subClass</code>
+    * 
+    * @return <code>true</code> if the contextualization process was successfully
+    *         performed; </code>false</code> otherwise.
+    */
+   private boolean contextualizeVariables(Class subClass, Type superType)
+   {
+      if (!initialized || variableReplacements.isEmpty())
+      {
+         initialized = false;
+         return true;
+      }
+      if (superType instanceof Class)
+      {
+         return false; // warning: variables lost in hierarchy
+      }
+      ParameterizedType superParamType = (ParameterizedType) superType;
+      for (iterator = variableReplacements.listIterator(); iterator.hasNext(); )
+      {
+         if(iterator.next().replace(superParamType, subClass))
+         {
+            iterator.remove();
+         }
+      }
+      iterator = null;
+      return true; 
+   }
+   
+   /**
+    * Process an argument, definining whether it needs to be replaced during
+    * contextualization process or not.
+    * 
+    * @param <O>
+    * 
+    * @param argumentContainer the array that contains the argument to be
+    *                          processed 
+    * @param argumentIndex     the index of the argument in <code>
+    *                          argumentContainer</code>
+    * @param declaringClass    the class that declares the argument
+    * @param recorder          object responsible for recording future
+    *                          replacements to be performed during
+    *                          contextualization
+    * @param outer             
+    * @return the argument processed. This return value may be null if no
+    *         processement of <code>argumentContainer[argumentIndex]</code> is
+    *         rerquired, or an equivalent type otherwise.
+    */
+   private static <O> Type processArgument(Type[] argumentContainer,
+         int argumentIndex, Class<?> declaringClass,
+         ReplacementScheduler<O> recorder, O outer)
+   {
+      Type argument = argumentContainer[argumentIndex];
+      if (argument instanceof Class)
+      {
+         return null;
+      }
+      if (argument instanceof ParameterizedType)
+      {
+         ParameterizedType paramType = (ParameterizedType) argument;
+         ParameterizedType_ newParamType = null;
+         Type[] arguments = paramType.getActualTypeArguments();
+         for (int i = 0; i < arguments.length; i++)
+         {
+            Type newType = processArgument(arguments, i, declaringClass, recorder,
+                  outer);
+            if (newType != null)
+            {
+               if (newParamType == null)
+               {
+                  newParamType = new ParameterizedType_(paramType);
+               }
+               newParamType.getActualTypeArguments()[i] = newType;
+            }
+         }
+         return newParamType;
+      }
+      //else if (bounds[i] instanceof TypeVariable)
+      if (declaringClass == null)
+      {
+         return null;
+      }
+      String paramName = ((TypeVariable) argument).getName();
+      int index = 0;
+      TypeVariable[] typeVariables = declaringClass.getTypeParameters();
+      for (index = 0; index < typeVariables.length; index ++)
+      {
+         if (typeVariables[index].getName().equals(paramName)){
+            break;
+         }
+      }
+      recorder.scheduleReplacement(argumentContainer, argumentIndex, index, outer);
+      return argument; 
+   }
+
+   boolean initialized = false;
+
+   private void initialize()
+   {
+      if (!initialized)
+      {
+         Type[] oldResult = this.arguments;
+         this.arguments = new Type[oldResult.length];
+         System.arraycopy(oldResult, 0, this.arguments, 0, this.arguments.length);
+         this.variableReplacements = new LinkedList<VariableReplacer>();
+         initialized = true;
+      }
+   }
+   private ListIterator<VariableReplacer> iterator;
+
+   /**
+    * Returns contextualized arguments.
+    * 
+    * @return contextualized arguments
+    */
+   public Type[] getArguments()
+   {
+      return this.arguments;
+   }
+
+   /**
+    * Creates a variable replacement. This replacement should take place during the
+    * contextualization steps, where the variable will be replaced by its value.
+    * Notice this value may or may not be another variable.
+
+    * @param argumentContainer array on which the replacement will be executed 
+    * @param argumentIndex     the index that indicates a position of the variable
+    *                          to be replaced in <code>argumentContainer</code>
+    *                          array
+    * @param variableIndex     index of the variable value in the next argument
+    *                          context array. This index shall be used on the
+    *                          replacement, during contextualization process.
+    */
+   private void createVariableReplacement(Type[] argumentContainer, int argumentIndex,
+         int variableIndex)
+   {
+      if (iterator != null)
+      {
+         iterator.add(new VariableReplacer(argumentContainer, argumentIndex,
+               variableIndex));
+      }
+      else
+      {
+         this.variableReplacements.add(new VariableReplacer(
+               argumentContainer, argumentIndex, variableIndex));
+      }
+   }
+   
+   /**
+    * Replaces a variable by another type according to an argument context.
+    *  
+    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+    */
+   class VariableReplacer
+   {
+      private Type[] arguments;
+      private int argumentIndex;
+      private int valueIndex;
+      private boolean pendingExecution;
+
+      /**
+       * Constructor.
+       * 
+       * @param arguments     array on which the replacement will be executed 
+       * @param argumentIndex the index that indicates a position of the variable
+       *                      to be replaced in <code>argumentContainer</code> array
+       * @param valueIndex    index of the variable value in the next argument
+       *                      context array. This index shall be used on the
+       *                      replacement, during contextualization process.
+       */
+      public VariableReplacer(Type[] arguments, int argumentIndex, int valueIndex)
+      {
+         this.valueIndex = valueIndex;
+         this.arguments = arguments;
+         this.argumentIndex = argumentIndex;
+         this.pendingExecution = true;
+      }
+
+      // return true if replacement has been done for good
+      /**
+       * Performs replacemen of a variable by a new type.
+       * 
+       * @param paramType      parameterized type that contains the context to be
+       *                       used during replacement proccess.
+       * @param declaringClass the class that declares the the variables used in the
+       *                       arguments of <code>paramType</code>. This class must
+       *                       extend/implement the generic type
+       *                       <code>paramType</code>.
+       */
+      public boolean replace(ParameterizedType paramType, Class<?> declaringClass)
+      {
+         arguments[argumentIndex] = paramType.getActualTypeArguments()[valueIndex];
+         this.pendingExecution = false;
+         Type newType = ArgumentContextualizer.processArgument(arguments, argumentIndex,
+               declaringClass, updater, this);
+         if (newType != null)
+         {
+            arguments[argumentIndex] = newType;
+            return false;
+         }
+         return true;
+      }
+
+      /**
+       * Returns the contextualizer that scheduled this replacement.
+       * 
+       * @return the contextualizer.
+       */
+      ArgumentContextualizer getContextualizer()
+      {
+         return ArgumentContextualizer.this;
+      }
+   }
+
+   /**
+    * Parameterized type implementation. Allows replacement of arguments without
+    * affecting reflection information.
+    * 
+    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+    */
+   private static final class ParameterizedType_ implements ParameterizedType
+   {
+      private Type[] arguments;
+      private Type ownerType;
+      private Type rawType;
+
+      ParameterizedType_(ParameterizedType type)
+      {
+         Type[] actualArguments = type.getActualTypeArguments();
+         this.arguments = new Type[actualArguments.length];
+         System.arraycopy(actualArguments, 0, arguments, 0, actualArguments.length);
+         this.ownerType = type.getOwnerType();
+         this.rawType = type.getRawType();
+      }
+
+
+      public Type[] getActualTypeArguments()
+      {
+         return this.arguments;
+      }
+
+      public Type getOwnerType()
+      {
+         return this.ownerType;
+      }
+
+      public Type getRawType()
+      {
+         return this.rawType;
+      }
+
+      public boolean equals(Object obj)
+      {
+         if (!(obj instanceof ParameterizedType))
+         {
+            return false;
+         }
+         ParameterizedType other = (ParameterizedType) obj;
+         if (!this.ownerType.equals(other.getOwnerType()) ||
+               !this.rawType.equals(other.getRawType()))
+         {
+            return false;
+         }
+         Type[] otherArguments = other.getActualTypeArguments();
+         for (int i = 0; i < arguments.length; i++)
+         {
+            if (!arguments[i].equals(otherArguments[i]))
+            {
+               return false;
+            }
+         }
+         return true;
+      }
+   }
+
+   /**
+    * Schedules replacements to be performed during contextualization.
+    * 
+    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+    *
+    * @param <C> the scheduler client 
+    */
+   interface ReplacementScheduler<C>
+   {
+      /**
+       * Schedules a variable replacement to be performed on next contextualization
+       * step.
+       * 
+       * @param argumentContainer array on which the replacement will be executed 
+       * @param argumentIndex     the index that indicates a position of the variable
+       *                          to be replaced in <code>argumentContainer</code>
+       *                          array
+       * @param variableIndex     index of the variable value in the next argument
+       *                          context array. This index shall be used on the
+       *                          replacement, during contextualization process.
+       * @param client            the client of recorder
+       */
+      public void scheduleReplacement(Type[] argumentContainer, int argumentIndex,
+            int variableIndex, C client);
+   }
+   
+   /**
+    * Schedules variable replacement when required by contextualizer.
+    * The effect of this scheduling process is the creation of variable replacement.
+    */
+   private static ReplacementScheduler<ArgumentContextualizer> replacementCreator =
+      new ReplacementScheduler<ArgumentContextualizer>()
+   {
+      public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
+            int variableIndex, ArgumentContextualizer outer)
+      {
+         outer.initialize();
+         outer.createVariableReplacement(outer.arguments, targetIndex, variableIndex);
+      }
+   };
+   
+   /**
+    * Schedules variable replacement when required by a <code>VariableReplacement
+    * </code> object.
+    * Generally, the effect of this schedule process will be an update in
+    * the client object, unless this one already has a pending replacement scheduled.
+    */
+   private static ReplacementScheduler<VariableReplacer> updater =
+      new ReplacementScheduler<VariableReplacer>()
+   {
+      public void scheduleReplacement(Type[] replacementTarget, int targetIndex,
+            int variableIndex, VariableReplacer replacer)
+      {
+         if (replacer.pendingExecution) // replacer is already busy
+         {
+            replacer.getContextualizer().createVariableReplacement(replacementTarget,
+                  targetIndex, variableIndex);
+         }
+         else
+         {
+            replacer.valueIndex = variableIndex;
+            replacer.arguments = replacementTarget;
+            replacer.argumentIndex = targetIndex;
+            replacer.pendingExecution = true;
+         }
+      }
+   };
+}
\ No newline at end of file

Added: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ChoiceBound.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ChoiceBound.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ChoiceBound.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,44 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+
+/**
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ChoiceBound implements Type
+{
+   public ChoiceBound(TypeVariable variable, Type[] bounds)
+   {
+      this.variable = variable;
+      this.bounds = new LinkedList<Type>();
+      Collections.addAll(this.bounds, bounds);
+   }
+   TypeVariable variable;
+   Collection<Type> bounds;
+}
\ No newline at end of file

Copied: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java (from rev 63838, projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/ParamTypeAssignabilityAlgorithm.java)
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/ParamTypeAssignabilityAlgorithm.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,152 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+
+/**
+ * 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ParamTypeAssignabilityAlgorithm
+{
+   /**
+    * Class responsible for telling whether two groups of arguments, used on
+    * two different instances of ParameterizedType, can be considered the same
+    * group of arguments.
+    * 
+    * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+    *
+    * @param <T> this is a token that can be used to store information useful for
+    *            the implementor.
+    */
+   static abstract class EqualityChecker<C, T>
+   {
+      /**
+       * Indicates whether both argument list can be considered the same.
+       * This method is a facility that will invoke {@link #isSame(Type, Type, Object)}
+       * for each argument of the lists. Both lists have the same length.
+       * 
+       * @param arguments     list of arguments.
+       * @param fromArguments list of arguments that will be assigned to <code>
+       *                      arguments</code> only if this method returns <code>true
+       *                      </code>
+       * @param token         a token that may be needed by implementor as auxiliar
+       * @return              <code>true</code> only if values of <code>
+       *                      fromArguments</code> list can be assigned to a list of
+       *                      <code>arguments</code> type.
+       */
+      protected boolean isSame(Type[] arguments, Type[] fromArguments, C caller, T token, boolean assignAllowed)
+      {
+         for (int i = 0; i < arguments.length; i++)
+         {
+            if (!isSame(arguments[i], fromArguments[i], caller, token, assignAllowed))
+            {
+               return false;
+            }
+         }
+         return true;
+      }
+
+      /**
+       * Indicates whether both arguments can be considered the same.
+       * This method execution might require some variable inference process,
+       * in which case only a variable type referenced by <code>argument</code> can
+       * have its value infered according to the process.
+       * @param token         a token that may be needed by implementor as auxiliar
+       * @param arguments     an argument type
+       * @param fromArguments argument type that will have its value assigned to
+       *                      <code>argument</code> only if this method returns
+       *                      <code>true</code>
+       * 
+       * @return              <code>true</code> only if a parameterized type with
+       *                      <code>argument</code> as one of its parameter values
+       *                      can be assigned from the same parameterized type with
+       *                      <code>fromArgument</code> as the equivalent parameter
+       *                      value
+       */
+      abstract boolean isSame(Type argument, Type fromArgument, C caller, T token, boolean assignAllowed);
+   }
+
+   /**
+    * 
+    * @param <T>
+    * @param paramType
+    * @param fromType
+    * @param checker
+    * @param checkerToken
+    * @return
+    */
+   public static<C, T> boolean isAssignable(ParameterizedType paramType, Type fromType,
+         EqualityChecker<C, T> checker, C caller, T checkerToken, boolean assignAllowed)
+   {
+      Class<?> fromRaw = null;
+      ParameterizedType fromParamType = null;
+      Class<?> desiredType = (Class<?>) paramType.getRawType();
+      if (fromType instanceof Class)
+      {
+         fromRaw = (Class<?>) fromType;
+         if (!desiredType.isAssignableFrom(fromRaw))
+         {
+            return false;
+         }
+         if (fromRaw.getTypeParameters().length > 0)
+         {
+            // notice that, if fromRaw equals desiredType, we also have the
+            // result true with a warning (i.e., this if statemente is not only for
+            // fromRaw subclass of desiredType, but also for fromRaw same as
+            // desiredType
+            return true;// TODO With warning
+         }
+      }
+      else if (fromType instanceof ParameterizedType)
+      {
+         fromParamType = (ParameterizedType) fromType;
+         fromRaw = (Class<?>) fromParamType.getRawType();
+         if (fromRaw == desiredType)
+         {
+            // compare arguments with arguments
+            return checker.isSame(paramType.getActualTypeArguments(),
+                  fromParamType.getActualTypeArguments(), caller, checkerToken, assignAllowed);
+         }
+         else if (!desiredType.isAssignableFrom(fromRaw))
+         {
+            return false;
+         }
+      }
+      else
+      {
+         return false;
+      }
+      // try to get, if null, warning, parameters lost in hierarchy
+      Type[] arguments = ArgumentContextualizer.getContextualizedArguments(
+            fromParamType, fromRaw, desiredType);
+      if (arguments == null)
+      {
+         return true; // TODO with Warning
+      }
+      return checker.isSame(paramType.getActualTypeArguments(), arguments, caller, checkerToken, assignAllowed);
+   }
+}
\ No newline at end of file

Added: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableHierarchy.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,70 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.TypeVariable;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class VariableHierarchy
+{
+   private Map<String, VariableNode> map;
+   private int boundComparation;
+   
+   public VariableHierarchy()
+   {
+      this.map = new HashMap<String, VariableNode>();
+   }
+
+   VariableNode getVariableNode(TypeVariable typeVariable)
+   {
+      String key = typeVariable.getName();
+      if (map.containsKey(key))
+      {
+         return map.get(key);
+      }
+      VariableNode node = new VariableNode(typeVariable, this);
+      map.put(key, node);
+      return node;
+   }
+   
+   void startBoundComparation()
+   {
+      this.boundComparation ++;
+   }
+   
+   void finishBoundComparation()
+   {
+      this.boundComparation --;
+   }
+   
+   boolean isBoundComparation()
+   {
+      return this.boundComparation > 0;
+   }
+}
\ No newline at end of file

Copied: projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java (from rev 63838, projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/VariableNode.java)
===================================================================
--- projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/main/org/jboss/aop/advice/annotation/assignability/VariableNode.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,454 @@
+/*
+ * 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.advice.annotation.assignability;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+
+/**
+ * 
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class VariableNode
+{
+   private VariableHierarchy hierarchy;
+   private VariableNode previous;
+   private VariableNode next;
+   private Collection<Type> lowerBounds;
+   private TypeVariable variable;
+   private Type assignedValue;
+   
+   public VariableNode(TypeVariable content, VariableHierarchy hierarchy)
+   {
+      this.hierarchy = hierarchy;
+      this.variable = content;
+      lowerBounds = new HashSet<Type>();
+      Type[] bounds = content.getBounds();
+      if (bounds.length == 1 && bounds[0] instanceof TypeVariable)
+      {
+         TypeVariable typeVariable = (TypeVariable) bounds[0];
+         next = hierarchy.getVariableNode(typeVariable);
+         next.previous = this;
+      }
+   }
+   
+   public final boolean assignValue(Type value, boolean boundLevel)
+   {
+      if (this.hierarchy.isBoundComparation() && !(value instanceof Class)
+            && !(value instanceof ParameterizedType))
+      {
+         return false;
+      }
+      
+      if (boundLevel && value instanceof WildcardType)
+      {
+         return false;
+      }
+      
+      if (this.assignedValue != null)
+      {
+         // TODO HERE1 HERE HERE HERE HERE
+         return isSame(value, this.assignedValue, true);
+      }
+      
+      // TODO fix this
+      /*if (value instanceof WildcardType)
+      {
+         return false;
+      }*/
+      
+      if (!isInsideBounds(value, true) ||
+            (this.previous != null && !this.previous.areBoundsInside(value)))
+      {
+         return false;
+      }
+      this.assignedValue = value;
+      return true;
+   }
+   
+   public final boolean addLowerBound(Type lowerBound)
+   {
+      if (!isInsideBounds(lowerBound, false) ||
+            (this.previous != null && !this.previous.areBoundsInside(lowerBound)))
+      {
+         return false;
+      }
+      // TODO check this
+      if (lowerBound instanceof TypeVariable)
+      {
+         Type[] bounds = ((TypeVariable) lowerBound).getBounds();
+         this.lowerBounds.add(new ChoiceBound((TypeVariable) lowerBound, bounds));
+      }
+      else
+      {
+         this.lowerBounds.add(lowerBound);
+      }
+      return true;
+   }
+   
+   public final boolean addUpperBound(Type upperBound)
+   {
+      // TODO
+      return true;
+   }
+   
+   private boolean areBoundsInside(Type bound)
+   {
+      if (this.assignedValue != null && !isAssignable(bound, assignedValue))
+      {
+         return false;
+      }
+      for (Type lowerBound: this.lowerBounds)
+      {
+         if (!isAssignable(bound, lowerBound))
+         {
+            return false;
+         }
+      }
+      if (previous != null)
+      {
+         return previous.areBoundsInside(bound);
+      }
+      return true;
+   }
+   
+   private boolean isInsideBounds(Type lowerBound, boolean checkLowerBounds)
+   {
+      if (this.assignedValue != null && !isAssignable(lowerBound, assignedValue))
+      {
+         return false;
+      }
+      if (checkLowerBounds)
+      {
+         for (Type bound: this.lowerBounds)
+         {
+            if (!isAssignable(bound, lowerBound))
+            {
+               return false;
+            }
+         }
+      }
+      if (next == null)
+      {
+         Type[] bounds = variable.getBounds();
+         this.hierarchy.startBoundComparation();
+         try
+         {
+            for (int i = 0; i < bounds.length; i++)
+            {
+               if (!Algorithm.VARIABLE_TARGET.isAssignable(bounds[i], lowerBound, hierarchy))
+               {
+                  return false;
+               }
+            }
+         }
+         finally
+         {
+            this.hierarchy.finishBoundComparation();
+         }
+         return true;
+      }
+      return next.isInsideBounds(lowerBound, true);
+   }
+   
+   private boolean isAssignable(TypeVariable type, TypeVariable fromType)
+   {
+      Type[] fromBounds = fromType.getBounds();
+      if (type == fromType)
+      {
+         return true;
+      }
+      while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
+      {
+         if (fromBounds[0] == type)
+         {
+            return true;
+         }
+         fromType = (TypeVariable) fromBounds[0];
+         fromBounds = fromType.getBounds();
+      }
+      TypeVariable variable = (TypeVariable) type;
+      Type[] bounds = variable.getBounds();
+      while (bounds.length == 1 && bounds[0] instanceof TypeVariable)
+      {
+         if (bounds[0] == fromType)
+         {
+            return false;
+         }
+         variable = (TypeVariable) bounds[0];
+         bounds = variable.getBounds();
+      }
+      // TODO check if this should really be removed
+      /*outer: for (int i = 0; i < bounds.length; i++)
+      {
+         for (int j = 0; j < fromBounds.length; j++)
+         {
+            if (isAssignable(bounds[i], fromBounds[j]))
+            {
+               continue outer;
+            }
+         }
+         return false;
+      }
+      return true;*/
+      return false;
+   }
+   
+   // both type and bound belong to the same context
+   private boolean isAssignable(Type type, Type fromType)
+   {
+      if (fromType instanceof TypeVariable)
+      {
+         TypeVariable fromVariable = (TypeVariable) fromType;
+         if (type instanceof TypeVariable)
+         {
+            return isAssignable((TypeVariable) type, fromVariable);
+         }
+         Type[] fromBounds = fromVariable.getBounds();
+         TypeVariable temp = fromVariable;
+         while (fromBounds.length == 1 && fromBounds[0] instanceof TypeVariable)
+         {
+            temp = (TypeVariable) fromBounds[0];
+            fromBounds = temp.getBounds();            
+         }
+         for (Type fromBound: fromBounds)
+         {
+            if (isAssignable(type, fromBound))
+            {
+               return true;
+            }
+         }
+         return false;
+      }
+      if (fromType instanceof ChoiceBound)
+      {
+         ChoiceBound fromChoiceBound = (ChoiceBound) fromType;
+         if (type instanceof TypeVariable &&
+               !isAssignable((TypeVariable) type, fromChoiceBound.variable))
+         {
+            return false;
+         }
+         for (Iterator<Type> it = fromChoiceBound.bounds.iterator(); it.hasNext();)
+         {
+            Type fromOption = it.next();
+            if (!isAssignable(type, fromOption))
+            {
+               it.remove();
+            }
+         }
+         return !fromChoiceBound.bounds.isEmpty();
+      }
+      if (type instanceof Class)
+      {
+         if (type == Object.class)
+         {
+            return true;
+         }
+         Class<?> clazz = (Class<?>) type;
+         if (fromType instanceof Class)
+         {
+            return clazz.isAssignableFrom((Class<?>) fromType);
+         }
+         if (fromType instanceof ParameterizedType)
+         {
+            return clazz.isAssignableFrom((Class<?>) ((ParameterizedType) fromType).getRawType());
+         }
+         if (fromType instanceof WildcardType)
+         {
+            WildcardType fromWildcard = (WildcardType) fromType;
+            boolean boundOk = false;
+            for (Type upperBound: fromWildcard.getUpperBounds())
+            {
+               if (isAssignable(type, upperBound))
+               {
+                  boundOk = true;
+                  break;
+               }
+            }
+            if (!boundOk)
+            {
+               return false;
+            }
+            for (Type lowerBound: fromWildcard.getLowerBounds())
+            {
+               if (isAssignable(type, lowerBound))
+               {
+                  return true;
+               }
+            }
+            return false;
+         }
+         if (fromType instanceof TypeVariable)
+         {
+            for (Type upperBound: ((TypeVariable) fromType).getBounds())
+            {
+               if (isAssignable(type, upperBound))
+               {
+                  return true;
+               }
+            }
+            return false;
+         }
+         return clazz.isArray() && isAssignable(clazz.getComponentType(), 
+               ((GenericArrayType) fromType).getGenericComponentType());
+      }
+      if (type instanceof ParameterizedType)
+      {
+         return ParamTypeAssignabilityAlgorithm.isAssignable(
+               (ParameterizedType) type, fromType, CHECKER, this, null, false);
+      }
+      if (type instanceof TypeVariable)
+      {
+         for (Type bound: ((TypeVariable) type).getBounds())
+         {
+            if (!isAssignable(bound, fromType))
+            {
+               return false;
+            }
+         }
+         return true;
+      }
+      ChoiceBound choiceBound = (ChoiceBound) type;
+      if (fromType instanceof TypeVariable &&
+            !isAssignable(choiceBound.variable, (TypeVariable) fromType))
+      {
+         return false;
+      }
+      for (Iterator<Type> it = choiceBound.bounds.iterator(); it.hasNext();)
+      {
+         Type boundOption = it.next();
+         if (!isAssignable(boundOption, fromType))
+         {
+            it.remove();
+         }
+      }
+      return !choiceBound.bounds.isEmpty();
+   }
+   
+   protected boolean isSame(Type argument, Type fromArgument, boolean argumentAssigned)
+   {
+      if (argument instanceof WildcardType)
+      {
+         WildcardType wildcard = (WildcardType) argument;
+         Type[] upperBounds = wildcard.getUpperBounds();
+         Type[] lowerBounds = wildcard.getLowerBounds();
+         if (fromArgument instanceof WildcardType)
+         {
+            WildcardType fromWildcard = (WildcardType) fromArgument;
+            Type[] fromUpperBounds = fromWildcard.getUpperBounds();
+            if (!isAssignable(upperBounds, fromUpperBounds))
+            {
+               return false;
+            }
+            
+            Type[] fromLowerBounds = fromWildcard.getLowerBounds();
+            outer: for (int i = 0; i < fromLowerBounds.length; i++)
+            {
+               for (int j = 0; j < lowerBounds.length; j++)
+               {
+                  if (isAssignable(fromLowerBounds[i], lowerBounds[j]))
+                  {
+                     continue outer;
+                  }
+               }
+               return false;
+            }
+            return true;
+         }
+         if (argumentAssigned)
+         {
+            return false;
+         }
+         if(fromArgument instanceof TypeVariable)
+         {
+            if (!isAssignable(upperBounds, ((TypeVariable) fromArgument).getBounds()))
+            {
+               return false;
+            }
+         }
+         else
+         {
+            for (int i = 0; i < upperBounds.length; i++)
+            {
+               if (!isAssignable(upperBounds[i], fromArgument))
+               {
+                  return false;
+               }
+            }
+            return true;
+         }
+      }
+      else if (argument instanceof GenericArrayType)
+      {
+         if (fromArgument instanceof GenericArrayType)
+         {
+            return isSame(((GenericArrayType) argument).getGenericComponentType(),
+                  ((GenericArrayType) fromArgument).getGenericComponentType(),
+                  argumentAssigned);
+         }
+         else
+         {
+            return false;
+         }
+      }
+      return argument.equals(fromArgument); // TODO check this works correctly
+   }
+
+   /**
+    * @param node
+    * @param upperBounds
+    * @param upperBounds
+    */
+   private boolean isAssignable(Type[] upperBounds, Type[] fromUpperBounds)
+   {
+      outer: for (int i = 0; i < upperBounds.length; i++)
+      {
+         for (int j = 0; j < fromUpperBounds.length; j++)
+         {
+            if (isAssignable(upperBounds[i], fromUpperBounds[j]))
+            {
+               continue outer;
+            }
+         }
+         return false;
+      }
+      return true;
+   }
+   
+   private static ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode, ?> CHECKER =
+      new ParamTypeAssignabilityAlgorithm.EqualityChecker<VariableNode, Object>()
+      {
+         public boolean isSame(Type argument, Type fromArgument, VariableNode node,
+               Object token, boolean boundLevel)
+         {
+            return node.isSame(argument, fromArgument, false);
+         }
+      };
+}
\ No newline at end of file

Added: projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AllTests.java
===================================================================
--- projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AllTests.java	                        (rev 0)
+++ projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AllTests.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -0,0 +1,50 @@
+/*
+ * 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.test.aop.unit.assignability;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * @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.test.aop.unit.assignability");
+      //$JUnit-BEGIN$
+      suite.addTestSuite(ClassTypeTest.class);
+      suite.addTestSuite(ParameterizedTypeFromClassTest.class);
+      suite.addTestSuite(TypeVariableTest.class);
+      suite.addTestSuite(ParameterizedTypeFromVariableTest.class);
+      //suite.addTestSuite(ParameterizedTypeTest.class);
+      suite.addTestSuite(ParameterizedTypeFromParamTypeTest.class);
+      suite.addTestSuite(ParameterizedTypeFromArrayTest.class);
+      //$JUnit-END$
+      return suite;
+   }
+
+}

Modified: projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AssignabilityAlgorithmTest.java
===================================================================
--- projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AssignabilityAlgorithmTest.java	2007-07-06 02:36:30 UTC (rev 63854)
+++ projects/aop/trunk/aop/src/test/org/jboss/test/aop/unit/assignability/AssignabilityAlgorithmTest.java	2007-07-06 04:45:28 UTC (rev 63855)
@@ -21,16 +21,10 @@
  */
 package org.jboss.test.aop.unit.assignability;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import junit.framework.TestCase;
 
-import org.jboss.aop.advice.annotation.Algorithm;
-import org.jboss.aop.advice.annotation.VariableNode;
+import org.jboss.aop.advice.annotation.assignability.Algorithm;
+import org.jboss.aop.advice.annotation.assignability.VariableHierarchy;
 
 /**
  * 
@@ -41,7 +35,7 @@
 {
 
    protected Algorithm algorithm;
-   protected Map<String, VariableNode> hierarchy;
+   protected VariableHierarchy hierarchy;
 
    /**
     * 
@@ -53,7 +47,7 @@
 
    public void setUp()
    {
-      algorithm = Algorithm.getInstance();
-      hierarchy = algorithm.getInitialHierarchy();
+      algorithm = Algorithm.VARIABLE_TARGET;
+      hierarchy = new VariableHierarchy();
    }
 }
\ No newline at end of file




More information about the jboss-cvs-commits mailing list