[jboss-cvs] JBossAS SVN: r68604 - in projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint: graph and 7 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jan 3 14:07:18 EST 2008


Author: flavia.rainone at jboss.com
Date: 2008-01-03 14:07:18 -0500 (Thu, 03 Jan 2008)
New Revision: 68604

Added:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRange.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/KeyPart.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotCollection.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystem.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/Flags.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/SearchKey.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImpl.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoader.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElement.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Comparable.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparableFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithm.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndState.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResult.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStart.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartState.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Index.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRange.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestriction.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Matcher.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherProfile.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherSequenceProfile.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingResult.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingState.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/PrefixFunction.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/State.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/package.html
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPart.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/KeyPartIndex.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/package.html
Log:


Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRange.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRange.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/ExtendedLengthRange.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+/**
+ * <b>Despite being public, this class is meant for internal use of the
+ * tree only.</b><p>
+ * Extends <code>LengthRange</code> by adding element length range info.
+ * <p>
+ * Every key part has a length range associated with it, that stores info about
+ * its suffixes and post-prefixes length.  If its last element is not complete,
+ * not only the key part has suffixes, as the last element also has. These
+ * suffixes are the first element of the key part suffixes. In such case, the
+ * key part needs to store its length range info and the length range info of
+ * its last element. So, this class is used by key part when its last element is
+ * incomplete.
+ * 
+ * @author Flavia Rainone
+ * @see KeyPart
+ * @see LengthRange
+ */
+public class ExtendedLengthRange extends LengthRange
+{
+   /**
+    * The length range of the last (and incomplete) element of a key part.
+    */
+   private LengthRange elementLengthRange;
+   
+   /**
+    * Construtor. Creates an instance to be associated with a specific <code>
+    * KeyPart</code> instance.
+    * 
+    * @param length              the length of the key part
+    * @param postPrefixMinLength the minimum length of the key part
+    *                            post-prefixes
+    * @param postPrefixMaxLength the maximum length of the key part
+    *                            post-prefixes
+    * @param elementLengthRange the length range of the last key part element
+    */
+   public ExtendedLengthRange(byte length, byte postPrefixMinLength,
+         byte postPrefixMaxLength, LengthRange elementLengthRange)
+   {
+      super(length, postPrefixMinLength, postPrefixMaxLength);
+      this.elementLengthRange = elementLengthRange;
+   }
+   
+   /**
+    * Returns the length range of the last (and incomplete) element of the
+    * key part associated with this length range.
+    * 
+    * @return the length range of the last (and incomplete) element of the
+    *         key part associated with this length range
+    */
+   public final LengthRange getElementLengthRange()
+   {
+      return elementLengthRange;
+   }
+   
+   /**
+    * Overwrites the superclass method because, since the key part has an
+    * incomplete last element, the length of one of its suffixes minus
+    * the correspondent post-prefix length is not equal to the key part length.
+    * <p>
+    * As the last element of the key part is not complete, the length of this
+    * key part concatenated with one of its suffixes is equal to the sum of
+    * its length with the suffix length subtracted by 1. Consequently, the
+    * difference between the suffix and the post-prefix length equals the key
+    * part length minus 1.
+    * 
+    * @return the length of the key part minus 1
+    */
+   public byte getPostPrefix_SuffixDiff()
+   {
+      return (byte) (super.getLength() - 1);
+   }
+   
+   public String toString()
+   {
+      return super.toString().substring(0, super.toString().length() - 1) + 
+         ", " + this.elementLengthRange + "]";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,117 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.aop.joinpoint.graph.tree;
+
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+
+/**
+ * Internal node of the tree, represents a prefix common to all keys inserted
+ * in this node subtree.
+ * <p>
+ * Refer to the <i>Internal Tree Structure</i> section of
+ * {@link org.jboss.aop.joinpoint.graph.tree} for more information.
+ * 
+ * @author Flavia Rainone
+ */
+class InternalNode<E> extends Node<E>
+{
+   /**
+    * The subnodes of this node.
+    */
+   private SlotCollection<Node<E>> children;
+   
+   /**
+    * Creates a new internal node.
+    * <p>
+    * This method is invoked after a node is broken into two parts (prefix and
+    * suffix) because of a key insertion.
+    * 
+    * @param keyPart       the content of this node, the prefix part of the
+    *                      broken key part
+    * @param keyPartSuffix the suffix of <code>keyPart</code>, the second part
+    *                      of the broken key part
+    * @param newSuffix     the new suffix of this node key part represents a key
+    *                      that is being inserted in the tree.
+    */
+   public InternalNode(KeyPart keyPart, Node<E> keyPartSuffix, Node<E> newSuffix)
+   {
+      super(keyPart);
+      keyPart.newSuffix(newSuffix.keyPart);
+      children = new SlotCollection<Node<E>>(keyPartSuffix,
+            keyPartSuffix.getIdentifier(), newSuffix,
+            newSuffix.getIdentifier());
+   }
+   
+   /**
+    * Inserts <code>value</code>, identified by <code>insertionKey</code>, in
+    * one of the child nodes.
+    */
+   protected Node<E> internalInsert(InsertionKey insertionKey, E value)
+   {
+      char nextChar = insertionKey.getNextChar();
+      if (nextChar == InsertionKey.INSERTION_COMPLETE)
+      {
+         nextChar = KeyPart.KEY_ELEMENT_END;
+      }
+      children.loadSlot(nextChar);
+      if (!children.isSlotEmpty())
+      {
+         Node<E> child = children.getSlotContent();
+         child = child.insert(insertionKey, value);
+         children.replaceSlotContent(child);
+         keyPart.newSuffix(child.keyPart);
+         
+      }
+      else
+      {
+         Node<E> newNode = new LeafNode<E>(insertionKey.toKeyPart(), value); 
+         children.fillSlot(newNode);
+         keyPart.newSuffix(newNode.keyPart);
+      }
+      return this;
+   }
+   
+   public void search(Collection<E> result, SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      //Collection result = new ArrayList();
+      if (nextChar == Flags.ALL)
+      {
+         Object[] all = children.getAllContents();
+         SearchKey wildcardSearchKey = searchKey.getWildcardInstance();
+         for (int i = 0; i < all.length; i++)
+         {
+            searchKey.prepareWildcardInstance(wildcardSearchKey);
+            // TODO refazer isso... força a criação de várias coleções...
+            // sugestão: colocar em Tree uma coleção e passá-la como
+            // argumento para os métodos search... uma coleção que pertence
+            // à Tree e que será sempre resetada, e não recriada.
+            /*result.addAll(*/((Node<E>) all[i]).search(result, wildcardSearchKey)/*)*/;
+         }
+      }
+      else if (nextChar != Flags.POSITIVE && nextChar != Flags.NEGATIVE)
+      {
+         children.loadSlot(nextChar);
+         if (!children.isSlotEmpty())
+         {
+            /*return */children.getSlotContent().search(result, searchKey);
+         }
+      }
+      //return result;
+   }
+   
+   public String toString()
+   {
+      return "(" + this.keyPart + ", " + this.children + ")";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/KeyPart.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/KeyPart.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/KeyPart.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,399 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+
+/**
+ * <b>Despite being public, this class is meant for internal use of the
+ * tree only.</b><p>
+ * This class represents a part of a key contained in the tree.
+ * <p>
+ * Each tree node contains a key part. For more details, refer to the <i>
+ * Internal Tree Structure</i> section in {@link org.jboss.aop.joinpoint.graph.tree}.
+ * 
+ * @author Flavia Rainone
+ * @see Tree
+ * @see org.jboss.aop.joinpoint.graph.tree
+ */
+public class KeyPart
+{
+   /**
+    * Empty key end, represents the end of a key.
+    * Used in cases where a key is a prefix of another one.
+    */
+   public static KeyPart EMPTY_KEY_END = new KeyPart(new String[0]);
+   
+   /**
+    * Indicates the end of an element, utilized to identify key parts whose
+    * first element is an empty string and to identify <code>
+    * EMPTY_KEY_END</code>.
+    */
+   public static final char KEY_ELEMENT_END = '#';
+   
+   /** Contains elements of a key. */
+   private String[] keyElements;
+  
+   /**
+    * Indicates if the last element of <code>keyElements</code> is complete
+    * or is splitten.<p>
+    * If this value is </code>false</code>, there are more than one possible
+    * suffixes to this element on the tree. The possible endings of the last
+    * element can be found in the subnodes of the node containing this key part.
+    */
+   private boolean lastElementComplete;
+   
+   /**
+    * The maximum-minimum range of this key part suffixes and post-prefixes.
+    * 
+    * @see LengthRange
+    * @see ExtendedLengthRange
+    */
+   private LengthRange lengthRange;
+   
+   /**
+    * Constructor. Creates a key part that contains <code>
+    * keyPartExpression</code>.
+    * @param keyPartExpression the element that will be represented by the
+    *                          instance created. This element is allowed to
+    *                          contain any valid Java class name character,
+    *                          besides the element separator char <code>'.'
+    *                          </code>. Should never end with <code>'.'</code>.
+    *                          TODO (new: nor even should it
+    * be an empty string? right?)
+    */
+   public KeyPart(String keyPartExpression)
+   {
+      // splits the key into keyElements
+      Collection keyElements = new ArrayList();
+      // split element
+      int begin = 0;
+      int end = keyPartExpression.indexOf('.');
+      while(end >= 0)
+      {
+         keyElements.add(keyPartExpression.substring(begin, end));   
+         begin = end + 1;
+         end = keyPartExpression.indexOf('.', begin + 1);
+      }
+      if (begin >= 0)
+      {
+         keyElements.add(keyPartExpression.substring(begin));
+      }
+      // initialize fields
+      this.keyElements = new String[keyElements.size()];
+      this.keyElements = (String[]) keyElements.toArray(this.keyElements);
+      this.lastElementComplete = true;
+      this.lengthRange = new
+         LengthRange((byte) this.keyElements.length,
+                     (byte) this.keyElements.length);
+   }
+   
+   /**
+    * Private constructor, for internal use only.
+    * 
+    * @param keyElements         the elements of the key part.
+    * @param lastElementComplete indicates if the last element is complete. If
+    *                            it is not, then there are more than one
+    *                            possible endings to this last element in the
+    *                            tree. These endings can be found on the
+    *                            subnodes of the node that will contain the
+    *                            instance to be created.
+    * @param suffixPart          the unique suffix of the key part to be
+    *                            created.
+    */
+   private KeyPart(String[] keyElements, boolean lastElementComplete,
+         KeyPart suffixPart)
+   {
+      // initialize elements data
+      this.keyElements = keyElements;
+      this.lastElementComplete = lastElementComplete;
+      
+      // initialize length range
+      byte ppMinLength = (byte) (keyElements.length +
+            suffixPart.lengthRange.getPostPrefixMinLength());
+      byte ppMaxLength = (byte) (keyElements.length +
+            suffixPart.lengthRange.getPostPrefixMaxLength());
+      this.lengthRange = lastElementComplete? new LengthRange(
+            (byte) keyElements.length, ppMinLength, ppMaxLength):
+          new ExtendedLengthRange((byte) keyElements.length,
+                (byte) (ppMinLength - 1),  (byte) (ppMaxLength - 1),
+                createElementLengthRange(suffixPart));
+   }
+   
+   /**
+    * Private constructor, for internal use only.
+    * 
+    * @param keyElements the elements of the key part
+    */
+   private KeyPart(String[] keyElements)
+   {
+      this.keyElements = keyElements;
+      this.lastElementComplete = true;
+      this.lengthRange = new LengthRange((byte) keyElements.length,
+            (byte) keyElements.length);
+   }
+  
+   /**
+    * Returns the first character contained in this key part. It is used by
+    * internal nodes for sub nodes identification.
+    * 
+    * @return the first character of the first key element. May return <code>
+    *         KeyPart.KEY_ELEMENT_END</code> if the first element is empty,
+    *         which means that this <code>KeyPart</code> determines the end of a
+    *         key (<code>EMPTY_KEY_END</code>), or that it starts with the end
+    *         of the last element of the <code>KeyPart</code> contained in the
+    *         super node.
+    */
+   public char getFirstCharacter()
+   {
+      if (keyElements.length == 0 || keyElements[0].length() == 0)
+      {
+         return KeyPart.KEY_ELEMENT_END;
+      }
+      return keyElements[0].charAt(0);
+   }
+   
+   /**
+    * Returns the key elements of this key part.
+    * 
+    * @return the key elements array.
+    */
+   public String[] getKeyElements()
+   {
+      return this.keyElements;
+   }
+   
+   /**
+    * Indicates if the last element is complete. If it is not, then there are
+    * more than one possible ending to the last element. These endings can be
+    * found in the subnodes of the node carrying this key part instance.
+    * 
+    * @return <code>true</code> if the last element is complete.
+    */
+   public boolean isLastElementComplete()
+   {
+      return this.lastElementComplete;
+   }
+   
+   /**
+    * Returns the minimum-maximum range of the length of the suffixes and
+    * post-prefixes of this key part.
+    * 
+    * @return the minimum-maximum range of the length of the suffixes and
+    *         post-prefixes of this key part. May be a {@link
+    *         ExtendedLengthRange} instance if <code>lastElementComplete</code>
+    *         is <code>false</code>.
+    *         
+    * @see LengthRange
+    * @see ExtendedLengthRange
+    */
+   public LengthRange getLengthRange()
+   {
+      return lengthRange;
+   }
+   
+   /**
+    * Notifies this key part that a new suffix was added to it.
+    * <p>
+    * This method updates the length range data accordingly.
+    * 
+    * @param newSuffix the new suffix of this key part.
+    */
+   public void newSuffix(KeyPart newSuffix)
+   {
+      LengthRange suffixLengthRange = newSuffix.getLengthRange();
+      // update length range
+      byte diff = lastElementComplete? (byte) 0: (byte) 1;
+      byte ppMinLength = (byte) (suffixLengthRange.getPostPrefixMinLength() +
+                                 this.lengthRange.getLength() - diff);
+      byte ppMaxLength = (byte) (suffixLengthRange.getPostPrefixMaxLength() +
+                                 this.lengthRange.getLength() - diff);
+      this.lengthRange.update(ppMinLength, ppMaxLength);
+      
+      if (!this.lastElementComplete)
+      {
+         // update element length range
+         LengthRange elementLengthRange = ((ExtendedLengthRange) lengthRange).
+                  getElementLengthRange();
+         byte[] lengthRange = getElementLengthRange(newSuffix);
+         if (lengthRange.length == 2)
+         {
+            elementLengthRange.update(lengthRange[1]);
+         }
+         else
+         {
+            elementLengthRange.update(lengthRange[1], lengthRange[2]);
+         }
+      }
+   }
+      
+   /**
+    * Extracts a prefix part of this part.
+    * <p>
+    * After this method executes, this key part will contain only the remainder
+    * key part suffix.
+    * 
+    * @param element     the element index. The prefix will be extracted from
+    *                    the first element until the one identified by this
+    *                    index.
+    * @param elementChar the element char index, identifies until which char
+    *                    of <code>element</code> the prefix will be extracted.
+    * @return the extracted prefix.
+    */
+   public KeyPart extractPrefixPart(int element, int elementChar)
+   {
+      if (element == 0 && elementChar == 0)
+      {
+         String[] emptyElement = new String[1];
+         emptyElement[0] = "";
+         return new KeyPart(new String[]{""}, false, this);
+      }
+      String[] oldKeyElements = keyElements;
+      boolean oldLastElementComplete = lastElementComplete;
+      String[] extractedKeyElements = (elementChar == 0)?
+            new String[element]: new String[element + 1];;
+      boolean extractedLastElementComplete;
+            
+      for (int j = 0; j < element; j++)
+      {
+         extractedKeyElements[j] = oldKeyElements[j];
+      }
+      this.keyElements = new String[oldKeyElements.length - element];
+      int startIndex = 0;
+      if (elementChar > 0)
+      {
+         extractedKeyElements[element] =
+            oldKeyElements[element].substring(0, elementChar);
+         extractedLastElementComplete = false;
+         this.keyElements[0] = oldKeyElements[element].substring(elementChar);
+         startIndex ++;
+      }
+      else
+      {
+         extractedLastElementComplete = true;
+      }
+      for (int i = startIndex; i < keyElements.length; i++)
+      {
+         keyElements[i] = oldKeyElements[element + i];
+      }
+      
+      byte lengthDiff = (byte) (this.lengthRange.getLength() -
+            keyElements.length);
+      byte postPrefixMinLength = (byte)
+         (this.lengthRange.getPostPrefixMinLength() - lengthDiff);
+      byte postPrefixMaxLength = (byte)
+         (this.lengthRange.getPostPrefixMaxLength() - lengthDiff); 
+      this.lengthRange.reset((byte) keyElements.length, postPrefixMinLength,
+            postPrefixMaxLength);
+      
+      if (!lastElementComplete && element == (oldKeyElements.length - 1))
+      {
+         // element length range affected
+         LengthRange elementLengthRange = ((ExtendedLengthRange) lengthRange).
+            getElementLengthRange();
+         postPrefixMinLength = (byte) (
+               elementLengthRange.getPostPrefixMinLength() - elementChar);
+         postPrefixMaxLength = (byte) (
+               elementLengthRange.getPostPrefixMaxLength() - elementChar);
+         elementLengthRange.reset( (byte)
+               this.keyElements[this.keyElements.length - 1].length(),
+               postPrefixMinLength, postPrefixMaxLength);
+      }                           
+
+      return new
+         KeyPart(extractedKeyElements, extractedLastElementComplete, this);
+   }
+   
+   /**
+    * Creates an element length range for the unique suffix of this part.
+    * <p>
+    * Is called only when <code>lastElementComplete</code> equals false.
+    * 
+    * @param suffixPart the unique suffix of this part
+    * @return the element length range of this part
+    */
+   private LengthRange createElementLengthRange(KeyPart suffixPart)
+   {
+      byte[] lengthRange = getElementLengthRange(suffixPart);
+      if (lengthRange.length == 2)
+         return new LengthRange(lengthRange[0], lengthRange[1]);
+      return new LengthRange(lengthRange[0], lengthRange[1], lengthRange[2]);
+   }
+
+   /**
+    * Returns the element length range data for <code>suffixPart</code>. This
+    * data is calculated based on <code>suffixPart</code> only, so other
+    * suffixes are not considered in the calculation.
+    * <p>
+    * This method is called only when there is an element length range, i.e.,
+    * when <code>lastElementComplete</code> is <code>false</code>.
+    * 
+    * @param suffixPart the suffix that will be used for the element length
+    *                   range calculation
+    * @return a byte array composed of two or three values. The first one is the
+    *         length of the element. When there are two values, the second one
+    *         is the new post-prefix length. If three values are returned, the 
+    *         second and third ones are the minimum and maximum post-prefix
+    *         length, respectively. Three values are returned only when <code>
+    *         suffixPart</code> represents more than one element suffix.
+    */
+   private byte[] getElementLengthRange(KeyPart suffixPart)
+   {
+      byte length = (byte)
+         this.keyElements[this.keyElements.length - 1].length();
+      // if suffix part represents more than one element suffix...
+      if (suffixPart.getKeyElements().length == 1 &&
+            !suffixPart.isLastElementComplete())
+      {  
+         // calculate minimum and maximum post prefix length
+         LengthRange newElementLR = ((ExtendedLengthRange)
+               suffixPart.getLengthRange()).getElementLengthRange();
+         byte ppMinLength = (byte) (newElementLR.getPostPrefixMinLength()
+               + length);
+         byte ppMaxLength = (byte) (newElementLR.getPostPrefixMaxLength()
+               + length);
+         return new byte[] {length, ppMinLength, ppMaxLength};
+      }
+
+      // calculate the unique post prefix length otherwise
+      return new byte[] {length,
+            // notice that the 0 element may not exist if newSuffix is
+            // EMPTY_KEY_END, but an EMPTY_KEY_END is always preceeded by
+            // lastElementComplete true values
+            (byte) (suffixPart.getKeyElements()[0].length() + length)};
+   }
+   
+   public String toString()
+   {
+      String result = "[";
+      for (int i = 0; i < keyElements.length; i++)
+      {
+         result += "\"" + keyElements[i] + "\", ";
+      }
+      result += this.lastElementComplete + "]";
+      return result;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+
+/**
+ * Leaf node of the tree, represents a unique key in the tree and contains the
+ * value identified by this key.
+ * <p>
+ * Refer to the <i>Internal Tree Structure</i> section of
+ * {@link org.jboss.aop.joinpoint.graph.tree} for more information.
+ * 
+ * 
+ * @author Flavia Rainone
+ * @see Node
+ * @see Tree
+ */
+class LeafNode<E> extends Node<E>
+{
+   /**
+    * The value contained in this leaf.
+    */
+   private E value;
+   
+   /**
+    * Constructor. Creates a node representing a unique key in the tree, and
+    * containing the value identified by this key.
+    * 
+    * @param keyPart the part of the key that is uncommon to the other keys
+    *                in the tree.
+    * @param value   the value identified by the key.
+    */
+   public LeafNode(KeyPart keyPart, E value)
+   {
+      super(keyPart);
+      this.value = value;
+   }
+
+   /**
+    * Proceeds insertion when this leaf represents a key that is a prefix
+    * of or equal to the key to be inserted in the tree.
+    */
+   public Node<E> internalInsert(InsertionKey insertionKey, E value)
+   {
+      // if this leaf represents a key different from the key to be inserted...
+      if (insertionKey.getNextChar() != InsertionKey.INSERTION_COMPLETE)
+      {
+         // creates a new leaf for the insertion key
+         Node leafNode = new LeafNode<E>(insertionKey.toKeyPart(), value);
+         // this leaf will contain only an empty key end
+         KeyPart fatherKeyPart = this.keyPart;
+         this.keyPart = KeyPart.EMPTY_KEY_END; // TODO this may generate more than one EMPTY KEY PART in a row... is this a problem?
+         fatherKeyPart.newSuffix(this.keyPart);// TODO is this necessary?
+         Node<E> newNode = new InternalNode<E>(fatherKeyPart, this, leafNode);
+         return newNode;
+      }
+      // if this leaf  represents a key equal to the key to be inserted...
+      // just redefine value
+      this.value = value;
+      return this;
+   }
+
+   public void search(Collection<E> result, SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      //Collection result = new ArrayList();
+      if (nextChar == Flags.POSITIVE)
+      {
+         result.add(value);
+      }
+      //return result;
+   }
+   
+   public String toString()
+   {
+      return "(" + this.keyPart + ", " + this.value + ")";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+
+/**
+ * Represents a node of the tree, and provides insertion and search
+ * functionality.
+ * Every node can be seen as the root of a subtree.
+ * 
+ * @author Flavia Rainone
+ * @see Tree
+ */
+abstract class Node<E>
+{
+   /**
+    * The contents of the node.
+    */
+   protected KeyPart keyPart;
+   
+   /**
+    * Constructor.
+    * 
+    * @param keyPart the key part to be contained in the created node.
+    */
+   public Node(KeyPart keyPart) {
+      this.keyPart = keyPart;
+   }
+   
+   /**
+    * Searchs by <code>searchKey<code> on this node subtree.
+    * 
+    * @param searchKey represents a search element
+    * @return a <code>Collection</code> of the objects identified by the keys
+    *         matched by the search key
+    */
+   public abstract void search(Collection<E> result, SearchKey searchKey);
+   
+   /**
+    * Returns the identifier char of this node.
+    * 
+    * @return the char that identifies this node
+    */
+   public char getIdentifier()
+   {
+      return keyPart.getFirstCharacter();
+   }
+   
+   /**
+    * Insert <code>value</code> in the tree, identified by the key <code>
+    * insertionKey</code>.
+    * 
+    * @param insertionKey the key that identifies <code>value</code>, provides
+    *                     insertion mechanisms for the tree
+    * @param value        the object to be inserted in the tree
+    * @return as the insertion may afect the node subtree structure,
+    *         returns the new subtree root after insertion.
+    */
+   public Node<E> insert(InsertionKey insertionKey, E value)
+   {
+      // if the whole key part is a prefix of insertion key...
+      KeyPart commonKeyPart = insertionKey.extractCommonPrefix(this.keyPart);
+      if (commonKeyPart == this.keyPart)
+      {  // proceed according to the node type
+         return internalInsert(insertionKey, value);
+      }
+      // otherwise, create a leaf with the insertion key unmatched part
+      Node<E> leafNode = new LeafNode<E>(insertionKey.toKeyPart(), value);
+      // and create a new internal node, containing the common prefix as
+      // its data, and this node and the created node as contents
+      Node<E> newNode = new InternalNode<E>(commonKeyPart, this, leafNode);
+      return newNode;
+   }
+   
+   /**
+    * Performs the insertion of <code>value</code> in this node subtree.
+    * <p>
+    * Is called whenever the node contents represent a prefix of <code>
+    * insertionKey</code>.
+    * 
+    * @param insertionKey the key that identifies <code>value</code>, provides
+    *                     insertion mechanisms for the tree
+    * @param value        the object to be inserted in the tree
+    * @return as the insertion may afect the node subtree structure,
+    *         returns the new subtree root after insertion.
+    */
+   protected abstract Node<E> internalInsert(InsertionKey insertionKey,
+         E value);
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotCollection.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotCollection.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotCollection.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,193 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+/**
+ * Represents a collection of slots.<p>
+ * Each slot is identified by a unicode character (all characters with values
+ * bigger than <code>'"'</code> have a slot available).
+ * A slot may be empty or not. When it is empty, it can be filled with content,
+ * but the reverse is not true. On the other hand, a filled slot can have its
+ * content replaced.
+ *  
+ * @author Flavia Rainone
+ */
+class SlotCollection<E>
+{
+   /**
+    * SlotFlagSystem that indicates whether a slot is empty.
+    */
+   SlotFlagSystem flagSystem;
+   
+   /**
+    * The contents vector, its size is exatcly the number of filled slots.
+    */
+   Object[] contents;
+   
+   /**
+    * The index of a filled slot.
+    */
+   int slotIndex;
+   
+   /**
+    * Constructs a collection with only two slots occupied: the one identified
+    * by <code>id1</code>, filled with <code>content1</code>; and the one
+    * identified by <code>id2</code>, filled with <code>content2</code>.
+    * 
+    * @param content1 one of the contents to be inserted in the created
+    *                 collection
+    * @param id1      identifies the slot in which <code>content1</code> will be
+    *                 placed.
+    * @param content2 one of the contents to be inserted in the created
+    *                 collection
+    * @param id2      identifies the slot in which <code>content2</code> will be
+    *                 placed.
+    */
+   public SlotCollection(E content1, char id1, E content2, char id2)
+   {
+      flagSystem = new SlotFlagSystem(id1, id2);
+      contents = new Object[2];
+      if (id1 < id2)
+      {
+         this.contents[0] = content1;
+         this.contents[1] = content2;
+      }
+      else
+      {
+         this.contents[0] = content2;
+         this.contents[1] = content1;
+      }
+   }
+   
+   /**
+    * Loads the slot identified by <code>identifier</code>.
+    * <p>
+    * This operation must be executed before any other operation on a slot.
+    * 
+    * @param identifier the identifier char of the slot to be loaded
+    * @see #isSlotEmpty()
+    * @see #fillSlot(Object)
+    * @see #getSlotContent()
+    * @see #replaceSlotContent(Object)
+    */
+   public final void loadSlot(char identifier)
+   {
+      flagSystem.loadFlag(identifier);
+   }
+   
+   /**
+    * Indicates whether the loaded slot is empty (load a slot by calling
+    * {@link #loadSlot(char)}).
+    * 
+    * @return <code>true</code> if the loaded slot is empty; false otherwise
+    * @see #loadSlot(char)
+    */
+   public final boolean isSlotEmpty()
+   {
+      return !flagSystem.getFlagValue();
+   }
+   
+   /**
+    * Returns the content of the slot that is loaded (load a slot by
+    * calling {@link #loadSlot(char)}).
+    * <p>
+    * This method can be called only if the slot is not empty.
+    * 
+    * @return the content of the loaded slot.
+    * @see #loadSlot(char)
+    * @see #isSlotEmpty()
+    */
+   public final E getSlotContent()
+   {
+      slotIndex = flagSystem.calculateFlagIndex();
+      return (E) contents[slotIndex];
+   }
+   
+   /**
+    * Fills the loaded slot (load a slot by calling {@link #loadSlot(char)})
+    * with <code>content</code>.<p>
+    * This method mustn't be called if the loaded slot is not empty, or the
+    * collection will enter an inconsistent state. To redefine the content
+    * of a not empty slot, refer to {@link #replaceSlotContent(Object)}.  
+    *  
+    * @param content the content that will be used to fill the loaded slot
+    * @see #loadSlot(char)
+    * @see #isSlotEmpty()
+    */
+   public final void fillSlot(E content)
+   {
+      flagSystem.setFlagPositive();
+      slotIndex = flagSystem.calculateFlagIndex();
+      Object[] oldContents = this.contents;
+      this.contents = new Object[oldContents.length + 1];
+      for (int i = 0; i < slotIndex; i++)
+      {
+         this.contents[i] = oldContents[i];
+      }
+      this.contents[slotIndex] = content;
+      for (int i = slotIndex + 1; i < contents.length; i++)
+      {
+         this.contents[i] = oldContents[i - 1];
+      }
+   }
+   
+   /**
+    * Replaces the content of the loaded slot with <code>content</code>.
+    * <p>
+    * This method must be called only after <code>getSlotContent<code>.
+    * 
+    * @param content the content that will replace the current content of the
+    *                loaded slot.
+    * @see #getSlotContent()
+    */
+   public final void replaceSlotContent(E content)
+   {
+      contents[slotIndex] = content;
+   }
+   
+   /**
+    * Returns the contents of all not empty slots.
+    * <p>
+    * The client should not modify the returned array.
+    * 
+    * @return an array containing all contents.
+    */
+   public Object[] getAllContents()
+   {
+      return contents;
+   }
+   
+   public String toString()
+   {
+      String result = "(";
+      int i = 0;
+      if (i < contents.length)
+      {
+         result += contents[i++];
+      }
+      for (;i < contents.length; i++)
+      {
+         result += ", " + contents[i];
+      }
+      return result + ")";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystem.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystem.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SlotFlagSystem.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,300 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+/**
+ * Defines the flag system that is utilized by {@link SlotCollection}
+ * to indicate which slots are empty and which are not.
+ * <p>
+ * In this flag system, a flag is identified by a char.
+ * 
+ * @author Flavia Rainone
+ * @see SlotCollection
+ */
+class SlotFlagSystem
+{
+   /**
+    * The offset of the flags. All flags should have an identifier greater than
+    * or equal to this offset.
+    */
+   private static final char OFFSET = '#';
+   
+   /**
+    * The initial flags array size.
+    */
+   private static final byte INITIAL_FLAGS_SIZE = 6;
+   
+   /**
+    * The flags array.
+    */
+   char[] flags;
+   
+   /**
+    * Counts the number of positive flags.
+    */
+   private byte [] count;
+   
+   /**
+    * The currently loaded flag.
+    */
+   private Flag flag;
+   
+   /**
+    * Creates a flag system with <code>id1</code> and <code>id2</code> flags
+    * set to positive.
+    * 
+    * @param id1 indentifies a flag that should be set to positive
+    * @param id2 indentifies a flag that should be set to positive
+    */
+   public SlotFlagSystem(char id1, char id2)
+   {
+      // calculate flags length
+      int flagsLength = Math.max(INITIAL_FLAGS_SIZE, id1/16 + 1);
+      flagsLength = Math.max(flagsLength, id2/16 + 1);
+      // create and initialize vectors
+      this.flags = new char[flagsLength];
+      for (int i = 0; i < flagsLength; i++)
+         this.flags[i] = 0;
+      this.count = new byte[flagsLength];
+      flag = new Flag();
+      flag.initialize(id1);
+      flag.setPositive();
+      flag.initialize(id2);
+      flag.setPositive();
+   }
+   
+   /**
+    * Loads a flag identified by <code>id</code>.
+    * <p>
+    * This operation must be executed before any other operation on a flag.
+    * 
+    * @param id identifies the flag to be loaded.
+    * @see #getFlagValue()
+    * @see #setFlagPositive()
+    * @see #calculateFlagIndex()
+    */
+   public final void loadFlag(char id)
+   {
+      flag.initialize(id);
+   }
+   
+   /**
+    * Returns the value of the loaded flag (load a flag by calling {@link
+    * #loadFlag(char)}).
+    * 
+    * @return <code>true</code> only if the loaded flag is positive; <code>
+    *         false</code> otherwise.
+    * @see #loadFlag(char)
+    */
+   public final boolean getFlagValue()
+   {
+      return flag.getValue();
+   }
+   
+   /**
+    * Sets the loaded flag value as positive (load a flag by calling {@link
+    * #loadFlag(char)}).
+    * <p>
+    * Should be called only when the flag value is positive.
+    * 
+    * @see #loadFlag(char)
+    * @see #getFlagValue()
+    */
+   public final void setFlagPositive()
+   {
+      this.updateSupportedIdRange(flag.getId());
+      flag.setPositive();
+   }
+   
+   /**
+    * Calculates the index that stores the contents of the slot identified
+    * by the loaded flag (load a flag by calling {@link
+    * #loadFlag(char)}).
+    * <p>
+    * Should be called only when the flag value is positive.
+    * 
+    * @return the index that stores the contents of the slot identified
+    *         by the loaded flag
+    * @see #loadFlag(char)
+    * @see #getFlagValue()
+    * @see #setFlagPositive()
+    */
+   public final int calculateFlagIndex()
+   {
+      return flag.calculateIndex();
+   }
+   
+   /**
+    * Updates the range of ids that can be set as positive, in such a way that
+    * <code>id</code> is inside this range.
+    *  
+    * @param id the id that must be in the suported id range.
+    */
+   private final void updateSupportedIdRange(char id)
+   {
+      char maximumIdSupported = (char) (flags.length * 16 + OFFSET - 1);
+      if (id <= maximumIdSupported)
+      {
+         return;
+      }
+      int flagsNeeded = this.flags.length + (int) Math.ceil((double)
+            (id - maximumIdSupported) / 16.0);
+      char oldFlags[] = this.flags;
+      this.flags = new char[flagsNeeded];
+      for (int i = 0; i < oldFlags.length; i++)
+      {
+         this.flags[i] = oldFlags[i];
+      }
+      byte[] oldCount = this.count;
+      this.count = new byte[flagsNeeded];
+      for (int i = 0; i < oldCount.length; i++)
+      {
+         this.count[i] = oldCount[i];
+      }
+      byte newCountValue = (byte) (oldCount[oldCount.length -1] + 
+            countFlagValues(oldCount.length - 1, 16));
+      for (int i = oldCount.length; i < count.length; i++)
+      {
+         count[i] = newCountValue;
+      }
+   }
+   
+   /**
+    * Returns the number of positive flags in <code>flags[flagNumber]</code>
+    * with id smaller than <code>flagMask</code>. 
+    * 
+    * @param flagNumber identifies where are the flags to be counted
+    * @param flagMask   the upper limit mask of the flags to be counted
+    * @return the number of positive flags in <code>flags[flagNumber]</code>
+    *         with id smaller than <code>flagMask</code>
+    */
+   private final int countFlagValues(int flagNumber, int flagMask)
+   {
+      char flag = flags[flagNumber];
+      int total = 0;          
+      for (int i = 0; i < flagMask; i++)
+      {
+         if (flag % 2 == 1)
+         {
+            total ++;  
+         }
+         flag = (char) (flag >> 1);
+      }
+      return total;
+   }
+   
+   /**
+    * Represents a flag of the flag system. A flag is identified by a character
+    * and indicates if the character slot is empty or not, besides being able
+    * of calculating the index of the slot contents in an array. 
+    * 
+    * @author Flavia Rainone
+    */
+   class Flag
+   {
+      /**
+       * The number of the flag, indicates an index in the <code>flags</code>
+       * array. 
+       */
+      private int flagNumber;
+      
+      /**
+       * The mask of the flag, indicates which bit of <code>flags[flagNumber]
+       * </code>contains the value of this flag.
+       */
+      private int flagMask;
+      
+      /**
+       * The character that identifies this flag.
+       */
+      private char id;
+      
+      /**
+       * Initializes the flag with <code>id</code>. The initialization results
+       * in this flag representing the flag identifed by <code>id</code>.
+       * <p>
+       * Any operation on this flag must be called only after this flag is
+       * initialized.
+       * 
+       * @param id the id of the flag that this object will represent
+       */
+      public final void initialize(char id)
+      {
+         this.id = id;
+         id -= OFFSET;
+         this.flagNumber = id / 16;
+         this.flagMask = id % 16;//(short) Math.pow(2.0, id % 16);
+      }
+      
+      /**
+       * Returns the value of this flag.
+       * 
+       * @return the value of this flag
+       */
+      public final boolean getValue()
+      {
+         if (flagNumber >= flags.length)
+         {
+            return false;
+         }
+         return (flags[flagNumber] >> flagMask) % 2 == 1;
+      }
+      
+      /**
+       * Set this flag as positive.
+       */
+      public final void setPositive()
+      {
+         flags[flagNumber] += (char) (1 << flagMask);
+         {
+            // TODO: replace by a class whose count is int (very rare scenario)
+         }
+         for (int i = flagNumber + 1; i < count.length; i++)
+         {
+            count[i] ++;
+         }
+      }
+      
+      /**
+       * Returns the identifier of the flag that this object represents.
+       * @return the identifier of the flag that this object represents
+       */
+      public final char getId()
+      {
+         return id;
+      }
+      
+      /**
+       * Calculates the index of an array indicating where is the content
+       * of the slot represented by this flag.
+       * 
+       * @return the index of an array indicating where is the content
+       *         of the slot represented by this flag
+       */
+      private final int calculateIndex()
+      {
+         int index = countFlagValues(flagNumber, flagMask);
+         index += count[flagNumber];
+         return index;
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,177 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+
+/**
+ * A search tree, this is the unique class in this package that should be
+ * used by the client.
+ * This tree allows search using expresions with one or more wildcards.
+ * 
+ * @author Flavia Rainone
+ */
+public class Tree<E>
+{
+   /**
+    * Root of the tree.
+    */
+   private Node root;
+   
+   /**
+    * State of the tree: empty or not.
+    */
+   private State state;
+   
+   /**
+    * Constructs an empty tree.
+    */
+   public Tree()
+   {
+      this.root = null;
+      this.state = new EmptyState();
+   }
+   
+   /**
+    * Inserts <code>value</code> in the tree. This value is uniquely identified
+    * by <code>key</code>, that can contain one or more valid Java names
+    * separated by the <code>'.'</code> character. If a value was already
+    * inserted with the same key, the previous value will be overwritten.
+    * 
+    * @param key   identifies <code>value</code>. This key is used during
+    *              search. <b>Should not be an empty string.</b>
+    * @param value the object that will be inserted in the tree
+    */
+   public void insert(String key, E value)
+   {
+      InsertionKey insertionKey = new InsertionKey(key);
+      state.insert(insertionKey, value);
+   }
+   
+   /**
+    * Searches for all values whose key matches the <code>
+    * searchKeyExpresion</code>.
+    * 
+    * @param searchKeyExpression element that defines the search; may contain
+    *                            zero or more wildcards (<code>'*'</code>) to
+    *                            indicate zero or more characters in the key.
+    * @return a collection of all values whose key matches the <code>
+    *         searchKeyExpresion</code> 
+    */
+   public Collection<E> search(String searchKeyExpression)
+   {
+      SearchKey searchKey = new SearchKey(searchKeyExpression);
+      return state.search(searchKey);
+   }
+   
+   public boolean isEmpty()
+   {
+	   return this.root == null;
+   }
+   // TODO create a node method for this type of search and test it.
+   public E searchElement(String elementName)
+   {
+	   Collection<E> elements = search(elementName);
+	   if (elements.isEmpty())
+	   {
+		   return null;
+	   }
+	   if (elements.size() > 1)
+	   {
+		   throw new RuntimeException("Element name shouldn't contain wildcards:" + elementName);
+	   }
+	   return elements.iterator().next();
+   }
+   
+   /**
+    * The state of the tree, defines how the insertion and search operations
+    * should be carried out.
+    * 
+    * @author Flavia Rainone
+    *
+    */
+   interface State
+   {
+      /**
+       * Performs an insertion in the tree.
+       * @see Tree#insert(String, Object)
+       */
+      <E> void insert(InsertionKey insertionKey, E value);
+      
+      /**
+       * Performs a search in the tree.
+       * @see Tree#search(String)
+       */
+      <E> Collection<E> search(SearchKey searchKey);
+   }
+
+   /**
+    * Indicates that the tree is empty. Answers to the insertion and search
+    * operations accordingly.
+    * 
+    * @author Flavia Rainone
+    */
+   class EmptyState implements State
+   {
+      public <E> void insert(InsertionKey insertionKey, E value)
+      {
+         root = new LeafNode(insertionKey.toKeyPart(), value);
+         state = new NotEmptyState();
+         
+      }
+      public <E> Collection<E> search(SearchKey searchKey)
+      {
+         return new ArrayList<E>();
+      }
+   }   
+
+   /**
+    * Indicates that the tree is not empty. Answers to the insertion and search
+    * operations accordingly.
+    * 
+    * @author Flavia Rainone
+    */
+   class NotEmptyState implements State
+   {
+      public <E> void insert(InsertionKey insertionKey, E value)
+      {
+         root = root.insert(insertionKey, value);
+      }
+      public <E> Collection<E> search(SearchKey searchKey)
+      {
+         //return root.search(searchKey);
+    	  Collection<E> result = new ArrayList<E>();
+    	  root.search(result, searchKey);
+    	  return result;
+      }
+   }
+   
+   public String toString()
+   {
+      return "" + root;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKey.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/InsertionKey.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,202 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.aop.joinpoint.graph.tree.insertion;
+
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+
+/**
+ * Represents a key to be inserted in the tree.<p>
+ * This key is capable of providing a way of searching for each char of it in
+ * the tree, indicating whether a node contains chars common to it (
+ * {@link #extractCommonPrefix(KeyPart)}) and, if it does, which subnode should
+ * be analyzed next ({@link #getNextChar()}). This search finishes when a
+ * node that contains chars uncommon to this insertion key is found, which means
+ * that a char of the key was not found on the tree. When this happens, the
+ * unmatched part of this insertion key can be retrieved ({@link #toKeyPart()})
+ * and inserted in the tree.
+ * 
+ * @author Flavia Rainone
+ */
+public class InsertionKey
+{
+   /**
+    * Indicates that the insertion is complete.
+    */
+   public static final char INSERTION_COMPLETE = '.';
+
+   /**
+    * The key to be inserted in the tree.
+    */
+   private String key;
+   
+   /**
+    * Indicates from which index the key data wasn't found on the tree.
+    * This means that the prefix of <code>key</code> contained in the interval
+    * <code>0,keyIndex-1</code> is already in the tree.
+    */
+   private int keyIndex;
+   
+   /**
+    * Indicates if the end of the <code>key</code> was found on the tree.
+    */
+   private boolean endRead = false;
+   
+   /**
+    * Constructor.
+    * 
+    * @param key the key to be inserted in the tree.
+    */
+   public InsertionKey(String key)
+   {
+      this.key = key;
+      this.keyIndex = 0;
+   }
+   
+   /**
+    * Extracts the prefix common to <code>keyPart</code> and to this insertion
+    * key.
+    * 
+    * @param keyPart the <code>keyPart</code> that may be broken into two
+    *                parts: the prefix common to this insertion key; and the
+    *                suffix, which contains the uncommon data. If broken during
+    *                this method execution, this key part will contain the
+    *                uncommon suffix only.
+    * @return the extracted common prefix, or <code>keyPart</code> itself if
+    *         it is a prefix of this insertion key.
+    */
+   public KeyPart extractCommonPrefix(KeyPart keyPart)
+   {
+      if (keyPart == KeyPart.EMPTY_KEY_END && endRead)
+      {
+         // this insertion key is already in the tree
+         return keyPart;
+      }
+      
+      String[] keyElements = keyPart.getKeyElements();
+      int element;
+      int i = 0;
+      // compares insertion key with elements until the key elements end or
+      // the insertion key end is reached
+      elementLoop:
+         for (element = 0; element < keyElements.length && !endRead; element++)
+      {
+         for (i = 0; i < keyElements[element].length(); i++)
+         {
+            // no more insertion key chars to compare...
+            if (keyIndex == key.length())
+            {
+               break elementLoop;
+            }
+            // a mismatch is found
+            if (keyElements[element].charAt(i) != key.charAt(keyIndex))
+            {
+               break elementLoop;
+            }
+            keyIndex ++;
+         }
+         // look for the '.' that separates the elements from one another
+         if (keyIndex < key.length())
+         {
+            if (key.charAt(keyIndex) != '.')
+            {
+               break;
+            }
+         }
+         // the end is reached
+         else
+         {
+            endRead = true;
+         }
+         i = 0;
+         keyIndex ++;
+      }
+      // extracts the common prefix part...
+      if (element < keyElements.length)
+      {
+         // if the common prefix isn't keyPart
+         if (element == (keyElements.length - 1) &&
+               i == keyElements[element].length() &&
+               !keyPart.isLastElementComplete())
+         {
+            return keyPart;
+         }
+         return keyPart.extractPrefixPart(element, i);
+      }
+      //(element == keyElements.length)
+      if (!keyPart.isLastElementComplete())
+      {
+         // the last element wasn't complete, so...
+         // ... the '.' found on the end of the loop needs to be reconsidered
+         keyIndex--;
+         // ... or the end read needs to be reconsidered
+         endRead = false;
+      }
+      return keyPart;
+   }
+   
+   /**
+    * Returns the next char of the key to be searched on the tree.
+    * 
+    * @return the next char of the key to be searched on the tree. May be <code>
+    *         INSERTION_COMPLETE</code> to indicate that the insertion is
+    *         already complete (because the whole insertion key is already
+    *         contained in the tree). May return </code>KEY_ELEMENT_END</code>
+    *         to indicate that the end of the element of the previous processed
+    *         <code>keyPart</code> is what should be searched for in the tree.
+    */
+   public char getNextChar()
+   {
+      if (keyIndex >= key.length())
+      {
+         if (endRead)
+         {
+            return INSERTION_COMPLETE;
+         }
+         return KeyPart.KEY_ELEMENT_END;
+      }
+      char nextChar = key.charAt(keyIndex);
+      if (nextChar == '.')
+      {
+         return KeyPart.KEY_ELEMENT_END;
+      }
+      return nextChar;
+   }
+   
+   /**
+    * Transforms the unmatched part of this key into a key part, to be inserted
+    * in the tree.
+    * <p>
+    * Should be called when <code>extractCommonPrefix</code> returns something
+    * different from its <code>keyPart</code> parameter value.
+    *  
+    * @return a key part containing the unmatched part of this insertion key
+    */
+   public KeyPart toKeyPart()
+   {
+      if (endRead)
+      {
+         return KeyPart.EMPTY_KEY_END;
+      }
+      return new KeyPart(key.substring(keyIndex));
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/insertion/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,34 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Provides the tree insertion mechanism.
+
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.insertion.InsertionKey
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,58 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Provides a search tree.
+
+<h2>Package Specification</h2>
+<p>
+This tree stores objects identified by a key, composed of expressions separated
+by the '.' character, and allows the search with expressions containing
+wildcards ('*').
+</p>
+<p>
+The key stored in the tree may contain any valid java name character, which
+includes a bundle of special characters, like the chinese ones, for example.
+</p>
+
+<h2>Internal Tree Structure</h2>
+<p>
+Every key inserted in the tree is broken into parts according to the common
+prefixes of the keys contained in the tree. This way, each internal node
+contains a <i>key part</i>, that represents the prefix common to all keys
+inserted in the internal node subtree. Each leaf contains the part of a key
+that is uncommon to all other keys and identifies this key as unique in
+the tree (this uncommon part is the result of subtracting from the key the
+longest prefix that is common to another key in the tree). Henceforth, a leaf
+represents a key, whose value can be retrieved by concatenating the contents of
+the nodes in the path from the root to the leaf.
+</p>
+
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.Tree
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/Flags.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/Flags.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/Flags.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,27 @@
+package org.jboss.aop.joinpoint.graph.tree.search;
+
+/**
+ * Defines characters with special meanings that can be returned from the
+ * <code>SearchKey.matches</code> method.
+ * 
+ * @author Flavia Rainone
+ * @see SearchKey#matches(org.jboss.aop.joinpoint.graph.tree.KeyPart)
+ */
+public class Flags
+{
+   /**
+    * Indicates that no character identifies a possible positive matching, i.e.,
+    * any character could take the matching to a positive result.
+    */
+   public static final char ALL = '*';
+   
+   /**
+    * Indicates that the search is finished with a positive result.
+    */
+   public static final char POSITIVE = '+';
+   
+   /**
+    * Indicates that the search is finished with a negative result.
+    */
+   public static final char NEGATIVE = '-';
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/SearchKey.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/SearchKey.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/SearchKey.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search;
+
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Matcher;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPartFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.part.KeyPartIndex;
+
+
+/**
+ * A search key is meant to execute a macthing against a {@link
+ * org.jboss.aop.joinpoint.graph.tree.KeyPart key part}.
+ * <p>
+ * This matching process can be executed until {@link Flags#ALL} is returned. In
+ * this case, to continue the process against the subsequent key parts (in order
+ * to  continue the search process throughout a tree) it is necessary to ask
+ * for the wildcard search key instance ({@link #getWildcardInstance()}).
+ * 
+ * @author Flavia Rainone
+ */
+public class SearchKey
+{
+   /**
+    * The search key part matchers.
+    */
+   private Matcher[] partMatchers;
+   
+   /**
+    * Points to the current matcher (the one responsible for matching the
+    * next key part).
+    */
+   private int index;
+   
+   /**
+    * Contains the comparableIndex of the current matcher.
+    */
+   private KeyPartIndex comparableIndex;
+   
+   /**
+    * Contains the index of the next target.
+    */
+   private KeyPartIndex targetIndex;
+      
+   /**
+    * The state of the matching process.
+    */
+   private MatchingState state;
+   
+   /**
+    * The wildcard instance associated with this search key.
+    */
+   private SearchKey wildcardSearchKey;
+   
+   /**
+    * Constructor.
+    * 
+    * @param searchExpression a search element. This element is allowed to
+    *                         contain wildcards (<code>'*'</code>) besides any
+    *                         character contained in a valid java class name.
+    */
+   public SearchKey (String searchExpression)
+   {
+      ComparableKeyPartFactory factory = ComparableKeyPartFactory.getInstance();
+      this.partMatchers = MatcherFactory.createSequence(searchExpression,
+            factory, factory.getMatcherSequenceProfile());
+      index = 0;
+      comparableIndex = new KeyPartIndex();
+      targetIndex = new KeyPartIndex();
+      state = new MatchingState(new MatchingState());
+   }
+   
+   /**
+    * Private constructor.
+    * <p>
+    * Creates an empty search key.
+    */
+   private SearchKey()
+   {
+      this.comparableIndex = new KeyPartIndex();
+      this.targetIndex = new KeyPartIndex();
+      this.state = new MatchingState(new MatchingState());
+   }
+      
+   /**
+    * Matches this <code>SearchKey</code> content against <code>keyPart</code>.
+    * <p>
+    * In order to know exactly what will be matched it is necessary to notice
+    * that this <code>SearchKey</code> is resultant of previous comparisons made
+    * before, i.e., the matching will start at the exact search key expression
+    * point where the last matching process stopped in the previous matching.
+    * <p>
+    * 
+    * @param keyPart the <code>KeyPart</code> whose content will be compared to
+    *                the search key. It is the content of a tree node.
+    * @return <code>Flags.NEGATIVE</code> if the matching is negative. If the
+    *         matching is partially positive, returns the next character needed
+    *         by a successful search. The return value may be <code>
+    *         Flags.ALL</code> if there is no character that specifies a
+    *         possible positive match (in this case, this matcher cannot execute
+    *         the next matching, the {@link #getWildcardInstance() wildcard
+    *         search key} should do so). And returns <code>Flags.POSITIVE
+    *         </code> if the matching process finished succesfuly with a
+    *         positive result.
+    * @see Flags
+    */
+   public char matches(KeyPart keyPart)
+   {
+      // the initial index of key part
+      MatchingResult result = partMatchers[index].matches(keyPart,
+            keyPart.getLengthRange(), targetIndex, comparableIndex, state);
+      while (result == MatchingResult.POSITIVE_MATCH &&
+            ++ index < partMatchers.length)
+      {
+         comparableIndex.reset();
+         result = partMatchers[index].matches(keyPart, keyPart.getLengthRange(),
+               targetIndex, comparableIndex, state);
+      }
+      if (result == MatchingResult.NEGATIVE_MATCH)
+      {
+         return Flags.NEGATIVE;
+      }
+      if (index == partMatchers.length &&
+            result == MatchingResult.POSITIVE_MATCH)
+      {
+         if (keyPart.getLengthRange().getSuffixMaxLength() == 0)
+         {
+            return Flags.POSITIVE;
+         }
+         index--;
+      }
+      char nextChar = partMatchers[index].getNextCharacter(comparableIndex,
+            keyPart, keyPart.getLengthRange(), state);
+      //this.createNextSearchKey = (nextChar == '*');
+      targetIndex.update(keyPart.getLengthRange());
+      return nextChar;
+   }
+   
+   /**
+    * Returns the wildcard instance.
+    * <p>
+    * This method should be called when {@link #matches(KeyPart)} returns {@link
+    * Flags#ALL}. Once all subnodes of the current node will need to be
+    * searched, this instance is no longer appropriate. Instead, the client
+    * should search the subnodes using the wildcard instance.
+    * 
+    * @return the wildcard instance. This search key must be {@link
+    *         #prepareWildcardInstance prepared} before each time it is used
+    *         to search in a subnode. And it must not perform the searches
+    *         concurrently.
+    */
+   public SearchKey getWildcardInstance()
+   {
+      if (this.wildcardSearchKey == null)
+      {
+         this.wildcardSearchKey = new SearchKey();
+      }
+      return this.wildcardSearchKey;
+   }
+
+   /**
+    * Prepares the wildcard instance for doing a search.
+    * This method must be invoked before searching in each subnode of the last
+    * searched node (the one with a <code>Flags.ALL</code> result).
+    * 
+    * @param wildcardInstance the wildcard instance, must be the same returned
+    *                         by <code>getWildcardInstance</cocde>
+    * @see #getWildcardInstance()
+    */
+   public void prepareWildcardInstance(SearchKey wildcardInstance)
+   {
+      wildcardInstance.partMatchers = this.partMatchers; 
+      wildcardInstance.index = this.index;
+      //wildcardInstance.comparableIndex = new KeyPartIndex(this.comparableIndex);
+      //wildcardInstance.targetIndex = new KeyPartIndex(this.targetIndex);
+      wildcardInstance.comparableIndex.copy(this.comparableIndex);
+      wildcardInstance.comparableIndex.getElementIndex().copy(this.comparableIndex.getElementIndex());
+      wildcardInstance.targetIndex.copy(this.targetIndex);
+      wildcardInstance.targetIndex.getElementIndex().copy(this.targetIndex.getElementIndex());
+      //wildcardInstance.state = new MatchingState(this.state);
+      //wildcardInstance.state.setComparisonState(new MatchingState(
+      //      (MatchingState) this.state.getComparisonState()));
+      wildcardInstance.state.copy(state);
+   }
+
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImpl.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImpl.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionImpl.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,334 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.common;
+
+import org.jboss.aop.joinpoint.graph.tree.search.match.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.PrefixFunction;
+import org.jboss.aop.joinpoint.graph.tree.search.part.KeyPartIndex;
+
+
+/**
+ * Provides the prefix function to be used by <code>ComparableKeyPart</code>
+ * and <code>ComparableElement</code>.
+ * <p>
+ * This prefix function is calculated based on a key part pattern, which is
+ * composed by one or more elements. So, the function maps a {@link KeyPartIndex
+ * key part index}, which is formed by two values, the key part index value
+ * itself (part index for short) and the element index value, to an array
+ * containing two values: the new part index value, and the new element index
+ * value. When only the element index is provided, the part index is assumed to
+ * be equal to <code>0</code> and only the element index value of the prefix
+ * function is applied. 
+ * 
+ * @author Flavia Rainone
+ * @see org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElement
+ * @see org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPart
+ */
+class PrefixFunctionImpl implements PrefixFunction
+{
+   /**
+    * An array that represents the prefix function zero value.
+    * <p>
+    * Avoids the recurrent allocation of the same array value. 
+    */
+   private static final int[] ZERO_VALUE = new int[]{0, 0};
+   
+   /**
+    * The index of the prefix function part value.
+    */
+   private static final int PART_VALUE = 0;
+
+   /**
+    * The index of the prefix function element value.
+    */
+   private static final int ELEMENT_VALUE = 1;
+   
+   /**
+    * The pattern used for the calculation of the prefix function values.
+    */
+   private String[] pattern;
+   
+   /**
+    * The prefix function values.
+    */
+   private int[][][] prefixFunction;
+   
+   /**
+    * The part index from which the function has not been calculated (lazy
+    * initialization).
+    */
+   private int part;
+   
+   /**
+    * The element index from which the function has not been calculated (lazy
+    * initialization).
+    */
+   private int element;
+   
+   /**
+    * The current prefix function part value, utilized by the prefix calculation
+    * algorithm (lazy initialization).
+    */
+   private int i;
+   
+   /**
+    * The current prefix function element value, utilized by the prefix
+    * calculation algorithm (lazy initialization).
+    */
+   private int j;
+   
+   /**
+    * Assigns the prefix function value of the pattern end.
+    */
+   private PatternEnd patternEnd;
+   
+   /**
+    * Package protected constructor. Creates a prefix function whose values
+    * will be calculated based on a pattern not yet loaded. When such a pattern
+    * is loaded, the created prefix function must be {@link #initialize
+    * initialized} with it.
+    *
+    * @see PrefixFunctionLoader#getLoadedFunction()
+    */
+   PrefixFunctionImpl()
+   { }
+   
+   /**
+    * Initializes the prefix function with <code>pattern</code> data.
+    * 
+    * @param pattern             the pattern that will be used in the prefix
+    *                            function calculation
+    * @param lastElementComplete indicates whether the last <code>pattern</code>
+    *                            element is complete or not
+    */
+   final void initialize(String[] pattern, boolean lastElementComplete)
+   {
+      this.patternEnd = PatternEnd.getInstance(lastElementComplete);
+      this.pattern = pattern;
+      prefixFunction = new int[pattern.length + 1][][];
+      prefixFunction[0] = new int[pattern[0].length() + 1][];
+      prefixFunction[0][0] = ZERO_VALUE;
+      if (pattern[0].length() > 0)
+      {
+         prefixFunction[0][1] = ZERO_VALUE;
+         element = 1;
+      }
+      else
+      {
+         element = 0;
+      }
+      part = 0;
+      i = 0;
+      j = 0;
+   }
+   
+   /**
+    * Applies the prefix function to <code>index</code>, changing its value to
+    * the correspondent prefix function value.
+    * 
+    * @param index the index whose prefix function value will be applied. Notice
+    *              the matching framework may call this method for <code>
+    *              KeyPartIndex</code>es and for common <code>Index</code>es, as
+    *              long as this prefix function is provided as the prefix
+    *              function of both <code>ComparableKeyPart</code>s and  <code>
+    *              ComparableElements</code>.
+    */
+   public final void applyTo(Index index)
+   {
+      if (index instanceof KeyPartIndex)
+      {
+         KeyPartIndex keyPartIndex = (KeyPartIndex) index;
+         Index elementIndex = keyPartIndex.getElementIndex(); 
+         int[] value =  getValue(index.getValue(), elementIndex.getValue());
+         keyPartIndex.applyPrefixFunction(value[PART_VALUE]);
+         elementIndex.applyPrefixFunction(value[ELEMENT_VALUE]);
+      }
+      else
+      {
+         int[] value = getValue(0, index.getValue());
+         index.applyPrefixFunction(value[ELEMENT_VALUE]);
+      }
+   }
+   
+   /**
+    * Returns the prefix function value for the queried index.
+    * 
+    * @param qPart    the queried index part value
+    * @param qElement the queried index element value
+    * @return the prefix function value
+    */
+   private final int[] getValue(int qPart, int qElement)
+   {
+      // if the value is not calculated, calculate it!
+      if (prefixFunction[qPart] == null ||
+            prefixFunction[qPart][qElement] == null)
+      {
+         while(part < qPart || (part == qPart && element < qElement))
+         {
+            if (part < pattern.length)
+            {
+            while(element < pattern[part].length())
+            {
+               // while i,j indicates a '.' char
+               while ((i != 0 || j != 0) && j == pattern[i].length())
+               {
+                  // steps backward
+                  stepBackward();
+               }
+               // while the ZERO_VALUE is not reached nor a match is found
+               while ((i != 0 || j != 0) &&
+                     pattern[i].charAt(j) != pattern[part].charAt(element))
+               {
+                  // steps backward
+                  stepBackward();
+                  // while i,j indiates a '.', steps backward since
+                  // pattern[part][element] doesn't contain a '.'
+                  while ((i != 0 || j != 0) && j == pattern[i].length())
+                  {
+                     stepBackward();
+                  }
+               }
+               // if previous while loop terminated because a match was found...
+               if (j < pattern[i].length() &&
+                     pattern[i].charAt(j) == pattern[part].charAt(element))
+               {
+                  j++; // increment current index value
+               }
+               // prefix function value calculated for part,element
+               prefixFunction[part][++element] = new int[]{i, j};
+            }
+            }
+            // if there is a '.' after this element...
+            if (++ part  < pattern.length)
+            {
+               this.createPartElementFunction(pattern[part].length());
+            }
+            else
+            {
+               this.patternEnd.fillPatternEndValue(this);
+            }
+         }
+      }
+      return prefixFunction[qPart][qElement];   
+   }
+   
+   /**
+    * Creates the prefix function of the part element identified by the <code>
+    * part</code> index.
+    * 
+    * @param length the length of the element
+    */
+   private final void createPartElementFunction(int length)
+   {
+      //  while ZERO_VALUE is not reached and the '.' char is not found
+      while ((i !=  0 || j != 0) && j != pattern[i].length())
+      {
+         // steps backward...
+         stepBackward();
+      }
+      // if previous while loop terminated because the '.' was found
+      if ((i < (part - 1) || j != 0) && j == pattern[i].length())
+      {
+         // increment index value
+         i++;
+         j = 0;
+      }
+      // function value calculated for part,0
+      element = 0;
+      prefixFunction[part] = new int[length + 1][];
+      prefixFunction[part][element] = new int[]{i, j};
+   }
+
+   /**
+    * Steps backward the calculation of a prefix function value, applying the
+    * prefix function itself to the current value.
+    * <p>
+    * Called everytime a mismatch is found in the prefix function calculation.
+    */
+   private final void stepBackward()
+   {
+      int oldI = i;
+      // steps backward
+      i = prefixFunction[oldI][j][PART_VALUE];
+      j = prefixFunction[oldI][j][ELEMENT_VALUE];
+
+   }
+   
+   /**
+    * Defines the prefix function value to be assigned to the pattern end.
+    * 
+    * @author Flavia Rainone
+    */
+   private static abstract class PatternEnd
+   {
+      /**
+       * This pattern end assigns the appropriate prefix function value to the
+       * end of a pattern whose last element is complete.
+       */
+      public static final PatternEnd LAST_ELEMENT_COMPLETE = new PatternEnd()
+      {
+         public void fillPatternEndValue(PrefixFunctionImpl pfi)
+         {
+            pfi.createPartElementFunction(0);
+         }
+      };
+      
+      /**
+       * This pattern end assigns the appropriate prefix function value to the
+       * end of a pattern whose last element is incomplete.
+       */
+      public static final PatternEnd LAST_ELEMENT_INCOMPLETE = new PatternEnd()
+      {
+         public void fillPatternEndValue(PrefixFunctionImpl pfi)
+         {
+            pfi.prefixFunction[pfi.part] = new int[1][];
+            pfi.prefixFunction[pfi.part][0] = pfi.prefixFunction
+               [pfi.part - 1][pfi.pattern[pfi.part - 1].length()];
+         }
+      };
+      
+      /**
+       * Fills the pattern end prefix function value.
+       * 
+       * @param pfi the prefix function whose pattern end value will be
+       *            filled
+       */
+      public abstract void fillPatternEndValue(PrefixFunctionImpl pfi);
+      
+      /**
+       * Returns the appropriate pattern end instance, according to <code>
+       * lastElementComplete</code> value.
+       * 
+       * @param lastElementComplete indicates whether the last pattern element
+       *                            is complete or not
+       * @return the appropriate pattern end instance
+       */
+      public static final PatternEnd getInstance(boolean lastElementComplete)
+      {
+         if (lastElementComplete)
+         {
+            return PatternEnd.LAST_ELEMENT_COMPLETE;
+         }
+         return PatternEnd.LAST_ELEMENT_INCOMPLETE;
+      }
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoader.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoader.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/PrefixFunctionLoader.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,234 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElement;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.PrefixFunction;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPart;
+
+
+/**
+ * Loads a prefix function for {@link ComparableKeyPart}s and for {@link
+ * ComparableElement}s.
+ * 
+ * @author Flavia Rainone
+ */
+public class PrefixFunctionLoader
+{
+   /**
+    * Dummy loader, doesn't create a prefix function.
+    */
+   private static final PrefixFunctionLoader DUMMY_LOADER =
+      new PrefixFunctionLoader(false)
+   {
+      public PrefixFunctionImpl createPrefixFunction()
+      {
+         return null;
+      }
+   };
+
+   /**
+    * Pattern loader, loads the prefix function for a key part pattern.
+    */
+   private static final PrefixFunctionLoader PATTERN_LOADER =
+      new PrefixFunctionLoader(false);
+
+   /**
+    * Suffix loader, loads the prefix function for a key part suffix.
+    */
+   private static final PrefixFunctionLoader SUFFIX_LOADER =
+      new PrefixFunctionLoader(true);
+   
+   /**
+    * Contains all prefix function loader instances.
+    */
+   private static final PrefixFunctionLoader[] instances;
+   
+   /**
+    * The current prefix function loader, is the loader returned by the last
+    * invocation of {@link #getLoaderForProfile(MatcherProfile)}.
+    */
+   private static int currentLoader;
+   
+   static
+   {
+      instances = new PrefixFunctionLoader[MatcherProfile.getNumberOfInstances()];
+      instances[MatcherProfile.SIMPLE.getId()] = DUMMY_LOADER;
+      instances[MatcherProfile.PREFIX.getId()] = DUMMY_LOADER;
+      instances[MatcherProfile.PATTERN.getId()] = PATTERN_LOADER;
+      instances[MatcherProfile.SUFFIX.getId()] = SUFFIX_LOADER;
+   }
+   
+   /**
+    * Returns the prefix function loader appropriate for the <code>
+    * compKeyPartProfile</code>.
+    * <p>
+    * The loader returned by this method will become the current loader.
+    * 
+    * @param compKeyPartProfile the matcher profile associated with the
+    *                           comparable key part whose prefix function will
+    *                           be loaded
+    * @return the appropriate prefix function loader
+    */
+   public static PrefixFunctionLoader getLoaderForProfile(
+         MatcherProfile compKeyPartProfile)
+   {
+      currentLoader = compKeyPartProfile.getId();
+      return instances[currentLoader];
+   }
+   
+   /**
+    * Returns the current loader, which is the same loader returned by the
+    * last invocation of <code>getLoaderForProfile</code>.
+    * 
+    * @return the current loader
+    * @see #getLoaderForProfile(MatcherProfile)
+    */
+   public static PrefixFunctionLoader getCurrentLoader()
+   {
+      return instances[currentLoader];
+   }
+
+   /**
+    * Contains the elements of the pattern being loaded.
+    */
+   protected final List elements = new ArrayList();
+   
+
+   /**
+    * The instance whose pattern is being loaded. After the loading process
+    * finishes, this instance will be initialized with the loaded pattern.
+    */
+   protected PrefixFunctionImpl prefixFunction;
+   
+   /**
+    * Indicates whether the last element of the pattern to be loaded is complete
+    * or not (such an element is complete only when the loaded elements are part
+    * of a comparable key part suffix).
+    */
+   protected boolean lastElementComplete;
+   
+   /**
+    * Private constructor.
+    * 
+    * @param lastElementComplete indicates whether the last element of the
+    *                            pattern whose prefix function to be loaded
+    *                            is complete or not
+    */
+   private PrefixFunctionLoader(boolean lastElementComplete)
+   {
+      this.lastElementComplete = lastElementComplete;
+   }
+   
+   /**
+    * Prepares a prefix function instance for loading a pattern. Once
+    * this pattern is loaded, the created instance will be initialized with
+    * it.
+    *
+    * @see #loadElement(String)
+    * @see #loaded()
+    * @see #getLoadedFunction()
+    */
+   public final void prepareForLoading()
+   {
+      elements.clear();
+      prefixFunction = createPrefixFunction();
+   }
+   
+   /**
+    * Creates a prefix function.
+    * 
+    * @return the created prefix function
+    */
+   protected PrefixFunctionImpl createPrefixFunction()
+   {
+      return new PrefixFunctionImpl();
+   }
+   
+   /**
+    * Notifies that the complete pattern has been loaded and, consequently,
+    * that the pattern prefix function created in <code>prepareForLoadingPattern
+    * </code> can be initialized with the loaded data.
+    * <p>
+    * If the <code>prepareForLoading</code> method wasn't invoked before this
+    * one, an error will occur.
+    *
+    * @see #prepareForLoading()
+    * @see #loadElement(String)
+    * @see #getLoadedFunction()
+    */
+   public void loaded()
+   {
+      if (this.prefixFunction != null)
+      {
+         String[] elementArray = new String[elements.size()];
+         elementArray = (String[]) elements.toArray(elementArray);
+         elements.clear();
+         prefixFunction.initialize(elementArray, lastElementComplete);
+      }
+   }
+   
+   /**
+    * Loads an element of the pattern.
+    * <p>
+    * This method should be called in the order the elements occur in the
+    * pattern.
+    * 
+    * @param element an element of the pattern
+    * @return the prefix function that will be initialized with the loaded
+    *         pattern when the pattern loading process finishes. If the method
+    *         <code>prepareForLoading</code> wasn't invoked, returns <code>null
+    *         </code>.
+    * @see #prepareForLoading()
+    * @see #loaded()
+    * @see #getLoadedFunction()
+    */
+   public PrefixFunction loadElement(String element)
+   {
+      elements.add(element);
+      return prefixFunction;
+   }
+   
+   /**
+    * Returns the prefix function whose values are calculated based on the
+    * previously loaded pattern.
+    * <p>
+    * The same prefix function cannot be retrieved more than once, or <code>
+    * null</code> will be returned.
+    * 
+    * @return the prefix function whose values are calculated based on the
+    *         previously loaded pattern. Returns <code>null</code> if the prefix
+    *         function has already been retrieved or if the <code>
+    *         prepareForLoading</code> method was not called before the pattern
+    *         being loaded.
+    */
+   public PrefixFunction getLoadedFunction()
+   {
+      PrefixFunction function = prefixFunction;
+      prefixFunction = null;
+      return function;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/common/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Contains classes common to both <code>tree.search.element</code>
+and <code>tree.search.part</code> packages.
+
+
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.search.element
+ at see pointcutMatcher.tree.search.part
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElement.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElement.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElement.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.element;
+
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.common.PrefixFunctionLoader;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Comparable;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+import org.jboss.aop.joinpoint.graph.tree.search.match.PrefixFunction;
+import org.jboss.aop.joinpoint.graph.tree.search.match.State;
+import org.jboss.aop.joinpoint.graph.tree.search.part.ComparableKeyPart;
+
+
+/**
+ * Implements the <code>Comparable</code> interface having characters as
+ * components.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableElement implements Comparable
+{
+   /**
+    * The element expression.
+    */
+   private String expression;
+   
+   /**
+    * The prefix function associated with this element.
+    */
+   private PrefixFunction prefixFunction;
+   
+   /**
+    * Constructor.
+    * 
+    * @param expression           the element expression, that will be compared
+    *                             against a target in the {@link #compare
+    *                             compare} method
+    * @param prefixFunctionLoader the loader responsible for loading the prefix
+    *                             function of the {@link ComparableKeyPart} that
+    *                             contains this element.
+    */
+   ComparableElement (String expression,
+         PrefixFunctionLoader prefixFunctionLoader)
+   {
+      this.expression = expression;
+      this.prefixFunction = prefixFunctionLoader.loadElement(expression);
+   }
+   
+   public final int getPostPrefixLength()
+   {
+      return expression.length();
+   }
+   
+   public char getNextCharacter(Index comparableIndex, Object comparisonState)
+   {
+      if (expression.length() == 0)
+      {
+         return Flags.ALL;
+      }
+      if (comparableIndex.getValue() >= expression.length())
+      {
+         return KeyPart.KEY_ELEMENT_END;
+      }
+      return expression.charAt(comparableIndex.getValue());
+   }
+   
+   public char getNextCharacter(Index comparableIndex, Object target,
+         LengthRange targetLengthRange, Object comparisonState)
+   {
+      return getNextCharacter(comparableIndex, comparisonState);
+   }
+   
+   public PrefixFunction getPrefixFunction()
+   {
+      return prefixFunction;
+   }
+   
+   public ComparisonResult compare(Object target, Index targetIndex,
+         Index comparableIndex, State comparisonState)
+   {
+      String targetExpression = (String) target;
+      while(comparableIndex.getValue() < expression.length() &&
+            targetIndex.getValue() < targetExpression.length())
+      {
+         if (targetExpression.charAt(targetIndex.getValue()) !=
+             expression.charAt(comparableIndex.getValue()))
+         {
+            return ComparisonResult.MISMATCH_FOUND;
+         }
+         targetIndex.increment();
+         comparableIndex.increment();
+      }
+      boolean expressionEnd = comparableIndex.getValue() >= expression.length();
+      boolean targetEnd = targetIndex.getValue() >= targetExpression.length();
+      return ComparisonResult.getInstance(expressionEnd, targetEnd);
+   }
+   
+   public String toString()
+   {
+      return "\"" + expression + "\"";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactory.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/ComparableElementFactory.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,145 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.element;
+
+import org.jboss.aop.joinpoint.graph.tree.search.common.PrefixFunctionLoader;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Comparable;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparableFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherSequenceProfile;
+
+
+/**
+ * Creates <code>ComparableElement</code> instances.
+ * 
+ * @author Flavia Rainone
+ * @see ComparableElement
+ */
+public class ComparableElementFactory implements ComparableFactory
+{
+   /**
+    * Singleton instance.
+    */
+   private static final ComparableElementFactory instance =
+      new ComparableElementFactory();    
+   
+   /**
+    * Returns the singleton factory instance.
+    * 
+    * @return the singleton factory instance
+    */
+   public static final ComparableElementFactory getInstance()
+   { 
+      return instance; 
+   }
+   
+   /**
+    * Map of <code>MatcherProfile</code> to <code>MatcherSequenceProfile</code>,
+    * indicates the profile of the element matcher sequence to be created
+    * according to the key part matcher profile. 
+    */
+   private MatcherSequenceProfile[] profiles;
+   
+   /**
+    * The responsible for loading the prefix function of the comparable key part
+    * that contains the comparable elements to be created.
+    */
+   private PrefixFunctionLoader loader;
+
+   /**
+    * Private constructor (singleton class).
+    */
+   private ComparableElementFactory()
+   {
+      this.profiles =
+         new MatcherSequenceProfile[MatcherProfile.getNumberOfInstances()];
+      // sequence for simple part
+      this.profiles[MatcherProfile.SIMPLE.getId()] = new MatcherSequenceProfile(
+           MatcherProfile.SIMPLE, MatcherProfile.SIMPLE,
+           MatcherProfile.SIMPLE, MatcherProfile.SIMPLE);
+      // sequence for prefix part
+      this.profiles[MatcherProfile.PREFIX.getId()] = new MatcherSequenceProfile(
+            MatcherProfile.SIMPLE, MatcherProfile.SIMPLE,
+            MatcherProfile.PREFIX, MatcherProfile.PREFIX);
+      // sequence for pattern part
+      this.profiles[MatcherProfile.PATTERN.getId()] = new MatcherSequenceProfile(
+            MatcherProfile.SUFFIX, MatcherProfile.SIMPLE,
+            MatcherProfile.PREFIX, MatcherProfile.PATTERN);
+      // sequence for suffix part
+      this.profiles[MatcherProfile.SUFFIX.getId()] = new MatcherSequenceProfile(
+            MatcherProfile.SUFFIX, MatcherProfile.SIMPLE,
+            MatcherProfile.SIMPLE, MatcherProfile.SUFFIX);
+   }
+   
+   /**
+    * Notifies this factory to which key part matcher profile the comparable
+    * elements will be created.
+    * <p>
+    * This method must always be called before the <code>
+    * MatcherFactory.createSequence</code> method.
+    *  
+    * @param profile the matcher profile of the comparale key part whose
+    *                elements will be created by this factory
+    *                
+    * @return the profile of the element matcher sequence to be created. Should
+    *         be used as a parameter to the <code>MatcherFactory.createSequence
+    *         </code> method.
+    */
+   public MatcherSequenceProfile performCreationForProfile(
+         MatcherProfile profile)
+   {
+      this.loader = PrefixFunctionLoader.getLoaderForProfile(profile);
+      return profiles[profile.getId()];
+   }
+   
+   
+   public char getSeparator()
+   {
+      return '.';
+   }
+   
+   /**
+    * Prepares a prefix function for loading a pattern when needed.
+    * 
+    * @see #stopCreation()
+    */
+   public void startCreation()
+   {
+      loader.prepareForLoading();
+   }
+   
+   /**
+    * Stops the process of loading a pattern for a prefix function.
+    * 
+    * @see #startCreation()
+    */
+   public void stopCreation()
+   {
+      loader.loaded();
+   }
+   
+   public Comparable create(String comparableExpression,
+         MatcherProfile matcherProfile)
+   {
+      return new ComparableElement(comparableExpression, loader);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/element/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,48 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Implements the <code>search.match</code> package.
+
+
+
+<h2>Package Specification</h2>
+<p>
+In this package, the <code>Comparable</code> interface is implemented by the
+<code>ComparableElement</code> class, whose components are simple characters.
+</p>
+<p>
+This package contains the <code>ComparableFactory</code> implementation
+associated with <code>ComparableElement</code>, but not the <code>
+PrefixFunction</code> one, which is located in the <code>search.common</code>
+package.   
+</p>
+   
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.search.element.ComparableElement
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Comparable.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Comparable.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Comparable.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,118 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Represents a <i>matchable expression</i> part. Capable of comparing itself
+ * against a target, is utilized by the <code>Matcher</code> to execute the
+ * matching algorithm.
+ * 
+ * @author Flavia Rainone
+ * @see Matcher
+ * @see org.jboss.aop.joinpoint.graph.tree.search.match
+ */
+public interface Comparable
+{
+   /**
+    * Returns the number of components contained in the post-prefix of this
+    * comparable. 
+    * 
+    * @return the number of components contained in the post-prefix of this
+    *         comparable
+    */
+   int getPostPrefixLength();
+   
+   /**
+    * Returns the character that identifies the next comparable component that
+    * will be compared.
+    * 
+    * @param comparableIndex indicates the next comparable component to be
+    *                        compared
+    * @return the identifier of the next comparable component that will be
+    *         compared. May be <code>Flags.ALL</code> if this information
+    *         can not be asserted. 
+    */
+   char getNextCharacter(Index comparableIndex, Object comparisonState);
+   
+   /**
+    * Returns the character that identifies the next comparable component that
+    * will be compared.
+    * <p>
+    * The extra information provided by this method allows the comparable to
+    * return a more accurate result.
+    * 
+    * @param comparableIndex   indicates the next comparable component to be
+    *                          compared
+    * @param target            the target of the last comparison executed
+    *                          (with a <code>ComparisonResult.TARGET_END</code>
+    *                          or <code>ComparisonResult.BOTH_ENDS</code>
+    *                          result)
+    * @param targetLengthRange the length range of <code>target</code>
+    * @return the identifier of the next comparable component that will be
+    *         compared. May be <code>Flags.ALL</code> if this information
+    *         can not be asserted.
+    */
+   char getNextCharacter(Index comparableIndex, Object target,
+         LengthRange targetLengthRange, Object comparisonState);
+   
+   /**
+    * Returns the prefix function associated with this comparable.
+    * <p>
+    * Is involked only when the matcher associated with this comparable has the
+    * {@link MatcherProfile#PATTERN PATTERN} or the {@link MatcherProfile#SUFFIX
+    * SUFFIX} profile.
+    * 
+    * @return the prefix function associated with this comparable
+    * @see PrefixFunction
+    */
+   PrefixFunction getPrefixFunction();
+   
+   /**
+    * Compares the <i>matchable expression</i> part components with the target
+    * components one by one, until a mismatch is found or the end of components
+    * is reached.
+    * 
+    * @param target          the target of the comparison. Should be of a type
+    *                        compatible with this comparable
+    * @param targetIndex     indicates from which target component the
+    *                        comparison should start
+    * @param comparableIndex indicates from which comparable component the
+    *                        comparison should start
+    * @param comparisonState the state of the comparison, stores data relevant
+    *                        about previous comparisons. The same state is
+    *                        passed to each <code>compare</code> call made by
+    *                        the matcher sequence. The comparable is
+    *                        responsible for storing, updating and retrieving
+    *                        the data contained in this state, according to its
+    *                        need. The comparison state is passed by the client
+    *                        as an argument to the {@link
+    *                        MatchingState#MatchingState(State)} constructor. If
+    *                        the client doesn't provide a comparison state,
+    *                        the value contained in this parameter could be
+    *                        anything, including <code>null</code>.
+    * @return a comparison result, indicating whether a mismatch was found, or
+    *         if the comparison finished by reaching the comparable end,
+    *         target end or both ends.
+    */
+   ComparisonResult compare(Object target, Index targetIndex,
+         Index comparableIndex, State comparisonState);
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparableFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparableFactory.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparableFactory.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,72 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Creates a comparable instance.
+ * <p>
+ * Is invoked by the <code>MatcherFactory.createSequence</code> method.
+ * 
+ * @author Flavia Rainone
+ * @see MatcherFactory
+ */
+public interface ComparableFactory
+{
+   /**
+    * Returns the separator that will be used by the <code>MatcherFactory
+    * </code> class, to break the <code>matchableExpression</code> into the
+    * parts that will be attributed to comparables.
+    * 
+    * @return the separator that will be used to break the <code>
+    *         matchableExpression</code> into parts
+    */
+   char getSeparator();
+   
+   /**
+    * Callback method. Notifies this factory that the <code>MatcherFactory
+    * </code> will start the creation of comparables.
+    */
+   void startCreation();
+
+   /**
+    * Callback method. Notifies this factory that the <code>MatcherFactory
+    * </code> will stop the creation of comparables.
+    */
+   void stopCreation();
+   
+   /**
+    * Creates a comparable, able of comparing <code>comparableExpression</code>
+    * against a target.
+    * <p>
+    * Is invoked by <code>MatcherFactory.createSequence</code> method.
+    * 
+    * @param comparableExpression a part of the <i>matchable expression</i>
+    *                             passed to the <code>createSequence</code>
+    *                             method.
+    * @param matcherProfile       the profile of the matcher that will be
+    *                             associated with the comparable to be created
+    * @return the created comparable, able of comparing <code>
+    *         comparableExpression</code> against a target.
+    */
+   Comparable create(String comparableExpression,
+         MatcherProfile matcherProfile);
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithm.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithm.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonAlgorithm.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,285 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+
+/**
+ * One of the components of <code>MatcherProfile</code>.
+ * <p>
+ * Determines how the <code>Comparable</code> functionality is used
+ * by the <code>Matcher</code> methods.
+ * 
+ * @author Flavia Rainone
+ * @see Comparable
+ * @see Matcher
+ */
+abstract class ComparisonAlgorithm
+{
+   /**
+    * Algorithm that just compares the comparable with the target.
+    */
+   public static final ComparisonAlgorithm SIMPLE = new ComparisonAlgorithm(
+         "Simple Algorithm")
+   {
+      
+      public ComparisonResult execute(Comparable comparable,
+            Index comparableIndex, Object target, Index targetIndex,
+            int targetLength, LengthRestriction restriction,
+            State comparisonState)
+      {
+         return comparable.compare(target, targetIndex, comparableIndex,
+               comparisonState);
+      }
+      
+      public ComparisonResult execute(Comparable comparable,
+            Index comparableIndex, Object target, Index targetIndex,
+            LengthRange targetLengthRange, LengthRestriction restriction,
+            State comparisonState)
+      {
+         return comparable.compare(target, targetIndex, comparableIndex,
+               comparisonState);
+      }
+      
+      public char getNextCharacter(Comparable comparable, Index comparableIndex,
+            Object target, LengthRange targetLengthRange,
+            MatchingState matchingState)
+      {
+         return comparable.getNextCharacter(comparableIndex, target,
+               targetLengthRange, matchingState.comparisonState);
+      }
+      
+      public char getNextCharacter(Comparable comparable, Index comparableIndex,
+            MatchingState matchingState)
+      {
+         return comparable.getNextCharacter(comparableIndex,
+               matchingState.comparisonState);
+      }
+   };
+   
+   /**
+    * KMP pattern matching algorithm, executes the comparison one or more times,
+    * updating the index values until a mismatch is not found and the comparison
+    * succeeds, or until the length restriction cannot be applied anymore. TODO bom?
+    */
+   public static final ComparisonAlgorithm KMP = new ComparisonAlgorithm(
+         "KMP Algorithm")
+   {
+      
+      public ComparisonResult execute(Comparable comparable,
+            Index comparableIndex, Object target, Index targetIndex,
+            int targetLength, LengthRestriction restriction,
+            State comparisonState)
+      {
+         comparisonState.save();
+         ComparisonResult  result = comparable.compare(target, targetIndex,
+               comparableIndex, comparisonState);
+         PrefixFunction prefixFunction = comparable.getPrefixFunction();
+         
+         while (result == ComparisonResult.MISMATCH_FOUND)
+         {
+            if (comparableIndex.isInitialState())
+            {
+               targetIndex.increment();
+            }
+            else
+            {
+               prefixFunction.applyTo(comparableIndex);
+            }
+            if (! restriction.appliesTo(comparable, comparableIndex,
+                  targetLength, targetIndex))
+            {
+               return ComparisonResult.MISMATCH_FOUND;
+            }
+            comparisonState.rollback();
+            result = comparable.compare(target, targetIndex, comparableIndex,
+                  comparisonState);     
+         }
+         return result;
+      }
+      
+      public ComparisonResult execute(Comparable comparable,
+            Index comparableIndex, Object target, Index targetIndex,
+            LengthRange targetLengthRange, LengthRestriction restriction,
+            State comparisonState)
+      {
+         comparisonState.save();
+         ComparisonResult  result = comparable.compare(target, targetIndex,
+               comparableIndex, comparisonState);
+         PrefixFunction prefixFunction = comparable.getPrefixFunction();
+         while (result == ComparisonResult.MISMATCH_FOUND)
+         {
+            if (comparableIndex.isInitialState())
+            {
+               targetIndex.increment();
+            }
+            else
+            {
+               prefixFunction.applyTo(comparableIndex);
+            }
+            if (! restriction.appliesTo(comparable, comparableIndex,
+                  targetLengthRange, targetIndex))
+            {
+               return ComparisonResult.MISMATCH_FOUND;
+            }
+            comparisonState.rollback();
+            result = comparable.compare(target, targetIndex, comparableIndex,
+                  comparisonState);     
+         }
+         return result;
+      }
+      
+      public char getNextCharacter(Comparable comparable, Index comparableIndex,
+            Object target, LengthRange targetLengthRange, MatchingState state)
+      {
+         return state.getNextCharacter(comparable, comparableIndex, target,
+               targetLengthRange);
+      }
+      
+      public char getNextCharacter(Comparable comparable, Index comparableIndex,
+            MatchingState state)
+      {
+         return state.getNextCharacter(comparable, comparableIndex);
+      }
+   };
+   
+   
+   /**
+    * A string that describes this algorithm.
+    */
+   private String description;
+   
+   /**
+    * Private constructor.
+    */
+   private ComparisonAlgorithm(String description)
+   {
+      this.description = description;
+   }
+   
+   /**
+    * Executes the algorithm, making use of the <code>comparable</code>
+    * functionality to compare it against the target.
+    * <p>
+    * Is invoked when <code>target</code> has no suffixes.
+    *  
+    * @param comparable         object that will be compared with <code>target
+    *                           </code>
+    * @param comparableIndex    indicates from which <code>comparable</code>
+    *                           component the comparison will start
+    * @param target             the target of the comparison
+    * @param targetIndex        indicates from which target component the
+    *                           comparison will start
+    * @param targetLength       the number of components contained in <code>
+    *                           target</code>
+    * @param restriction        the length restriction that applies to this
+    *                           scenario. Every time the indexes values are
+    *                           changed outside of a comparison, this
+    *                           restriction must be applied again.
+    * @param comparisonState    the state of comparison, is passed along to
+    *                           <code>comparable</code> on every comparison
+    *                           performed by it.
+    * @return the result of the comparison
+    */
+   public abstract ComparisonResult execute(Comparable comparable,
+         Index comparableIndex, Object target, Index targetIndex,
+         int targetLength, LengthRestriction restriction,
+         State comparisonState);
+   
+   /**
+    * Executes the algorithm, making use of the <code>comparable</code>
+    * functionality to compare it against the target.
+    * <p>
+    * Is invoked when <code>target</code> has one or more suffixes.
+    *  
+    * @param comparable         object that will be compared with <code>target
+    *                           </code>
+    * @param comparableIndex    indicates from which <code>comparable</code>
+    *                           component the comparison will start
+    * @param target             the target of the comparison
+    * @param targetIndex        indicates from which target component the
+    *                           comparison will start
+    * @param targetLengthRange  the minimum-maximum range of the
+    *                           <code>target</code> suffixes and pos-prefixes
+    *                           length
+    * @param restriction        the length restriction that applies to this
+    *                           scenario. Every time the indexes values are
+    *                           changed outside of a comparison, this
+    *                           restriction must be applied again.
+    * @param comparisonState    the state of comparison, is passed along to
+    *                           <code>comparable</code> on every comparison
+    *                           performed by it.
+    * @return the result of the comparison
+    */
+   public abstract ComparisonResult execute(Comparable comparable,
+         Index comparableIndex, Object target, Index targetIndex,
+         LengthRange targetLengthRange, LengthRestriction restriction,
+         State comparisonState);
+   
+   /**
+    * Returns the character that identifies the next target to be compared by
+    * this algorithm with a successful result. If a target not identified by
+    * this character is compared, the result will be certainly <code>
+    * ComparisonResult.MISMATCH_FOUND</code>.
+    * <p>
+    * Is invoked when the <code>target</code> and its length range are known. 
+    * 
+    * @param comparable         object that will perform the next comparison
+    * @param comparableIndex    indicates from which <code>comparable</code>
+    *                           component the comparison will start
+    * @param target             the target of the last algorithm execution
+    *                           (with a <code>ComparisonResult.TARGET_END</code>
+    *                           or <code>ComparisonResult.BOTH_ENDS</code>
+    *                           result) 
+    * @param targetLengthRange the length range of <code>target</code>
+    * @param matchingState      the state of the matching process
+    * @return the character that identifies the next target to be compared by
+    *         this algorithm with a successful result. May be <code>Flags.ALL
+    *         </code> to indicate that any target may have a successful result.
+    */
+   public abstract char getNextCharacter(Comparable comparable,
+         Index comparableIndex, Object target, LengthRange targetLengthRange,
+         MatchingState matchingState);
+   
+   /**
+    * Returns the character that identifies the next target to be compared by
+    * this algorithm with a successful result. If a target not identified by
+    * this character is compared, the result will be certainly <code>
+    * ComparisonResult.MISMATCH_FOUND</code>.
+    * <p>
+    * Is invoked when the last compared target and its length range are unknown. 
+    * 
+    * @param comparable         object that will perform the next comparison
+    * @param comparableIndex    indicates from which <code>comparable</code>
+    *                           component the comparison will start
+    * @param matchingState      the state of the matching process
+    * @return the character that identifies the next target to be compared by
+    *         this algorithm with a successful result. May be <code>Flags.ALL
+    *         </code> to indicate that any target may have a successful result.
+    */
+   public abstract char getNextCharacter(Comparable comparable,
+         Index comparableIndex, MatchingState matchingState);
+
+   public String toString()
+   {
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndState.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndState.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonEndState.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,242 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+
+/**
+ * This state indicates the relationship between the number of available
+ * comparable components and the maximum number of available target components
+ * (available components are those that still need to be compared and matched).
+ * In other words, it indicates how close to the end of the longest complete
+ * target the current comparison will finish, in case of a positive comparison
+ * result.
+ * 
+ * @author Flavia Rainone
+ */
+public abstract class ComparisonEndState
+{
+   /**
+    * Loose state, indicates that the number of available comparable components
+    * is less than the maximum number of available target components.
+    */
+   public static final ComparisonEndState LOOSE =
+      new ComparisonEndState("Loose")
+   {
+      public void update(MatchingState state, Comparable comparable,
+            Index comparableIndex, int targetPostPrefixMaxLength,
+            Index targetIndex)
+      {
+         if ((targetPostPrefixMaxLength - targetIndex.getValue()) <= 
+            (comparable.getPostPrefixLength() - comparableIndex.getValue()))
+         {
+            state.comparisonEndState= TIGHT;
+         }
+      }
+      
+      public void tightenComparison(MatchingState state, Comparable comparable,
+            Index comparableIndex, int targetPostPrefixMinLength,
+            Index targetIndex)
+      {
+         int difference = comparable.getPostPrefixLength() -
+            targetPostPrefixMinLength + targetIndex.getValue();
+         if (difference < 0)
+         {
+            targetIndex.increment(- difference);
+            comparableIndex.reset();
+         }
+         PrefixFunction prefixFunction = comparable.getPrefixFunction();
+         while (comparableIndex.getValue() != 0 &&
+                  comparableIndex.getValue() > difference)
+         {
+            prefixFunction.applyTo(comparableIndex);
+         }
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex, Object target,
+            LengthRange targetLengthRange)
+      {
+         if (targetLengthRange.getSuffixMaxLength() <= 
+            (comparable.getPostPrefixLength() - comparableIndex.getValue()))
+         {
+            state.comparisonEndState = TIGHT;
+            return comparable.getNextCharacter(comparableIndex, target,
+                  targetLengthRange, state.comparisonState);
+         }
+         return Flags.ALL;
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex)
+      {
+         return Flags.ALL;
+      }
+   };
+   
+   /**
+    * Tight state, indicates that the number of available comparable components
+    * is equal to the maximum number of available target components.
+    */
+   public static final ComparisonEndState TIGHT =
+      new ComparisonEndState("Tight")
+   {
+      public void update(MatchingState state, Comparable comparable,
+            Index comparableIndex, int targetPostPrefixMaxLength,
+            Index targetIndex)
+      {}
+
+      public void tightenComparison(MatchingState state, Comparable comparable,
+            Index comparableIndex, int targetPostPrefixMinLength,
+            Index targetIndex)
+      {}
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex, Object target,
+            LengthRange targetLengthRange)
+      {
+         return comparable.getNextCharacter(comparableIndex, target,
+               targetLengthRange, state.comparisonState);
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex)
+      {
+         return comparable.getNextCharacter(comparableIndex,
+               state.comparisonState);
+      }
+   };
+
+   /**
+    * A string that describes this comparison end state.
+    */
+   private String description;
+   
+   /**
+    * Private constructor.
+    */
+   private ComparisonEndState(String description)
+   {
+      this.description = description;
+   }
+   
+   /**
+    * Updates the current comparison end state.
+    * 
+    * @param state                     the matching state, that contains the
+    *                                  current comparison end state
+    * @param comparable                the comparable that will perform the next
+    *                                  comparison
+    * @param comparableIndex           indicates from which <code>comparable
+    *                                  </code> component the next comparison
+    *                                  will start
+    * @param targetPostPrefixMaxLength the length of the biggest target
+    *                                  post-prefix
+    * @param targetIndex               indicates from which target component
+    *                                  the next comparison will start
+    *                         
+    */
+   public abstract void update(MatchingState state, Comparable comparable,
+         Index comparableIndex, int targetPostPrefixMaxLength,
+         Index targetIndex);
+
+   /**
+    * Tightens the comparison, incrementing <code>targetIndex</code> until
+    * the minimum number of available target components becomes the same as
+    * the number of the availble <code>comparable</code> components.
+    * 
+    * @param state                     the matching state, contains the current
+    *                                  comparison end state
+    * @param comparable                the comparable that will perform the next
+    *                                  comparison
+    * @param comparableIndex           indicates from which <code>comparable
+    *                                  </code> component the next comparison
+    *                                  will start. This index value may be
+    *                                  changed accordingly to the changes made
+    *                                  to <code>targetIndex</code> value. 
+    * @param targetPostPrefixMinLength the length of the smallest target
+    *                                  post-prefix
+    * @param targetIndex               indicates from which target component the
+    *                                  next comparison will start. The value of
+    *                                  this index may be changed by this method,
+    *                                  in order to tighten comparison.
+    */
+   public abstract void tightenComparison(MatchingState state,
+         Comparable comparable, Index comparableIndex,
+         int targetPostPrefixMinLength, Index targetIndex);
+
+   /**
+    * Returns the character that identifies the next target to be compared
+    * with a positive result (i.e., with no mismatches found). If a target not
+    * identified by this character is compared, the result will be certainly
+    * a {@link ComparisonResult#MISMATCH_FOUND mismatch}.
+    * <p>
+    * Is invoked when the last target compared and/or its length range are
+    * unknown.
+    * 
+    * @param state             the matching state, stores the current comparison
+    *                          end state
+    * @param comparable        the comparable that will perform the next
+    *                          comparison
+    * @param comparableIndex   indicates from which <code>comparable</code>
+    *                          component the next comparison will start
+    * @return                  the character that identifies the next target to
+    *                          be compared with a positive result. May return
+    *                          {@link Flags#ALL} to indicate that any target may
+    *                          have a positive result.
+    */
+   public abstract char getNextCharacter(MatchingState state,
+         Comparable comparable, Index comparableIndex);
+   
+   /**
+    * Returns the character that identifies the next target to be compared
+    * with a positive result (i.e., with no mismatches found). If a target not
+    * identified by this character is compared, the result will be certainly
+    * a {@link ComparisonResult#MISMATCH_FOUND mismatch}.
+    * <p>
+    * Is invoked when <code>target</code> and <code>targetLengthRange</code>
+    * are known.
+    *  
+    * @param state             the matching state, stores the current comparison
+    *                          end state
+    * @param comparable        the comparable that will perform the next
+    *                          comparison
+    * @param comparableIndex   indicates from which <code>comparable</code>
+    *                          component the next comparison will start
+    * @param target            the object that will be compared to <code>
+    *                          comparable</code>
+    * @param targetLengthRange the minimum-maximum length range of the target
+    *                          suffixes and post-prefixes
+    * @return                  the character that identifies the next target to
+    *                          be compared with a positive result. May return
+    *                          {@link Flags#ALL} to indicate that any target may
+    *                          have a positive result.
+    */
+   public abstract char getNextCharacter(MatchingState state,
+         Comparable comparable, Index comparableIndex, Object target,
+         LengthRange targetLengthRange);
+   
+   public String toString()
+   {
+      return description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResult.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResult.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonResult.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,119 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * This class is a singleton whose instances represent the result of a
+ * comparison (type enum pattern, of Joshua Block).
+ * 
+ * @author Flavia Rainone
+ * @see Comparable#compare
+ */
+public class ComparisonResult
+{
+   /**
+    * Indicates that only the comparable's end was reached during the
+    * comparison.
+    */
+   public static final ComparisonResult COMPARABLE_END =
+      new ComparisonResult("Comparable Expression End");
+   
+   /**
+    * Indicates that both the comparable and the target reached their ends
+    * during the comparison.
+    */
+   public static final ComparisonResult BOTH_ENDS =
+      new ComparisonResult("End of Both Expressions");
+   
+   /**
+    * Indicates that none of the parts involved reached their ends during the
+    * comparison, because a mismatch was found.
+    */
+   public static final ComparisonResult MISMATCH_FOUND =
+      new ComparisonResult("Mismatch Found");
+   
+   /**
+    * Indicates that only the target's end was reached during the comparison. 
+    */
+   public static final ComparisonResult TARGET_END =
+      new ComparisonResult("Target Expression End");
+   
+   /**
+    * Returns the instance of <code>ComparisonResult</code> that represents
+    * the comparison outcome contained in the <code>compEnd</code> and <code>
+    * targetEnd</code> parameters.
+    *  
+    * @param compEnd   <code>true</code> if the comparable's end was reached
+    *                  during comparison
+    * @param targetEnd <code>true</code> if the target's end was reached during
+    *                  comparison
+    * @return the appropriate comparison result
+    */
+   public static ComparisonResult getInstance(boolean compEnd,
+         boolean targetEnd)
+   {
+      int id = 2 + (compEnd? -2: 0) + (targetEnd? + 1: 0);
+      return INSTANCES[id];
+   }
+   
+   /**
+    * Returns the number of <code>ComparisonResult</code> instances.
+    * 
+    * @return the number of <code>ComparisonResult</code> instances
+    */
+   public static final int getNumberOfInstances()
+   {
+      return INSTANCES.length;
+   }
+   
+   /////////////////////////////////////////////////////////////////////////////
+   
+   /** Contains all instances. */
+   private static ComparisonResult[] INSTANCES = new ComparisonResult[] {
+      COMPARABLE_END, BOTH_ENDS, MISMATCH_FOUND, TARGET_END};
+   
+   /** Used to generate ids for the instances.*/
+   private static int ID_COUNTER = 0;
+   
+   /////////////////////////////////////////////////////////////////////////////
+   
+   /** Identifier of this comparison result. */
+   private int id;
+   
+   /** String that describes this comparison result. */
+   private String description;
+   
+   /**
+    * Private constructor.
+    * 
+    * @param description the description of the comparison result to be created.
+    */
+   private ComparisonResult(String description)
+   {
+      this.description = description;
+      id = ID_COUNTER++;
+   }
+   
+   /**
+    * Returns the id of the <code>ComparisonResult</code> instance.
+    * 
+    * @return an id. Notice that all <code>ComparisonResult</code> instances
+    *         have an id, which is different for each instance. The smallest id 
+    *         is <code>0</code>, and for each existent id <code>i</code> there
+    *         is also an id <code>i - 1</code> if <code>i</code> > <code>1
+    *         </code>.
+    */
+   public int getId()
+   {
+      return id;
+   }
+   
+   public String toString(){
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStart.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStart.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStart.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,130 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * One of the components of <code>MatcherProfile</code>.
+ * <p>
+ * Tunes the comparable and target indexes before a comparison is executed.
+ * 
+ * @author Flavia Rainone
+ * @see MatcherProfile
+ */
+abstract class ComparisonStart
+{
+   /**
+    * Loose comparison start, keeps the indexes unchanged.
+    */
+   public static final ComparisonStart LOOSE = new ComparisonStart(
+         "Loose Comparison Start")
+   {
+     public void tuneIndex(Comparable comparable, Index comparableIndex,
+           int targetLength, Index targetIndex, MatchingState state)
+     {}
+     public boolean tuneIndex(Comparable comparable, Index comparableIndex,
+           LengthRange targetLengthRange, Index targetIndex,
+           MatchingState state)
+     {
+        return false;
+     }
+   };
+
+   /**
+    * Tight comparison start, increments the indexes until the number of
+    * available comparable components and the minimum number of available target
+    * components become the same (the number of available components it the
+    * number of components that still need to be compared and matched).
+    * 
+    * @see MatchingState#tightenComparison(Comparable, Index, int, Index)
+    * @see MatchingState#tightenComparison(Comparable, Index, LengthRange, Index)
+    */
+   public static final ComparisonStart TIGHT = new ComparisonStart(
+         "Tight Comparison Start")
+   {
+     public void tuneIndex(Comparable comparable, Index comparableIndex,
+           int targetLength, Index targetIndex, MatchingState state)
+     {
+       state.tightenComparison(comparable, comparableIndex, targetLength,
+             targetIndex);
+     }
+     
+     public boolean tuneIndex(Comparable comparable, Index comparableIndex,
+           LengthRange targetLengthRange, Index targetIndex,
+           MatchingState state)
+     {
+       return state.tightenComparison(comparable, comparableIndex,
+             targetLengthRange, targetIndex);
+     }
+   };
+   
+   
+   /**
+    * String that describes this comparison start.
+    */
+   private String description;
+   
+   /**
+    * Private constructor.
+    */
+   private ComparisonStart(String description)
+   {
+      this.description = description;
+   }
+   
+   /**
+    * Tunes the indexes to indicate from which <code>comparable</code> and
+    * target components comparison should start.
+    * <p>
+    * Is called when the target of the comparison has no suffixes.
+    * 
+    * @param comparable      object that will perform the comparison
+    * @param comparableIndex the comparable index before being tuned
+    * @param targetLength    the length of the comparison target
+    * @param targetIndex     the index of the target before being tuned
+    * @param state the state of the matching process
+    */
+   public abstract void tuneIndex(Comparable comparable, Index comparableIndex,
+         int targetLength, Index targetIndex, MatchingState state);
+   
+   /**
+    * Tunes the indexes to indicate from which <code>comparable</code> and
+    * target components comparison should start.
+    * <p>
+    * Is called when the target of the comparison has one or more suffixes.
+    * 
+    * @param comparable        object that will perform the comparison
+    * @param comparableIndex   the comparable index before being tuned
+    * @param targetLengthRange the length range of the comparison target
+    * @param targetIndex       the index of the target before being tuned
+    * @param state the state of the matching process
+    * @return <code>true</code> if the comparison start is postponed to be
+    *         performed on the target suffixes; <code>false</code> otherwise.
+    */
+   public abstract boolean tuneIndex(Comparable comparable,
+         Index comparableIndex,
+         LengthRange targetLengthRange, Index targetIndex, MatchingState state);
+   
+   public String toString()
+   {
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartState.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartState.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/ComparisonStartState.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,261 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+
+/**
+ * This state indicates whether comparison will start with the current target or
+ * with one of its suffixes.
+ * 
+ * @author Flavia Rainone
+ */
+public abstract class ComparisonStartState
+{
+   /**
+    * Indicates the next comparison will start executing with the current
+    * target.
+    */
+   public static final ComparisonStartState CURRENT_TARGET =
+      new ComparisonStartState("Current Target")
+   {
+      public void update(MatchingState state, Index targetIndex,
+            LengthRange targetLengthRange)
+      {
+         if (targetLengthRange.getPostPrefixMaxLength() == 0)
+         {
+            return;
+         }
+         if (targetIndex.getValue() > targetLengthRange.getLength())
+         {
+            state.comparisonStartState = ComparisonStartState.NEXT_SUFFIXES;
+         }
+         else if (targetIndex.getValue() == targetLengthRange.getLength() &&
+               targetIndex.getValue() == 
+                  targetLengthRange.getPostPrefix_SuffixDiff())
+         {
+            state.comparisonStartState =
+               ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT;
+         }
+         else
+         {
+            return;
+         }
+         targetIndex.comparisonPostponed();
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex, Object target, LengthRange targetLengthRange)
+      {
+         return state.comparisonEndState.getNextCharacter(state, comparable,
+               comparableIndex, target, targetLengthRange);
+      }
+
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex)
+      {
+         return state.comparisonEndState.getNextCharacter(state, comparable,
+               comparableIndex);
+      }
+      
+      public boolean isComparisonPostponed()
+      {
+         return false;
+      }
+   };
+   
+   /**
+    * Indicates the next comparison will start executing with the first
+    * component of the next target suffixes.
+    */   
+   public static final ComparisonStartState NEXT_SUFFIX_FIRST_COMPONENT =
+      new ComparisonStartState("First Component of Next Suffix")
+   {
+      public void update(MatchingState state, Index targetIndex,
+            LengthRange targetLengthRange)
+      {
+         if (targetLengthRange.getPostPrefixMaxLength() == 0 ||
+               targetIndex.getValue() < targetLengthRange.getLength())
+         {
+            state.comparisonStartState = ComparisonStartState.CURRENT_TARGET;
+            targetIndex.comparisonReady();
+         }
+         else if (targetIndex.getValue() != 
+            targetLengthRange.getPostPrefix_SuffixDiff())
+         {
+            state.comparisonStartState = ComparisonStartState.NEXT_SUFFIXES;
+         }
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex, Object target, LengthRange targetLengthRange)
+      {
+         return state.comparisonEndState.getNextCharacter(state, comparable,
+               comparableIndex, target, targetLengthRange);
+      }
+
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex)
+      {
+         return state.comparisonEndState.getNextCharacter(state, comparable,
+               comparableIndex);
+      }
+      
+      public boolean isComparisonPostponed()
+      {
+         return true;
+      }
+   };
+
+   /**
+    * Indicates the next comparison will start executing with some component
+    * of the next target suffixes.
+    */
+   public static final ComparisonStartState NEXT_SUFFIXES =
+      new ComparisonStartState("Next Suffixes")
+   {
+      public void update(MatchingState state, Index targetIndex,
+            LengthRange targetLengthRange)
+      {
+         if (targetLengthRange.getPostPrefixMaxLength() == 0 ||
+               targetIndex.getValue() < targetLengthRange.getLength())
+         {
+            state.comparisonStartState = ComparisonStartState.CURRENT_TARGET;
+            targetIndex.comparisonReady();
+         }
+         else if (targetIndex.getValue() == 
+            targetLengthRange.getPostPrefix_SuffixDiff())
+         {
+            state.comparisonStartState =
+               ComparisonStartState.NEXT_SUFFIX_FIRST_COMPONENT;
+         }
+      }
+      
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex, Object target, LengthRange targetLengthRange)
+      {
+         return Flags.ALL;
+      }
+
+      public char getNextCharacter(MatchingState state, Comparable comparable,
+            Index comparableIndex)
+      {
+         return Flags.ALL;
+      }
+      
+      public boolean isComparisonPostponed()
+      {
+         return true;
+      }
+   };
+
+   
+   /**
+    * A string that describes this comparison start state.
+    */
+   private String description;
+   
+   /**
+    * Private constructor.
+    */
+   private ComparisonStartState(String description)
+   {
+      this.description = description;
+   }
+   
+   /**
+    * Updates the current comparison start state.
+    * 
+    * @param state                     the matching state, that contains the
+    *                                  current comparison start state
+    * @param targetIndex               indicates from which target component
+    *                                  the next comparison will start
+    * @param targetLengthRange the minimum-maximum length range of the target
+    *                          suffixes and post-prefixes
+    */
+   public abstract void update(MatchingState state,
+         Index targetIndex, LengthRange targetLengthRange);
+
+   /**
+    * Returns the character that identifies the next target to be compared
+    * with a positive result (i.e., with no mismatches found). If a target not
+    * identified by this character is compared, the result will be certainly
+    * a {@link ComparisonResult#MISMATCH_FOUND mismatch}.
+    * <p>
+    * Is invoked when <code>target</code> and <code>targetLengthRange</code>
+    * are known.
+    *  
+    * @param state             the matching state, stores the current comparison
+    *                          start state
+    * @param comparable        the comparable that will perform the next
+    *                          comparison
+    * @param comparableIndex   indicates from which <code>comparable</code>
+    *                          component the next comparison will start
+    * @param target            the object that will be compared to <code>
+    *                          comparable</code>
+    * @param targetLengthRange the minimum-maximum length range of the target
+    *                          suffixes and post-prefixes
+    * @return                  the character that identifies the next target to
+    *                          be compared with a positive result. May return
+    *                          {@link Flags#ALL} to indicate that any target may
+    *                          have a positive result.
+    */
+   public abstract char getNextCharacter(MatchingState state,
+         Comparable comparable, Index comparableIndex, Object target,
+         LengthRange targetLengthRange);
+   
+   /**
+    * Returns the character that identifies the next target to be compared
+    * with a positive result (i.e., with no mismatches found). If a target not
+    * identified by this character is compared, the result will be certainly
+    * a {@link ComparisonResult#MISMATCH_FOUND mismatch}.
+    * <p>
+    * Is invoked when the last target compared and/or its length range are
+    * unknown.
+    * 
+    * @param state             the matching state, stores the current comparison
+    *                          start state
+    * @param comparable        the comparable that will perform the next
+    *                          comparison
+    * @param comparableIndex   indicates from which <code>comparable</code>
+    *                          component the next comparison will start
+    * @return                  the character that identifies the next target to
+    *                          be compared with a positive result. May return
+    *                          {@link Flags#ALL} to indicate that any target may
+    *                          have a positive result.
+    */
+   public abstract char getNextCharacter(MatchingState state,
+         Comparable comparable, Index comparableIndex);
+   
+   /**
+    * Returns a boolean indicating whether this state indicates that the
+    * comparison is postponed to start with a target suffix.
+    * @return <code>true</code> if comparison is postponed to a target suffix;
+    *         <code>false</code> otherwise.
+    */
+   public abstract boolean isComparisonPostponed();
+   
+   public String toString()
+   {
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Index.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Index.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Index.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,217 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Indicates from which target or comparable component a comparison will start.
+ * <p>
+ * Can be extended to store additional information about the comparable and
+ * target components.
+ *  
+ * @author Flavia Rainone
+ */
+public class Index
+{
+   /**
+    * Indicates from which component comparison should start.
+    */
+   private int value;
+   
+   /**
+    * Indicates comparison has been postponed to a target suffix.
+    * <p>
+    * When this field equals <code>true</code>, <code>value</code> is greater
+    * than the target length.
+    */
+   private boolean postponedComparison;
+   
+   /**
+    * Constructor.
+    * <p>
+    * Creates an index with zero value.
+    */
+   public Index ()
+   {
+      this.value = 0;
+   }
+
+   /**
+    * Returns the value of the index.
+    * 
+    * @return the index value, indicates from which component comparison should
+    *         start
+    */
+   public final int getValue()
+   { 
+      return value;
+   }
+   
+   /**
+    * Indicates if this index is in its initial state, which means its
+    * value is zero.
+    * <p>
+    * Clients can overwrite this method when there is additional data that
+    * defines whether an index is in its initial state or not.
+    * 
+    * @return <code>true</code> if this index is in its initial value; <code>
+    *         false</code> otherwise.
+    */
+   public boolean isInitialState()
+   {
+      return this.value == 0;
+   }
+   
+   /**
+    * This method should be called only by <code>PrefixFunction</code>
+    * implementations, to redefine the index as being its correspondent prefix
+    * function value.
+    * 
+    * @param value the prefix function value of this index
+    * @see PrefixFunction
+    */
+   public void applyPrefixFunction(int value)
+   {
+      this.value = value;
+   }
+   
+   /**
+    * Increments the index value by one.
+    */
+   public final void increment()
+   { 
+      increment(1);
+   }
+   
+   /**
+    * Increments the index value by <code>increment</code> units.
+    * 
+    * @param increment the number of units by which the index value will be
+    *                  incremented
+    */
+   public final void increment(int increment)
+   { 
+      this.value += increment;
+      this.valueChanged();
+   }
+   
+   /**
+    * Increments the current index value by <code>increment</code> units,
+    * without triggering the {@link #valueChanged() valueChanged} callback
+    * method.
+    * 
+    * @param increment the number of units by which the index value will be
+    *                  incremented
+    */
+   protected final void noCallBackIncrement(int increment)
+   {
+      this.value += increment;
+   }
+   
+   /**
+    * Resets the index value to zero. After this method is executed, this <code>
+    * Index</code> will be the same as an index created by the default
+    * constructor.
+    * <p>
+    * This method provides a way of avoiding the cost of creating new instances.
+    */
+   public final void reset()
+   { 
+      this.value = 0;
+      this.valueChanged();
+   }
+
+   /**
+    * Copies <code>indexToCopy</code>, so that this index becomes equivalent to
+    * <code>indexToCopy</code>.
+    * 
+    * @param indexToCopy index whose values will be copied
+    */
+   public void copy(Index indexToCopy)
+   { 
+      this.value = indexToCopy.value;
+      this.postponedComparison = indexToCopy.postponedComparison;
+   }
+   
+   /**
+    * Notifies this index that comparison is postponed to a target suffix.
+    * <p>
+    * This method is invoked only for target indexes.
+    */
+   public final void comparisonPostponed()
+   {
+      this.postponedComparison = true;
+   }
+   
+   /**
+    * Notifies this index that comparison is not postponed anymore. It is ready
+    * to start with the current target.
+    * <p>
+    * This method is always  invoked after {@link #comparisonPostponed()}.
+    */
+   public final void comparisonReady()
+   {
+      this.postponedComparison = false;
+   }
+   
+   /**
+    * Subtracts the apropriate number from this index value, so that this
+    * index becomes valid for matching the target suffixes.
+    * <p>
+    * For example, if this index value is 5, and the target length is 3, this
+    * index value could be updated to 2, to indicate comparison should start
+    * in the third target suffix component. Notice that not necessarily the
+    * target length is the number subtracted by this index value.  This number
+    * is chosen according to whether the comparison is postponed. If it is not,
+    * the target length itself is subtracted. If it is postponed, the result of
+    * {@link LengthRange#getPostPrefix_SuffixDiff()
+    * targetLengthRange.getPostPrefix_SuffixDiff()} is the number subtracted.
+    * <p>
+    * This method is invoked only for target indexes. 
+    * 
+    * @param targetLengthRange the length range of the last matched target (with
+    *                          a {@link MatchingResult#PARTIAL_MATCH partial
+    *                          match} result)
+    */
+   public final void update(LengthRange targetLengthRange)
+   {
+      if (postponedComparison) // comparison was postponed to a target suffix
+      {
+         this.value -= targetLengthRange.getPostPrefix_SuffixDiff();
+      }
+      else // !comparisonPostponed means comparison took place
+      {
+         this.value = 0; // = value - targetLengthRange.getLength();
+      }
+   }
+  
+   /**
+    * Callback method, called everytime the index value is changed by
+    * the <code>increment</code> or <code>reset</code> methods.
+    */
+   protected void valueChanged()
+   {}
+   
+   public String toString()
+   {
+      return String.valueOf(this.value);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRange.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRange.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRange.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,217 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Provides information about the length of a target, its suffixes and
+ * post-prefixes.
+ * <p>
+ * This class assumes as default that a suffix length is equal to the length of
+ * the correspondent post-prefix length minus the target length. The client
+ * can change this by extending this class and overriding the
+ * {@link #getPostPrefix_SuffixDiff()} method.
+ *  
+ * @author Flavia Rainone
+ *
+ */
+public class LengthRange
+{
+   /**
+    * The number of components contained in the target.
+    */
+   private byte length;
+   
+   /**
+    * The number of components contained in the smallest target post-prefix.
+    */
+   private byte postPrefixMinLength;
+   
+   /**
+    * The number of components contained in the biggest target post-prefix.
+    */
+   private byte postPrefixMaxLength;
+   
+   /**
+    * Constructor, creates an object that provides information about the
+    * length of the suffix and post-prefix of a target.
+    * <p>
+    * Should be called when the target has only one suffix.
+    * 
+    * @param length           the number of components contained in the
+    *                         target
+    * @param postPrefixLength the number of components contained in the
+    *                         target post-prefix
+    */
+   public LengthRange(byte length, byte postPrefixLength)
+   {
+      this(length, postPrefixLength, postPrefixLength);
+   }
+   
+   /**
+    * Constructor, creates an object that provides information about the
+    * length of the suffixes and post-prefixes of a target.
+    * <p>
+    * Should be called when the target has more than one suffix.
+    * 
+    * @param length              the number of components contained in the
+    *                            target
+    * @param postPrefixMinLength the number of components contained in the
+    *                            smallest target post-prefix
+    * @param postPrefixMaxLength the number of components contained in the
+    *                            biggest target post-prefix
+    */
+   public LengthRange(byte length, byte postPrefixMinLength,
+         byte postPrefixMaxLength)
+   {
+      this.length = length;
+      this.postPrefixMinLength = postPrefixMinLength;
+      this.postPrefixMaxLength = postPrefixMaxLength;
+   }
+   
+   /**
+    * Resets the data contained in this intance.
+    * <p>
+    * This method avoids the cost of creating a new instance since, once this
+    * method is executed, this length range will be equal to the result of
+    * calling the constructor with the same parameters.
+    * 
+    * @param length              the number of components contained in the
+    *                            target
+    * @param postPrefixMinLength the number of components contained in the
+    *                            smallest target post-prefix
+    * @param postPrefixMaxLength the number of components contained in the
+    *                            biggest target post-prefix
+    */
+   public final void reset(byte length, byte postPrefixMinLength,
+         byte postPrefixMaxLength)
+   {
+      this.length = length;
+      this.postPrefixMinLength = postPrefixMinLength;
+      this.postPrefixMaxLength = postPrefixMaxLength;
+   }
+
+   /**
+    * Returns the number of components contained in the target.
+    * 
+    * @return the number of components contained in the target
+    */
+   public final byte getLength()
+   {
+      return this.length;
+   }
+   
+   /**
+    * Returns the number that must be subtracted from a post-prefix length
+    * to retrieve the correpondent suffix length.
+    * <p>
+    * This implementation returns the target length, but can be ovewritten by
+    * the client as needed.
+    * 
+    * @return the length of the target
+    */
+   public byte getPostPrefix_SuffixDiff()
+   {
+      return this.length;
+   }
+   
+   /**
+    * Returns the number of components contained in the smallest suffix.
+    * 
+    * @return the number of components contained in the smallest suffix
+    */
+   public final byte getSuffixMinLength()
+   {
+      return (byte) (this.postPrefixMinLength -
+            this.getPostPrefix_SuffixDiff());
+   }
+   
+   /**
+    * Returns the number of components contained in the biggest suffix.
+    * 
+    * @return the number of components contained in the biggest suffix
+    */
+   public final byte getSuffixMaxLength()
+   {
+      return (byte) (this.postPrefixMaxLength -
+            this.getPostPrefix_SuffixDiff());
+   }
+   
+   /**
+    * Returns the number of components contained in the smallest target
+    * post-prefix.
+    * 
+    * @return the number of components contained in the smallest target
+    * post-prefix
+    */
+   public final byte getPostPrefixMinLength()
+   {
+      return this.postPrefixMinLength;
+   }
+
+   /**
+    * Returns the number of components contained in the biggest target
+    * post-prefix.
+    * 
+    * @return the number of components contained in the biggest target
+    * post-prefix
+    */
+   public final byte getPostPrefixMaxLength()
+   {
+      return this.postPrefixMaxLength;
+   }
+   
+   /**
+    * Updates the length range of a target.
+    * <p>
+    * Should be called when a new suffix is added to the target.
+    * 
+    * @param newPostPrefixLength the number of components contained in the
+    *                            concatenation of the target and its new suffix 
+    */
+   public final void update(byte newPostPrefixLength)
+   {
+      this.update(newPostPrefixLength, newPostPrefixLength);
+   }
+
+   /**
+    * Updates the length range of a target.
+    * <p>
+    * Should be called when a new suffix group is added to the target.
+    * 
+    * @param ppMinLength the number of components contained in the concatenation
+    *                    of the target and the smallest suffix in the group
+    * @param ppMaxLength the number of components contained in the concatenation
+    *                    of the target and the biggest suffix in the group 
+    */
+   public final void update(byte ppMinLength, byte ppMaxLength)
+   {
+      postPrefixMinLength = (byte) Math.min(postPrefixMinLength, ppMinLength);
+      postPrefixMaxLength = (byte) Math.max(postPrefixMaxLength, ppMaxLength);
+   }
+   
+   public String toString()
+   {
+      return "[length=" + this.length + ", ppMinLength=" +
+         this.postPrefixMinLength + ", ppMaxLength=" + this.postPrefixMaxLength
+         + "]";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestriction.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestriction.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/LengthRestriction.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,175 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+
+/**
+ * One of the components of <code>MatcherProfile</code>.
+ * <p>
+ * Defines a restriction between the number of available comparable components
+ * and the number of available target components (the number of available
+ * components is the number of components that need to be compared and
+ * matched).
+ * <p>
+ * This restriction must apply to a matching scenario before the matching
+ * execution proceeds.
+ * 
+ * @author Flavia Rainone
+ * @see MatcherProfile
+ */
+abstract class LengthRestriction
+{
+   /**
+    * Restricts the number of available comparable components to be less than
+    * or equal to the number of available target components.
+    */
+   public static final LengthRestriction LESS_OR_EQUAL = new LengthRestriction(
+         "Less or Equal Restriction")
+   {
+      protected boolean appliesTo(int comparableLength, int targetLength)
+      {
+         return comparableLength <= targetLength; 
+      }
+      
+      protected boolean appliesTo(int comparableLength, int minimumTargetLength,
+            int maximumTargetLength)
+      { 
+         return comparableLength <= maximumTargetLength; 
+      }
+   };
+   
+   /**
+    * Restricts the number of available comparable components to be equal to the
+    * number of available target components.
+    */   
+   public static final LengthRestriction EQUAL = new LengthRestriction(
+         "Equal Restriction")
+   {
+      protected boolean appliesTo(int comparableLength, int targetLength)
+      { 
+         return comparableLength == targetLength; 
+      }
+      
+      protected boolean appliesTo(int comparableLength, int minimumTargetLength,
+            int maximumTargetLength)
+      {
+         return comparableLength >= minimumTargetLength &&
+            comparableLength <= maximumTargetLength;
+      }
+   };
+   
+   /**
+    * The string that describes this length restriction.
+    */
+   private String description;
+   
+   /**
+    * Private constructor.
+    */
+   private LengthRestriction(String description)
+   {
+      this.description = description;
+   }
+   
+   
+   /**
+    * Checks if the restriction applies to the length of available comparable
+    * and target components.
+    * <p>
+    * This method is called when the target has no suffixes.
+    * 
+    * @param comparable      the comparable that will perform comparison
+    * @param comparableIndex the index of comparable, indicates from which
+    *                        component the comparison will start
+    * @param targetLength    the length of the target, indicates how many
+    *                        components it is made of
+    * @param targetIndex     the index of target, indicates from which target
+    *                        component the comparison will start
+    * @return <code>true</code> if the restriction applies to the scenario
+    *         described in the parameters
+    */
+   public boolean appliesTo(Comparable comparable, Index comparableIndex,
+         int targetLength, Index targetIndex)
+   {
+      return appliesTo(comparable.getPostPrefixLength() -
+            comparableIndex.getValue(), targetLength - targetIndex.getValue());
+   }
+
+   /**
+    * Checks if the restriction applies to the length of available comparable
+    * and target components.
+    * <p>
+    * This method is called when the target has one or more suffixes.
+    * 
+    * @param comparable        the comparable that will perform comparison
+    * @param comparableIndex   the index of comparable, indicates from which
+    *                          component the comparison will start
+    * @param targetLengthRange the length range of the target, indicates how
+    *                          many components its suffixes and post-prefixes
+    *                          contain
+    * @param targetIndex       the index of target, indicates from which target
+    *                          component the comparison will start
+    * @return <code>true</code> if the restriction applies to the scenario
+    *         described in the parameters
+    */
+   public boolean appliesTo(Comparable comparable, Index comparableIndex,
+         LengthRange targetLengthRange, Index targetIndex)
+   {
+      return appliesTo(
+            comparable.getPostPrefixLength() - comparableIndex.getValue(),
+            targetLengthRange.getPostPrefixMinLength() - targetIndex.getValue(),
+            targetLengthRange.getPostPrefixMaxLength() - targetIndex.getValue())
+            ;
+   }
+ 
+   /**
+    * Checks if the restriction applies to the comparable and target lengths.
+    * 
+    * @param comparableLength the number of comparable elements available for
+    *                         comparison
+    * @param targetLength     the number of target elements available for
+    *                         comparison
+    * @return <code>true</code> if the restriction applies to these lengths
+    */
+   protected abstract boolean appliesTo(int comparableLength, int targetLength);
+   
+   /**
+    * Checks if the restriction applies to the comparable and target lengths.
+    * <p>
+    * Called when the target length is specified by an interval.
+    * 
+    * @param comparableLength    the number of comparable elements available for
+    *                            comparison
+    * @param minimumTargetLength the minimum number of target elements available
+    *                            for comparison
+    * @param maximumTargetLength the maximum number of target elements available
+    *                            for comparison                           
+    * @return <code>true</code> if the restriction applies to these lengths
+    */   
+   protected abstract boolean appliesTo(int comparableLength,
+         int minimumTargetLength, int maximumTargetLength);
+   
+   public String toString()
+   {
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Matcher.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Matcher.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/Matcher.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,226 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Matches a <i>matchable expression</i> part (represented by a <code>Comparable
+ * </code> instance) against a target. The matching algorithm executed by the
+ * matcher is defined by its profile.
+ * <p>
+ * A matcher is contained in a sequence of matchers, which can match a
+ * <i>matchable expression</i> against a complete target. To know how to use
+ * a matcher sequence, refer to {@link MatcherFactory} and to the {@link
+ * org.jboss.aop.joinpoint.graph.tree.search.match description of this package}.
+ * 
+ * @author Flavia Rainone
+ * @see Comparable
+ * @see MatcherFactory
+ * @see MatcherProfile
+ */
+public class Matcher
+{
+   /**
+    * Defines the matching algorithm.
+    */
+   private MatcherProfile profile;
+   
+   /**
+    * Performs comparisons with targets.
+    */
+   private Comparable comparable;
+   
+   /**
+    * Constructor.
+    * 
+    * @param profile    defines the matching algorithm to be executed by the
+    *                   created matcher
+    * @param comparable the object to be compared against the target during the
+    *                   matching process. Represents a <i>matchable expression
+    *                   </i> part.
+    */
+   Matcher (MatcherProfile profile, Comparable comparable)
+   {
+      this.profile = profile;
+      this.comparable = comparable;
+   }
+   
+   /**
+    * Executes the matching process against the target.
+    * <p>
+    * The indexes and <code>state</code> objects are changed during execution
+    * and, thus, are part of the method outcome. 
+    * <p>
+    * This method should be called when the target has no suffixes at all, i.e.,
+    * when the target is the last component of the "complete target".
+    * 
+    * @param target          the matching target, that will be compared during
+    *                        the matching execution. Note that the comparison is
+    *                        performed by the <code>Comparable</code> associated
+    *                        with this matcher and, consequently, this target
+    *                        must be of a type compatible with the comparable.
+    * @param targetLength    the number of components contained in <code>
+    *                        target</code>
+    * @param targetIndex     indicates from which <code>target</code> component
+    *                        the matching should start. After this method runs,
+    *                        this index indicates in which <code>target</code>
+    *                        component the matching finished. This same index
+    *                        should be passed along with <code>target</code>
+    *                        to the next matcher in the sequence if the matching
+    *                        result is positive.
+    * @param comparableIndex indicates from which comparable component the
+    *                        matching should start.
+    * @param state           contains data about the state of the matching
+    *                        process. This state must be the same state used in
+    *                        the previous matching executions associated with
+    *                        the same matchable expression and complete target.
+    * @return the result of the match
+    * @see MatchingResult
+    */
+   public MatchingResult matches(Object target, int targetLength, Index targetIndex,
+         Index comparableIndex, MatchingState state)
+   {
+      profile.comparisonStart.tuneIndex(comparable, comparableIndex,
+            targetLength, targetIndex, state);
+      if (!profile.restriction.appliesTo(comparable,
+            comparableIndex, targetLength, targetIndex))
+      {
+         return MatchingResult.NEGATIVE_MATCH;
+      }
+      ComparisonResult result = profile.algorithm.execute(comparable,
+            comparableIndex, target, targetIndex, targetLength,
+            profile.restriction, state.comparisonState);
+      return profile.resultMap[result.getId()];
+   }
+   
+   
+   /**
+    * Executes the matching process against the target.
+    * <p>
+    * The indexes and <code>state</code> objects are changed during execution
+    * and, thus, are part of the method outcome. 
+    * <p>
+    * This method should be called when the target has no suffixes at all, i.e.,
+    * when the target is the last component of the "complete target".
+    * 
+    * @param target            the matching target, that will be compared during
+    *                          the matching execution. Note that the comparison
+    *                          is performed by the <code>Comparable</code>
+    *                          associated with this matcher and, consequently,
+    *                          this target must be of a type compatible with the
+    *                          comparable.
+    * @param targetLengthRange the maximum-minimum range of the number of
+    *                          components contained in the <code>target</code>
+    *                          suffixes and post-prefixes.
+    * @param targetIndex       indicates from which <code>target</code>
+    *                          component the matching should start. After this
+    *                          method runs, this index indicates in which <code>
+    *                          target</code> component the matching finished.
+    *                          This same index should be passed along with
+    *                          <code>target</code> to the next matcher in the
+    *                          sequence if the matching result is positive.
+    * @param comparableIndex   indicates from which comparable component the
+    *                          matching should start. After this method runs,
+    *                          this index indicates in which comparable
+    *                          component the matching finished. If the result of
+    *                          the matching is partial, the same index should
+    *                          be passed to this same matcher again, along with
+    *                          the next target and a reset target index.
+    * @param state             contains data about the state of the matching
+    *                          process. This state must be the same state used
+    *                          in the previous matching executions associated
+    *                          with the same matchable expression and complete
+    *                          target.
+    * @return the result of the match
+    * @see MatchingResult
+    */
+   public MatchingResult matches(Object target, LengthRange targetLengthRange,
+         Index targetIndex, Index comparableIndex, MatchingState state)
+   {
+      if (profile.comparisonStart.tuneIndex(comparable, comparableIndex,
+            targetLengthRange, targetIndex, state))
+      {
+         return MatchingResult.PARTIAL_MATCH;
+      }
+      if (!profile.restriction.appliesTo(comparable,
+            comparableIndex, targetLengthRange, targetIndex))
+      {
+         return MatchingResult.NEGATIVE_MATCH;
+      }
+      ComparisonResult result = profile.algorithm.execute(comparable,
+            comparableIndex, target, targetIndex, targetLengthRange,
+            profile.restriction, state.comparisonState);
+      return profile.resultMap[result.getId()];
+   }
+   
+   /**
+    * Returns the character that identifies the next target that can be matched
+    * with a non-negative result. If a target not identified by this character
+    * is matched, the result will be certainly negative.
+    * <p>
+    * Should be called whenever <code>target</code> and <code>targetLengthRange
+    * </code>are known, because this info allows a more accurate response. 
+    * 
+    * @param comparableIndex   indicates from which comparable component the
+    *                          next matching will execute
+    * @param target            the last matched target (with a positive result)
+    * @param targetLengthRange the maximum-minimum range of the length of the
+    *                          <code>target</code> suffixes and post-prefixes.
+    * @param state             the state of the matching process
+    * @return the character that identifies the next target that can be matched
+    *         with a non-negative result. May be <code>Flags.ALL</code> to
+    *         indicate that this matcher cannot infer which targets will have a
+    *         negative result.
+    */
+   public char getNextCharacter(Index comparableIndex, Object target,
+         LengthRange targetLengthRange, MatchingState state)
+   {
+      return profile.algorithm.getNextCharacter(comparable, comparableIndex,
+            target, targetLengthRange, state);
+   }
+
+   /**
+    * Returns the character that identifies the next target that can be matched
+    * with a non-negative result. If a target not identified by this character
+    * is matched, the result will be certainly negative.
+    * <p>
+    * Should be called if the last matched target and its length range are
+    * unknown.
+    * 
+    * @param comparableIndex   indicates from which comparable component the
+    *                          next matching will execute
+    * @param state             the state of the matching process
+    * @return the character that identifies the next target that can be matched
+    *         with a non-negative result. May be <code>Flags.ALL</code> to
+    *         indicate that this matcher cannot infer which targets will have a
+    *         negative result.
+    */
+   public char getNextCharacter(Index comparableIndex, MatchingState state)
+   {
+      return profile.algorithm.getNextCharacter(comparable, comparableIndex,
+            state);
+   }
+   
+   public String toString()
+   {
+      return "MATCHER[" + profile + ", " + comparable + "]";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactory.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherFactory.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,110 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Creates a sequence of matchers.<p>
+ * This sequence can be used to match a <i>matchable expression</i> against a
+ * complete target. To execute a matching process, the client must call each
+ * matcher of the sequence, in sequential order, and should consider the process
+ * as finished only when all matchers have stated a positive result, or when one
+ * of them returned a negative result. For more information on the generated
+ * matcher sequence, refer to {@link org.jboss.aop.joinpoint.graph.tree.search.match this
+ * package description}.
+ * 
+ * @author Flavia Rainone
+ *
+ */
+public abstract class MatcherFactory
+{
+   /**
+    * Creates a sequence of matchers capable of matching <code>
+    * matchableExpression</code> against a complete target.
+    * 
+    * @param matchableExpression the element that will be matched by the
+    *                            generated matcher sequence.
+    * @param comparableFactory   a factory that will be used to create a <code>
+    *                            Comparable</code> for each part of <code>
+    *                            matchableExpression</code>. The comparable
+    *                            instances are created in the same order as the
+    *                            <code>matchableExpression</code> parts are
+    *                            found in the element.
+    * @param profile             defines the profile of each matcher in the
+    *                            sequence
+    * @return a sequence of matchers that can match <code>
+    *         matchableExpresion</code> against a complete target
+    * @see ComparableFactory
+    * @see MatcherSequenceProfile
+    */
+   public static final Matcher[] createSequence(String matchableExpression,
+         ComparableFactory comparableFactory,
+         MatcherSequenceProfile profile)
+   {
+      Collection matchers = new ArrayList();
+      char separator = comparableFactory.getSeparator();
+      int begin = 0;
+      int end = matchableExpression.indexOf(separator);
+      Comparable comparable;
+      String expression;
+      // invoke factory notification method
+      comparableFactory.startCreation();
+      if (end == -1)
+      {
+         // create unique matcher
+         comparable = comparableFactory.create(matchableExpression,
+               profile.uniqueMatcherProfile);
+         matchers.add(new Matcher(profile.uniqueMatcherProfile, comparable));
+      }
+      else {
+         // create first matcher
+         expression = matchableExpression.substring(begin, end);
+         comparable = comparableFactory.create(expression,
+               profile.firstMatcherProfile);
+         matchers.add(new Matcher(profile.firstMatcherProfile, comparable));
+         begin = end + 1;
+         end = matchableExpression.indexOf(separator, begin);
+         // create middle matchers
+         while (end > 0)
+         {
+            expression = matchableExpression.substring(begin, end);
+            comparable = comparableFactory.create(expression,
+                  profile.middleMatchersProfile);
+            matchers.add(new Matcher(profile.middleMatchersProfile, comparable));
+            begin = end + 1;
+            end = matchableExpression.indexOf(separator, begin);
+         }
+         // create last matcher
+         expression = matchableExpression.substring(begin);
+         comparable = comparableFactory.create(expression,
+               profile.lastMatcherProfile);
+         matchers.add(new Matcher(profile.lastMatcherProfile, comparable));
+      }
+      // invoke factory notification method
+      comparableFactory.stopCreation();
+      // create and return sequence
+      Matcher[] matcherArray = new Matcher[matchers.size()];
+      return (Matcher[]) matchers.toArray(matcherArray);
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherProfile.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherProfile.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherProfile.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,198 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Represents a property that must hold between the complete target and the
+ * comparable, so that the matching process ends with a positive result.
+ * Henceforth, this class defines the matching algorithm, that will be executed
+ * by the <code>Matcher.matches</code> methods to verify whether such property
+ * holds.
+ * <p>
+ * Every matcher has a profile.
+ * 
+ * @author Flavia Rainone
+ * @see Matcher
+ * @see MatcherSequenceProfile
+ */
+public class MatcherProfile
+{
+   static
+   {
+      // SIMPLE profile creation
+      MatchingResult[] simpleMap =
+         new MatchingResult[ComparisonResult.getNumberOfInstances()];
+      simpleMap[ComparisonResult.MISMATCH_FOUND.getId()] =
+         MatchingResult.NEGATIVE_MATCH;
+      simpleMap[ComparisonResult.COMPARABLE_END.getId()] =
+         MatchingResult.NEGATIVE_MATCH;
+      simpleMap[ComparisonResult.TARGET_END.getId()] =
+         MatchingResult.PARTIAL_MATCH;
+      simpleMap[ComparisonResult.BOTH_ENDS.getId()] =
+         MatchingResult.POSITIVE_MATCH;
+      SIMPLE = new MatcherProfile("Simple Profile", ComparisonStart.LOOSE,
+            LengthRestriction.EQUAL, ComparisonAlgorithm.SIMPLE, simpleMap);
+      
+      // PREFIX profile creation
+      MatchingResult[] prefixMap =
+         new MatchingResult[ComparisonResult.getNumberOfInstances()];
+      prefixMap[ComparisonResult.MISMATCH_FOUND.getId()] =
+         MatchingResult.NEGATIVE_MATCH;
+      prefixMap[ComparisonResult.COMPARABLE_END.getId()] =
+         MatchingResult.POSITIVE_MATCH;
+      prefixMap[ComparisonResult.TARGET_END.getId()] =
+         MatchingResult.PARTIAL_MATCH;
+      prefixMap[ComparisonResult.BOTH_ENDS.getId()] =
+         MatchingResult.POSITIVE_MATCH;
+      PREFIX = new MatcherProfile("Prefix Profile", ComparisonStart.LOOSE,
+            LengthRestriction.LESS_OR_EQUAL, ComparisonAlgorithm.SIMPLE,
+            prefixMap);
+      
+      // PATTERN profile creation
+      PATTERN = new MatcherProfile("Pattern Profile", ComparisonStart.LOOSE,
+            LengthRestriction.LESS_OR_EQUAL, ComparisonAlgorithm.KMP,
+            prefixMap); // same map as PREFIX
+      
+      // SUFFIX profile creation
+      SUFFIX = new MatcherProfile("Suffix Profile", ComparisonStart.TIGHT,
+            LengthRestriction.LESS_OR_EQUAL, ComparisonAlgorithm.KMP,
+            simpleMap); // same map as SIMPLE
+   }
+   
+   /**
+    * Simple profile, defines the matching algorithm as verifying whether the
+    * the target is equal to the comparable.
+    */
+   public static final MatcherProfile SIMPLE;
+   
+   /**
+    * Prefix profile, defines the matching algorithm as verifying whether the
+    * target starts with the comparable.
+    */
+   public static final MatcherProfile PREFIX;
+   
+   /**
+    * Pattern profile, defines the matching algorithm as verifying whether the
+    * target contains the comparable.
+    */
+   public static final MatcherProfile PATTERN;
+   
+   /**
+    * Suffix profile, defines the matching algorithm as verifying whether the
+    * target ends with the comparable.
+    */
+   public static final MatcherProfile SUFFIX;
+   
+   /**
+    * Used to generate ids for the instances.
+    */
+   private static int ID_COUNTER = 0;
+   
+   /**
+    * Returns the number of <code>MatcherProfile</code> instances.
+    * 
+    * @return the number of <code>MatcherProfile</code> instances
+    */
+   public static int getNumberOfInstances()
+   {
+      return 4;
+   }
+   
+   /**
+    * The identifier of a <code>MatcherProfile</code> instance.
+    */
+   private int id;
+   
+   /**
+    * A string that describes this profile.
+    */
+   private String description;
+   
+   /**
+    * Tunes the comparable and target indexes to define where the comparison
+    * should start.
+    */
+   ComparisonStart comparisonStart;
+   
+   /**
+    * A restriction that must apply to the length of available comparable
+    * components and of available target components. If the restriction doesn't
+    * apply, the matching process terminates with a negative result.
+    */
+   LengthRestriction restriction;
+   
+   /**
+    * The algorithm that defines how the functionality of a <code>Comparable
+    * </code> is used by the <code>Matcher</code>.
+    */
+   ComparisonAlgorithm algorithm;
+   
+   /**
+    * Maps a <code>ComparisonResult</code> to the <code>MatchingResult</code>
+    * that should be returned by a <code>Matcher</code>.
+    */
+   MatchingResult[] resultMap;
+   
+   /**
+    * Constructor.
+    * 
+    * @param comparisonStart defines how the indexes should be tuned for
+    *                        comparison
+    * @param restriction     defines a restriction that must apply to the length
+    *                        of comparable components and of target components
+    *                        available for comparison
+    * @param algorithm       defines how <code>Comparable</code> functionality
+    *                        should be used in the matching process
+    * @param resultMap       maps a <code>ComparisonResult</code> to a <code>
+    *                        MatchingResult</code>
+    */
+   private MatcherProfile(String description, ComparisonStart comparisonStart,
+         LengthRestriction restriction, ComparisonAlgorithm algorithm,
+         MatchingResult[] resultMap)
+   {
+      this.description = description;
+      this.comparisonStart = comparisonStart;
+      this.restriction = restriction;
+      this.algorithm = algorithm;
+      this.resultMap = resultMap;
+      this.id = ID_COUNTER++;
+   }
+   
+   /**
+    * Returns the id of the <code>MatcherProfile</code> instance.
+    * 
+    * @return an id. Notice that all <code>MatcherProfile</code> instances
+    *         have an id, which is different for each instance. The smallest id 
+    *         is <code>0</code>, and for each existent id <code>i</code> there
+    *         is also an id <code>i - 1</code> if <code>i</code> > <code>1
+    *         </code>.
+    */
+   public int getId()
+   {
+      return this.id;
+   }
+   
+   public String toString()
+   {
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherSequenceProfile.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherSequenceProfile.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatcherSequenceProfile.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * The profile of a matcher sequence. Defines the profile of each matcher in the
+ * sequence.
+ * 
+ * @author Flavia Rainone
+ * @see MatcherProfile
+ * @see MatcherFactory#createSequence(String, ComparableFactory, MatcherSequenceProfile)
+ */
+public class MatcherSequenceProfile
+{
+   /**
+    * The profile of the first matcher in the sequence.
+    */
+   MatcherProfile firstMatcherProfile;
+   
+   /**
+    * The profile of all matchers in the sequence that not the first nor the
+    * last ones. 
+    */
+   MatcherProfile middleMatchersProfile;
+   
+   /**
+    * The profile of the last matcher in the sequence. 
+    */
+   MatcherProfile lastMatcherProfile;
+   
+   /**
+    * The profile of the unique matcher in the sequence, utilized by
+    * {@link MatcherFactory} when the sequence contains only one matcher.
+    */
+   MatcherProfile uniqueMatcherProfile;
+   
+   /**
+    * Constructor. Creates the profile of an entire sequence of matchers.
+    * 
+    * @param firstMatcherProfile   the profile of the first matcher in the
+    *                              sequence
+    * @param middleMatchersProfile the profile of all matchers in the sequence
+    *                              that not the first nor the last ones
+    * @param lastMatcherProfile    the profile of the last matcher in the
+    *                              sequence
+    * @param uniqueMatcherProfile  the profile used in the unique matcher in the
+    *                              sequence, utilized by <code>MatcherFactory
+    *                              </code> when the sequence contains only one
+    *                              matcher
+    * @see MatcherFactory
+    */
+   public MatcherSequenceProfile(MatcherProfile firstMatcherProfile,
+   MatcherProfile middleMatchersProfile,
+   MatcherProfile lastMatcherProfile,
+   MatcherProfile uniqueMatcherProfile)
+   {
+      this.firstMatcherProfile = firstMatcherProfile;
+      this.middleMatchersProfile = middleMatchersProfile;
+      this.lastMatcherProfile = lastMatcherProfile;
+      this.uniqueMatcherProfile = uniqueMatcherProfile;
+   }
+   
+   public String toString()
+   {
+      return "[first=" + firstMatcherProfile + ", middle=" +
+         middleMatchersProfile + ", last=" + lastMatcherProfile + ", unique=" +
+         uniqueMatcherProfile + "]";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingResult.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingResult.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingResult.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * The result of a matching execution.
+ * 
+ * @author Flavia Rainone
+ * @see Matcher#matches(Object, int, Index, Index, MatchingState)
+ * @see Matcher#matches(Object, LengthRange, Index, Index, MatchingState)
+ */
+public class MatchingResult
+{
+   /**
+    * Indicates that the matching is complete and has a positive result.
+    * <p>
+    * When this result is returned by a matcher, the client should pass the same
+    * target and the target index to the next matcher in the sequence. If this
+    * result is returned by the last matcher, the matching process is finished
+    * with a positive result.
+    */
+   public static final MatchingResult POSITIVE_MATCH = 
+      new MatchingResult("Positive Match");
+   
+   /**
+    * Indicates that matching is not complete, so its result cannot be inferred.
+    * <p>
+    * When this result is returned by a matcher, the client should pass the
+    * matched target suffix to the same matcher in the sequence, using the
+    * same comparable index and the {@link Index#update(LengthRange) updated}
+    * target index. If there are more than one suffix, the state and index must
+    * be copied for each suffix. If there are no suffixes, the matching process
+    * is finished and with a negative result, since the matcher is asking for a
+    * suffix that doesn't exist.
+    */
+   public static final MatchingResult PARTIAL_MATCH =
+      new MatchingResult("Partial Match");
+   
+   /**
+    * Indicates that the matching is complete and has a negative result.
+    * <p>
+    * When this result is returned by a matcher, the client should consider the
+    * matching process as finished and with a negative result.
+    */
+   public static final MatchingResult NEGATIVE_MATCH =
+      new MatchingResult("Negative Match");
+   
+   /////////////////////////////////////////////////////////////////////////////
+   
+   /** The string that describes this result. */
+   private String description;
+   
+   /**
+    * Private constructor.
+    * 
+    * @param description the description of the matching result to be created.
+    */
+   private MatchingResult(String description)
+   {
+      this.description = description;
+   }
+   
+   public String toString(){
+      return this.description;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingState.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingState.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/MatchingState.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,315 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * The state of a matching process, is associated with a complete target and
+ * with a matcher sequence. If the client needs to pass more than one target
+ * suffix to the next matcher in the sequence, it needs to copy the matching
+ * state of the previous matching execution for each suffix matching, since each
+ * target suffix represents a different complete target.
+ * <p>
+ * The client can associate a comparison state with the matching
+ * state. This comparison state will be passed along to the comparable on every
+ * call to the {@link Comparable#compare Comparable.compare} method, so it can
+ * store data that might happen to be important in future comparisons. Notice
+ * that the same state object is passed along to every comparable in the matcher
+ * sequence, since this object is associated with the matching state. The
+ * comparable is completely responsible for managing this state data. To
+ * assigin a comparison state to the matching state, invoke the {@link
+ * #MatchingState(State)} constructor instead of the default one.
+ * 
+ * @author Flavia Rainone
+ */
+public class MatchingState implements State
+{
+   /**
+    * Dummy state, is assigned to <code>comparisonState</code> when the client
+    * doesn't provide one.
+    */
+   private static final State DUMMY_STATE = new DummyState();
+   
+   /**
+    * The state value, answers to all methods in this class, since their
+    * behaviour is dependent on this value.
+    */
+   
+   /**
+    * The comparison state, stores data relevant to comparables.
+    */
+   State comparisonState;
+   
+   /**
+    * Indicates whether the comparison is scheduled to start in the current
+    * target, in a target suffix, or in the firt component of the next target
+    * suffix.
+    */
+   ComparisonStartState comparisonStartState;
+   
+   /**
+    * Indicates whether the comparison, in case the match outcomes a positive
+    * result, will finish exactly in the end of the longer complete target
+    * (tight comparison) or not (loose comparison).
+    */
+   ComparisonEndState comparisonEndState;
+   
+   /**
+    * Saved comparison state, is the backup of {@link #comparisonState}.
+    * <p>
+    * Is assigned by the {@link #copy} method and read by the {@link
+    * #rollback()} method.
+    */
+   State savedComparisonState;
+   
+   /**
+    * Saved comparison start state, is the backup of {@link
+    * #comparisonStartState }.
+    * <p>
+    * Is assigned by the {@link #copy} method and read by the {@link
+    * #rollback()} method.
+    */
+   ComparisonStartState savedComparisonStartState;
+   
+   /**
+    * Saved comparison end state, is the backup of {@link #comparisonEndState}.
+    * <p>
+    * Is assigned by the {@link #copy} method and read by the {@link
+    * #rollback()} method.
+    */
+   ComparisonEndState savedComparisonEndState;
+   
+
+   /**
+    * Constructor. Creates a initial state of a matching process, and should be
+    * passed to the first matcher in the sequence.
+    * <p>
+    * Invoke this constructor when there is no need of a comparison state.
+    */
+   public MatchingState()
+   {
+      comparisonStartState = ComparisonStartState.CURRENT_TARGET;
+      comparisonEndState = ComparisonEndState.LOOSE;
+      this.comparisonState = DUMMY_STATE;
+   }
+   
+   /**
+    * Constructor. Creates a initial state of a matching process, and should be
+    * passed to the first matcher in the sequence.
+    * <p>
+    * Invoke this constructor when the comparables associated with the matcher
+    * sequence will need a comparison state to store comparison relevant data.
+    * 
+    * @param comparisonState the comparison state that will be passed along to
+    *                        the comparables on every call to their {@link
+    *                        Comparable#compare compare} method
+    */
+   public MatchingState(State comparisonState)
+   {
+      comparisonStartState = ComparisonStartState.CURRENT_TARGET;
+      comparisonEndState = ComparisonEndState.LOOSE;
+      this.comparisonState = comparisonState;
+   }
+
+   /**
+    * Resets this state and the comparison state associated with it, if there is
+    * one.
+    * 
+    * @see org.jboss.aop.joinpoint.graph.tree.search.match.State#reset()
+    */
+   public void reset()
+   {
+      comparisonStartState = ComparisonStartState.CURRENT_TARGET;
+      comparisonEndState = ComparisonEndState.LOOSE;
+      this.comparisonState.reset();
+   }
+   
+   /**
+    * Saves the data contained in this state and in the comparison state
+    * associated with it, if there is one.
+    * 
+    * @see org.jboss.aop.joinpoint.graph.tree.search.match.State#save()
+    */
+   public void save()
+   {
+      this.savedComparisonState = this.comparisonState;
+      this.savedComparisonStartState = this.comparisonStartState;
+      this.savedComparisonEndState = this.comparisonEndState;
+   }
+   
+   /**
+    * Rollbacks the data contained in this state and in the comparison state
+    * associated with it, if there is one.
+    * 
+    * @see org.jboss.aop.joinpoint.graph.tree.search.match.State#rollback()
+    */
+   public void rollback()
+   {
+      this.comparisonState = this.savedComparisonState;
+      this.comparisonStartState = this.savedComparisonStartState;
+      this.comparisonEndState = this.savedComparisonEndState;
+   }
+   
+   /**
+    * Copies all data stored in <code>stateToCopy</code> to this state,
+    * including its comparison state data, if there is one.
+    * <p>
+    * This method should be called by the client everytime it will pass to the
+    * next match execution more than one suffixes of the previous matched
+    * target. The client needs to pass a diferent state instance to
+    * match each suffix.
+    * 
+    * @param stateToCopy the <code>MatchingState</code> to be copied
+    * @throws ClassCastException if <code>state</code> is not an instance of
+    *                            <code>MatchingState</code>
+    */
+   public final void copy(State stateToCopy)
+   {
+      MatchingState matchingState = (MatchingState) stateToCopy;
+      comparisonStartState = matchingState.comparisonStartState;
+      comparisonEndState = matchingState.comparisonEndState;
+      comparisonState.copy(matchingState.comparisonState);
+   }
+   
+   /**
+    * Increments the <code>targetIndex</code> in a way that the number of
+    * comparable components available for comparison become the same as the
+    * minimum number of available target components. The <code>comparableIndex
+    * </code> value is changed accordingly.
+    * <p>
+    * Is called when the comparison target has no suffixes.
+    * 
+    * @param comparable      the comparable that will perform comparison 
+    * @param comparableIndex indicates from which comparable component
+    *                        comparison will start
+    * @param targetLength    the length of the comparison target
+    * @param targetIndex     indicates from which target component comparison
+    *                        will start
+    */
+   void tightenComparison(Comparable comparable, Index comparableIndex,
+         int targetLength, Index targetIndex)
+   {
+      // updates value
+      this.comparisonEndState.update(this, comparable, comparableIndex,
+            targetLength, targetIndex);
+      // tightens comparison
+      this.comparisonEndState.tightenComparison(this, comparable,
+            comparableIndex, targetLength, targetIndex);
+      // don't waste time updating comparisonStartState, a next character will
+      // not be retrieved, since this target doesn't has suffixes
+   }
+
+   /**
+    * Increments the <code>targetIndex</code> in a way that the number of
+    * comparable components available for comparison become the same as the
+    * minimum number of available target components. The <code>comparableIndex
+    * </code> value is changed accordingly. 
+    * <p>
+    * Is called when the comparison target has one or more suffixes.
+    * 
+    * @param comparable        the comparable that will perform comparison 
+    * @param comparableIndex   indicates from which comparable component
+    *                          comparison will start
+    * @param targetLengthRange the length range of the comparison target
+    * @param targetIndex       indicates from which target component comparison
+    *                          will start
+    * @return <code>true</code> if the comparison start is postponed to be
+    *         performed on the target suffixes; <code>false</code> otherwise.
+    */
+   boolean tightenComparison(Comparable comparable, Index comparableIndex,
+         LengthRange targetLengthRange, Index targetIndex)
+   {
+      // updates value
+      this.comparisonEndState.update(this, comparable, comparableIndex,
+            targetLengthRange.getPostPrefixMaxLength(), targetIndex);
+      // tightens comparison
+      this.comparisonEndState.tightenComparison(this, comparable,
+            comparableIndex, targetLengthRange.getPostPrefixMinLength(),
+            targetIndex);
+      this.comparisonStartState.update(this, targetIndex, targetLengthRange);
+      return this.comparisonStartState.isComparisonPostponed();
+   }
+   
+   /**
+    * Returns the character that identifies the next targets that may result
+    * in a positive result. If a target not identified by this character is
+    * matched next, certainly the result will be negative.
+    * <p>
+    * Is called when the <code>target</code> and its length range are known.
+    * 
+    * @param comparable        responsible for performing comparison
+    * @param comparableIndex   indicates from which comparable component
+    *                          comparison will start
+    * @param target            the previously matched target (with a positive
+    *                          result)
+    * @param targetLengthRange the length range of <code>target</code>.
+    * @return the character that identifies the next targets that may result
+    * in a positive result. May be <code>Flags.ALL</code> to indicate that
+    * any target can have a positive result in the next matching execution
+    */
+   char getNextCharacter(Comparable comparable, Index comparableIndex,
+         Object target, LengthRange targetLengthRange)
+   {
+      return this.comparisonStartState.getNextCharacter(this, comparable,
+            comparableIndex, target, targetLengthRange);
+   }
+   
+   /**
+    * Returns the character that identifies the next targets that may result
+    * in a positive result. If a target not identified by this character is
+    * matched next, certainly the result will be negative.
+    * <p>
+    * Is called when the <code>target</code> or its length range are unknown.
+    * 
+    * @param comparable        responsible for performing comparison
+    * @param comparableIndex   indicates from which comparable component
+    *                          comparison will start
+    * @return the character that identifies the next targets that may result
+    * in a positive result. May be <code>Flags.ALL</code> to indicate that
+    * any target can have a positive result in the next matching execution
+    */
+   char getNextCharacter(Comparable comparable, Index comparableIndex)
+   {
+      return this.comparisonStartState.getNextCharacter(this, comparable,
+            comparableIndex);
+   }
+   
+   public String toString()
+   {
+      return "(comparisonStart=" + this.comparisonStartState + 
+         ", comparisonEnd=" + this.comparisonEndState + ", comparisonState=" +
+         comparisonState + ")";
+   }
+   
+   /**
+    * Empty implementation of <code>State</code>, provides a dummy comparison
+    * state to <code>MatchingState</code> when it doesn't have one.
+    * 
+    * @author Flavia Rainone
+    */
+   private static class DummyState implements State
+   {
+      public void reset() {}
+      public void save() {}
+      public void rollback() {}
+      public final void copy(State State) {}
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/PrefixFunction.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/PrefixFunction.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/PrefixFunction.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Provides the prefix function as defined in KMP pattern matching algorithm.
+ * <p>
+ * A prefix function is associated with a comparable and is responsible for,
+ * once a mismatch is returned by the <code>Comparable</code>, indicating from
+ * which comparable component the comparison should restart. This function is
+ * utilized in pattern and suffix matchings. 
+ * 
+ * @author Flavia Rainone
+ * @see Comparable
+ */
+public interface PrefixFunction
+{
+   /**
+    * Applies the prefix function value to <code>index</code>.
+    * 
+    * @param index indicates in which comparable component the mismatch occured.
+    *              After the function is applied to <code>index</code>, it will
+    *              contain the prefix function value correspondent to it.
+    *              This new index value is utilized to restart the comparison
+    *              in pattern and suffix matchings.
+    * @see Index#applyPrefixFunction(int)
+    */
+   void applyTo(Index index);   
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/State.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/State.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/State.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.match;
+
+/**
+ * Defines basic operations every state class needs to provide.
+ * 
+ * @author Flavia Rainone
+ */
+public interface State
+{
+   /**
+    * Resets this state to its initial value. After this method is executed,
+    * this state should be equal to a newly created state of the same class.
+    */
+   public abstract void reset();
+
+   /**
+    * Saves this state data so it can be restored by the {@link #rollback}
+    * method.
+    * @see #rollback()
+    */
+   public abstract void save();
+
+   /**
+    * Overwrites the current state data by the last saved data. Notice that,
+    * after this method is executed, the previous state data will be lost,
+    * completely overwriten.
+    * <p>
+    * This method is called only after the {@link #save} method.
+    * @see #save() 
+    */
+   public abstract void rollback();
+   
+   /**
+    * Overwrites the current state data by the <code>stateToCopy</code> data.
+    * <p>
+    * The data saved by <code>stateToCopy.save()</code> executions is the only
+    * data that doesn't need to be copied.
+    * 
+    * @param stateToCopy the state whose data will be copied
+    */
+   public void copy(State stateToCopy);
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/match/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,178 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Provides a framework for matching comparable objects using four different
+algorithms. All of these algorithms are based on functionality delivered by the
+{@link pointcutMatcher.tree.search.match.Comparable} interface, whose
+implementation must be provided by the client.
+
+
+<h2>Package Specification</h2>
+<p>
+This package is responsible for matching an expression, called <i>matchable
+expression</i>, against a <i>complete target</i>.</p>
+<p>
+In order for the matching process to take place, the matchable expression is
+scattered into smaller parts. Each part is associated with a {@link 
+pointcutMatcher.tree.search.match.Matcher matcher}, responsible for matching its
+part against a complete target part, which we will call, for simplicity, just
+<i>target</i> (so, we can state that a complete target is the result of the
+concatenation of sequential targets). This means that the first step of a
+matching process is to break the matchable expression into smaller parts,
+transforming it into a sequence of matchers. This is done by invoking {@link
+pointcutMatcher.tree.search.match.MatcherFactory#createSequence
+MatcherFactory.createSequence} method. Once this sequence is generated, each
+matcher must be invoked, in order, to match its part against a target, and the
+matching process should be considered finished when one of them states a
+negative result or when all of them have done the matching and resulted in a
+positive match.</p>
+<p>
+The matching performed by a matcher consists of verifying wheter a relationship
+between the complete target and its matchable expression part exists or not.
+Which relationship is checked by the matcher is defined by its profile (
+{@link pointcutMatcher.tree.search.match.MatcherProfile}). The available
+profiles and the relationship they enforce are:
+</p>
+<ul>
+   <li><code>SIMPLE</code>: equality;</li>
+   <li><code>PREFIX</code>: starts with;</li>
+   <li><code>SUFFIX</code>: ends with;</li>
+   <li><code>PATTERN</code>: contains.</li>
+</ul>
+<p>
+The client is responsible for specifying the profile of the matchers contained
+in the sequence. It can specify the profile of: the first matcher, the last
+matcher, the middle ones, and the unique matcher (this one is generated when the
+matchers sequence contains only one element).
+</p>
+<p>
+The extensibility in this package is on the {@link
+pointcutMatcher.tree.search.match.Comparable} interface. Differently from what
+one may have thought, the matchers are not responsible for comparing its
+matchable expression part with a target. For this task, it delegates execution
+to a comparable instance, provided by the client. So, the matchers are not
+dependent on how a comparison is performed, nor what is the target type. They
+don't even manipulate the matchable expression part associated with them,
+because this is responsability of the comparable. So, a matcher is not actually
+associated with its part, but with its comparable. This one needs to provide the
+comparison functionality and information about its matchable expression part; in
+fact, it represents the expression part along with the comparison functionality.
+</p>
+<p>
+Before we state the responsabilities of the comparable, lets at first define the
+terms:
+</p>
+<ul>
+   <li>Comparable Prefix: is the concatenation of all comparables contained
+      in the matchers previous to the current matcher in the sequence.
+   </li>
+   <li>Comparable Suffix: is the concatenation of all comparables contained in
+      matchers that follow the current matcher in the sequence.
+   </li>
+   <li>
+      Comparable Post-Prefix: is the concatenation of the comparable with its
+      suffix.
+   </li>      
+</ul>
+<p>
+In the same way comparables can be concatenated to form a matchable expression,
+the targets can be concatenated to form a complete target. So, we also have a
+target prefix, suffix and post-prefix. The only difference between a target and
+a comparable is that the first one can have more than one suffix, which means
+it can be part of more than one complete target. Henceforth the client can match
+more than one complete target with common prefixes in an economical way,
+matching a target that is the prefix common to all complete targets: if the
+matching result is negative, it means that none of the complete targets are
+positively matched by the matcher sequence; otherwise, the matching process
+should continue, this time with each suffix of the matched target.
+</p>
+<p>
+The comparable provided by the client must conform to the following rules:
+</p>
+<ul>
+   <li>
+      it is made up by components, as is the target. The comparable compares
+      each one of its components with a component of the target, in sequence.
+      What is the component is up to the client, but the most typical component
+      is a character;
+   </li>
+   <li>
+      it must provide the length of its post-prefix (how many components the 
+      post-prefix contains);
+   </li>
+   <li>
+      it must also provide a prefix function, the one specified in the pattern
+      matching KMP algorithm. Such a function can say from which index the
+      comparison must proceed once a mismatch is found, and is used to improve
+      efficiency in patterns matching. 
+   </li>
+   <li>
+      the comparable should provide a character that identifies the current
+      component being compared. This information can be used by the matcher to
+      provide an interesting functionality, capable of improving performance:
+      indicating to the client which target suffixes should be used in the next
+      matching execution. This way, some suffixes should not be processed
+      because certainly the matching result will be negative. Even though, there
+      are cases in which no suffix can be excluded from the matching process.
+   </li>
+</ul>
+<p>
+Besides this, the client is responsible for providing the target and its data,
+according to these rules:
+</p>
+<ul>
+   <li>
+      the target must be compatible with the comparable implementation the
+      client is providing;
+   </li>
+   <li>
+      the client must provide the target length when the target has no suffixes,
+      or the {@link pointcutMatcher.tree.search.match.LengthRange target length
+      range} (contains the length of minimum and maximum post-prefixes and of
+      the target itself) otherwise.
+   </li>
+</ul>
+<p>
+Notice that the length range is also responsbible for calculating the length of
+the minimum and maximum target suffixes. However, it is not assumed that the
+suffix length equals the post-prefix length minus the target length. The suffix
+length is just calculated this way as a default implementation, which can be
+overriden by the client. The reason for this is that the target is made of
+components which are known only to the client, so it cannot be assumed how the
+concatanation of target components is performed nor the length of its result. In
+the same way, the length of a comparable plus the length of its suffix is not
+assumed to be the same as the length of the comparable post-prefix.
+</p>
+
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.search.match.MatcherFactory
+ at see pointcutMatcher.tree.search.match.Matcher
+ at see pointcutMatcher.tree.search.match.ComparableFactory
+ at see pointcutMatcher.tree.search.match.Comparable
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,34 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Provides the search mechanism for the tree.
+
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.search.SearchKey
+
+</body>
+</html>
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPart.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPart.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPart.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,267 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.part;
+
+import org.jboss.aop.joinpoint.graph.tree.ExtendedLengthRange;
+import org.jboss.aop.joinpoint.graph.tree.KeyPart;
+import org.jboss.aop.joinpoint.graph.tree.search.common.PrefixFunctionLoader;
+import org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElementFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Comparable;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparisonResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+import org.jboss.aop.joinpoint.graph.tree.search.match.Matcher;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherSequenceProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingResult;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatchingState;
+import org.jboss.aop.joinpoint.graph.tree.search.match.PrefixFunction;
+import org.jboss.aop.joinpoint.graph.tree.search.match.State;
+
+
+/**
+ * Implements the <code>Comparable</code> interface having {@link
+ * org.jboss.aop.joinpoint.graph.tree.search.element.ComparableElement} matchers as
+ * components.
+ * 
+ * @author Flavia Rainone
+ */
+public class ComparableKeyPart implements Comparable
+{
+   /**
+    * The components of this comparable.
+    */
+   private Matcher[] elementMatchers;
+   
+   /**
+    * Indicates the index of the matcher element that doesn't specify the
+    * target end, it accepts any target suffix.
+    */
+   private int anySuffixMatcher;
+   
+   /**
+    * The prefix function of this comparable key part.
+    */
+   private PrefixFunction prefixFunction;
+   
+   /**
+    * The post prefix length.
+    */
+   protected int postPrefixLength;
+   
+   /**
+    * Constructor.
+    * 
+    * @param keyPartExpression the element that will be compared by the
+    *                          <code>ComparableKeyPart</code> to be created
+    * @param matcherProfile    the profile of the matcher that will contain the
+    *                          <code>ComparableKeyPart</code> to be created
+    */
+   ComparableKeyPart(String keyPartExpression, MatcherProfile matcherProfile)
+   {
+      // creates element matchers
+      ComparableElementFactory factory = ComparableElementFactory.getInstance();
+      MatcherSequenceProfile seqProfile = factory.performCreationForProfile(
+            matcherProfile);
+      elementMatchers = MatcherFactory.createSequence(keyPartExpression,
+            factory, seqProfile);
+      // retrieves prefix function calculated (or null, if this part is not
+      // a pattern nor a suffix
+      PrefixFunctionLoader prefixFunctionLoader = PrefixFunctionLoader.
+         getCurrentLoader();
+      this.prefixFunction = prefixFunctionLoader.getLoadedFunction();
+      // last matcher is anySuffixMatcher if it doesn't specify the
+      // target end, as is the case of prefix and pattern
+      if (matcherProfile == MatcherProfile.PREFIX ||
+            matcherProfile == MatcherProfile.PATTERN)
+      {
+         this.anySuffixMatcher = elementMatchers.length - 1;
+      }
+      else
+      {
+         // there isn't a anySuffixMatcher
+         this.anySuffixMatcher = elementMatchers.length;
+      }
+      // the post prefix length is initialy the key part length
+      // this value is updated as new key parts are created
+      // by ComparableKeyPartFactory
+      this.postPrefixLength = elementMatchers.length;
+   }
+   
+   /**
+    * Returns the number of element matchers contained in this comparable key
+    * part.
+    * 
+    * @return the number of element matchers contained in this comparable key
+    *         part
+    */
+   int getLength()
+   {
+      return this.elementMatchers.length;
+   }
+   
+   public int getPostPrefixLength()
+   { 
+      return this.postPrefixLength; 
+   }
+   
+   public char getNextCharacter(Index comparableIndex, Object comparisonState)
+   {
+      // the target and its length range should always be known when dealing
+      // with comparable key parts
+      throw new RuntimeException ("Unexpected call");
+   }
+   
+   public char getNextCharacter(Index comparableIndex, Object target,
+         LengthRange targetLengthRange, Object comparisonState)
+   {
+      if (comparableIndex.getValue() >= elementMatchers.length)
+      {
+         return KeyPart.KEY_ELEMENT_END;
+      }
+      KeyPart keyPart = (KeyPart) target;
+      KeyPartIndex mIndex = (KeyPartIndex) comparableIndex; // matchers index
+      if (! keyPart.isLastElementComplete())
+      {
+         // pass length range information
+         LengthRange elementLengthRange = ((ExtendedLengthRange)
+               targetLengthRange).getElementLengthRange(); 
+         return elementMatchers[mIndex.getValue()].getNextCharacter(
+               // don't waste time getting the target because this value
+               // will not be used
+               mIndex.getElementIndex(), null, elementLengthRange,
+               (MatchingState) comparisonState);
+      }
+      // length range unknown
+      return elementMatchers[mIndex.getValue()].getNextCharacter(
+            mIndex.getElementIndex(), (MatchingState) comparisonState);
+   }
+   
+   public PrefixFunction getPrefixFunction()
+   {
+      return prefixFunction;
+   }
+
+   /**
+    * @throws ClassCastException if <code>targetIndex</code> and/or <code>
+    *                            comparableIndex</code> are not instances of
+    *                            <code>KeyPartIndex</code>. The same exception
+    *                            is thrown if <code>target</code> isn't a <code>
+    *                            KeyPart</code>.
+    * @see KeyPartIndex
+    */
+   public ComparisonResult compare(Object target, Index targetIndex,
+         Index comparableIndex, State comparisonState)
+   {
+      // retrive important data from parameters
+      KeyPartIndex tIndex = (KeyPartIndex) targetIndex; // target index
+      KeyPartIndex mIndex = (KeyPartIndex) comparableIndex; // matchers index
+      MatchingState state = (MatchingState) comparisonState;
+      KeyPart keyPart = (KeyPart) target;
+      String[] elements = keyPart.getKeyElements();
+      int tEnd = keyPart.isLastElementComplete()? elements.length:
+         elements.length - 1;
+      MatchingResult result = MatchingResult.POSITIVE_MATCH;
+      Matcher matcher;
+      String element;
+      
+      // complete targets comparison
+      while(mIndex.getValue() < anySuffixMatcher && tIndex.getValue() < tEnd)
+      {
+         matcher = elementMatchers[mIndex.getValue()];
+         element = elements[tIndex.getValue()];
+         result = matcher.matches(element, element.length(),
+               tIndex.getElementIndex(), mIndex.getElementIndex(), state);
+         if (result != MatchingResult.POSITIVE_MATCH)
+         {
+            break;
+         }
+         tIndex.increment();
+         mIndex.increment();
+         state.reset();
+      }
+      
+      // compare incomplete target and/or suffixless element matcher
+      if (result == MatchingResult.POSITIVE_MATCH &&
+            mIndex.getValue() < elementMatchers.length &&
+            tIndex.getValue() < elements.length)
+      {
+         LengthRange elementLengthRange = null;
+         // if next target it a incomplete target
+         if (!keyPart.isLastElementComplete() && tIndex.getValue() == tEnd)
+         {
+            matcher = elementMatchers[mIndex.getValue()];
+            element = elements[tEnd];
+            elementLengthRange = ((ExtendedLengthRange)
+                  keyPart.getLengthRange()).getElementLengthRange();
+            result = matcher.matches(element, elementLengthRange,
+                  tIndex.getElementIndex(), mIndex.getElementIndex(), state);
+         }
+         else  // mIndex.getValue() == anySuffixMatcher
+         {
+            matcher = elementMatchers[mIndex.getValue()];
+            element = elements[tIndex.getValue()];
+            result = matcher.matches(element, element.length(),
+                  tIndex.getElementIndex(), mIndex.getElementIndex(), state);
+         }
+         // result is positive...
+         if (result == MatchingResult.POSITIVE_MATCH)
+         {
+            // and matcher doesn't specify the target end...
+            if (mIndex.getValue() == anySuffixMatcher)
+            {
+               // increments only matcher index
+               mIndex.increment();
+            }
+            // if compared target is an incomplete target
+            else//!keyPart.isLastElementComplete() && tIndex.getValue() == tEnd
+            {
+               // certainly last element was compared until
+               // the end and mIndex should not be incremented since
+               // the element end is not present
+               tIndex.increment(elementLengthRange);
+            }
+         }
+         else if (result == MatchingResult.PARTIAL_MATCH && 
+            // if target has suffixes...
+            (!keyPart.isLastElementComplete() && tIndex.getValue() == tEnd))
+         {
+               tIndex.increment(elementLengthRange);
+         }
+      }  
+      boolean targetEnd = tIndex.getValue() >= elements.length;
+      boolean matchersEnd = mIndex.getValue() >= elementMatchers.length;
+      return ComparisonResult.getInstance(matchersEnd, targetEnd);
+   }
+   
+   public String toString()
+   {
+      String result = "KeyPart:\n";
+      for (int i = 0; i < elementMatchers.length; i++)
+      {
+         result += "\t - " + elementMatchers[i] + "\n";
+      }
+      result += "-----------------------------------------";
+      return result;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactory.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/ComparableKeyPartFactory.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.part;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.jboss.aop.joinpoint.graph.tree.search.match.Comparable;
+import org.jboss.aop.joinpoint.graph.tree.search.match.ComparableFactory;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherProfile;
+import org.jboss.aop.joinpoint.graph.tree.search.match.MatcherSequenceProfile;
+
+
+/**
+ * Creates <code>ComparableKeyPart</code> instances.
+ * 
+ * @author Flavia Rainone
+ * @see ComparableKeyPart
+ */
+public class ComparableKeyPartFactory implements ComparableFactory
+{
+   /**
+    * Singleton instance.
+    */
+   private static ComparableKeyPartFactory instance =
+      new ComparableKeyPartFactory();
+   
+   /**
+    * Returns the singleton instance.
+    * @return the singleton instance
+    */
+   public static ComparableKeyPartFactory getInstance() {
+      return instance;
+      
+   }
+   
+   /**
+    * The profile of a key part matcher sequence.
+    */
+   private final MatcherSequenceProfile matcherSeqProfile;
+
+   /**
+    * Contains created <code>ComparableKeyPart</code> instances. 
+    */
+   private Collection parts;
+   
+   /**
+    * Private constructor (singleton class).
+    */
+   private ComparableKeyPartFactory()
+   {
+      parts = new ArrayList();
+      matcherSeqProfile = new MatcherSequenceProfile(MatcherProfile.PREFIX,
+            MatcherProfile.PATTERN, MatcherProfile.SUFFIX,
+            MatcherProfile.SIMPLE);
+   }
+   
+   /**
+    * Returns the key part matcher sequence profile.
+    * @return the key part matcher sequence profile
+    */
+   public final MatcherSequenceProfile getMatcherSequenceProfile()
+   {
+      return this.matcherSeqProfile;
+   }
+   
+   public char getSeparator()
+   {
+      return '*';
+   }
+   
+   public void startCreation() {}
+   
+   public void stopCreation()
+   {
+      parts.clear();
+   }
+   
+   public Comparable create(String comparableExpression,
+         MatcherProfile matcherProfile)
+   {
+      // creates instance
+      ComparableKeyPart part = new ComparableKeyPart(
+            comparableExpression, matcherProfile);
+      // updates post-prefix information of previously created instances
+      for (Iterator i = parts.iterator(); i.hasNext(); )
+      {
+         ComparableKeyPart registeredPart = (ComparableKeyPart) i.next();
+         registeredPart.postPrefixLength += part.getLength() - 1;
+      }
+      // adds this part to the created parts collection
+      parts.add(part);
+      return part;
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/KeyPartIndex.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/KeyPartIndex.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/KeyPartIndex.java	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,97 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph.tree.search.part;
+
+import org.jboss.aop.joinpoint.graph.tree.search.match.Index;
+import org.jboss.aop.joinpoint.graph.tree.search.match.LengthRange;
+
+/**
+ * Extended index class with added information about the element index.
+ * <p>
+ * This extra information is necessary because it is not enough to state from
+ * which key part element the comparison should start, it is also important
+ * to know from which element character.
+ * 
+ * @author Flavia Rainone
+ * @see Index
+ */
+public class KeyPartIndex extends Index
+{
+   /**
+    * Element index, contains the element char number from which comparison
+    * should start.
+    */
+   private Index elementIndex;
+   
+   /**
+    * Default constructor, creates an index with zero value.
+    *
+    */
+   public KeyPartIndex()
+   {
+      super();
+      this.elementIndex = new Index();
+   }
+
+   /**
+    * Overwrites the method in the super class, redefining the initial
+    * state as that in which: this index value is 0 and <code>element index
+    * </code> is also in its initial state
+    */
+   public boolean isInitialState()
+   {
+      return super.isInitialState() && this.elementIndex.isInitialState();
+   }
+
+   /**
+    * Returns the element index.
+    * 
+    * @return the element index, that indicates from which element char
+    *         comparison should start
+    */
+   public final Index getElementIndex()
+   {
+      return elementIndex;
+   }
+   
+   /**
+    * Increments this index value by <code>1</code> and updates the element
+    * index so it can be valid for matching the target suffix.
+    * <p>
+    * Should be called only when the target is incomplete.
+    */
+   final void increment(LengthRange elementLengthRange)
+   {
+      super.noCallBackIncrement(1);
+      this.elementIndex.update(elementLengthRange);
+   }
+   
+   public void valueChanged()
+   {
+      this.elementIndex.reset();
+   }
+   
+   public String toString()
+   {
+      return "[" + super.toString() + ", " + this.elementIndex + "]";
+   }
+}
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/package.html
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/package.html	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/search/part/package.html	2008-01-03 19:07:18 UTC (rev 68604)
@@ -0,0 +1,53 @@
+<html>
+<head>
+<!--
+ * 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.
+-->
+<title></title>
+</head>
+<body bgcolor="white">
+
+Implements the <code>search.match</code> package.
+
+
+
+<h2>Package Specification</h2>
+<p>
+In this package, the <code>Comparable</code> interface is implemented by the
+<code>ComparableKeyPart</code> class, whose components are comparable elements
+(<code>search.element.ComparableElement</code>) matchers.
+</p>
+<p>
+As is with <code>search.element</code>, this package contains the <code>
+ComparableFactory</code> implementation associated with <code>ComparableKeyPart
+</code>, but not the <code>PrefixFunction</code> one, which is located in the
+<code>search.common</code> package.
+</p>
+<p>
+This package also extends <code>search.match.Index</code> to add information
+about the element index.
+</p>
+   
+<!-- Put @see and @since tags down here. -->
+ at see pointcutMatcher.tree.search.part.ComparableKeyPart
+
+</body>
+</html>
\ No newline at end of file




More information about the jboss-cvs-commits mailing list